blob: 870c0ea85eaa8f7887c5a8eaaf86422bc5f9c1a3 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Thomas Wouters477c8d52006-05-27 19:21:47 +000016#ifdef __APPLE__
17 /*
Victor Stinner97b89882010-05-06 00:25:39 +000018 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000019 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#if defined(PYOS_OS2)
49#define INCL_DOS
50#define INCL_DOSERRORS
51#define INCL_DOSPROCESS
52#define INCL_NOPMAPI
53#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000054#if defined(PYCC_GCC)
55#include <ctype.h>
56#include <io.h>
57#include <stdio.h>
58#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000059#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000060#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#endif
62
Thomas Wouters0e3f5912006-08-11 14:57:12 +000063#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065#endif /* HAVE_SYS_TYPES_H */
66
67#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070
Guido van Rossum36bc6801995-06-14 22:54:23 +000071#ifdef HAVE_SYS_WAIT_H
Victor Stinner97b89882010-05-06 00:25:39 +000072#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000073#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000076#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000078
Guido van Rossumb6775db1994-08-01 11:34:53 +000079#ifdef HAVE_FCNTL_H
80#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000081#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000082
Guido van Rossuma6535fd2001-10-18 19:44:10 +000083#ifdef HAVE_GRP_H
84#include <grp.h>
85#endif
86
Barry Warsaw5676bd12003-01-07 20:57:09 +000087#ifdef HAVE_SYSEXITS_H
88#include <sysexits.h>
89#endif /* HAVE_SYSEXITS_H */
90
Anthony Baxter8a560de2004-10-13 15:30:56 +000091#ifdef HAVE_SYS_LOADAVG_H
92#include <sys/loadavg.h>
93#endif
94
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000095#ifdef HAVE_LANGINFO_H
96#include <langinfo.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Victor Stinner97b89882010-05-06 00:25:39 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
Victor Stinner97b89882010-05-06 00:25:39 +0000107#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
Victor Stinner97b89882010-05-06 00:25:39 +0000114#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
Victor Stinner97b89882010-05-06 00:25:39 +0000119#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#define HAVE_WAIT 1
121#else
Victor Stinner97b89882010-05-06 00:25:39 +0000122#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000123#define HAVE_GETCWD 1
Victor Stinner97b89882010-05-06 00:25:39 +0000124#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000125#define HAVE_EXECV 1
126#define HAVE_PIPE 1
Victor Stinner97b89882010-05-06 00:25:39 +0000127#define HAVE_SYSTEM 1
128#define HAVE_CWAIT 1
129#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000130#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000131#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000132#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
133/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner97b89882010-05-06 00:25:39 +0000134#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000135/* Unix functions that the configure script doesn't check for */
136#define HAVE_EXECV 1
137#define HAVE_FORK 1
Victor Stinner97b89882010-05-06 00:25:39 +0000138#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000139#define HAVE_FORK1 1
140#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#define HAVE_GETCWD 1
142#define HAVE_GETEGID 1
143#define HAVE_GETEUID 1
144#define HAVE_GETGID 1
145#define HAVE_GETPPID 1
146#define HAVE_GETUID 1
147#define HAVE_KILL 1
148#define HAVE_OPENDIR 1
149#define HAVE_PIPE 1
Victor Stinner97b89882010-05-06 00:25:39 +0000150#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#define HAVE_WAIT 1
Victor Stinner97b89882010-05-06 00:25:39 +0000152#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000153#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000154#endif /* _MSC_VER */
155#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000156#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000157#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000158
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000160
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000161#if defined(__sgi)&&_COMPILER_VERSION>=700
162/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
163 (default) */
164extern char *ctermid_r(char *);
165#endif
166
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000167#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000168#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000170#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000171#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000176#endif
177#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000178extern int chdir(char *);
179extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000180#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000181extern int chdir(const char *);
182extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000183#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000184#ifdef __BORLANDC__
185extern int chmod(const char *, int);
186#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000187extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000188#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000189/*#ifdef HAVE_FCHMOD
190extern int fchmod(int, mode_t);
191#endif*/
192/*#ifdef HAVE_LCHMOD
193extern int lchmod(const char *, mode_t);
194#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int chown(const char *, uid_t, gid_t);
196extern char *getcwd(char *, int);
197extern char *strerror(int);
198extern int link(const char *, const char *);
199extern int rename(const char *, const char *);
200extern int stat(const char *, struct stat *);
201extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000204#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000207#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000209
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000210#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#ifdef HAVE_UTIME_H
213#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000214#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000216#ifdef HAVE_SYS_UTIME_H
217#include <sys/utime.h>
218#define HAVE_UTIME_H /* pretend we do for the rest of this file */
219#endif /* HAVE_SYS_UTIME_H */
220
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#ifdef HAVE_SYS_TIMES_H
222#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000223#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
225#ifdef HAVE_SYS_PARAM_H
226#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000227#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228
229#ifdef HAVE_SYS_UTSNAME_H
230#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000231#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000233#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#define NAMLEN(dirent) strlen((dirent)->d_name)
236#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000237#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#include <direct.h>
239#define NAMLEN(dirent) strlen((dirent)->d_name)
240#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000243#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#endif
247#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000249#endif
250#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000252#endif
253#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000256#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000258#endif
259#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000261#endif
262#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000264#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000265#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000266#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <windows.h>
Victor Stinner97b89882010-05-06 00:25:39 +0000268#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000269#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270
Guido van Rossumd48f2521997-12-05 22:19:34 +0000271#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274
Tim Petersbc2e10e2002-03-03 23:17:02 +0000275#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000276#if defined(PATH_MAX) && PATH_MAX > 1024
277#define MAXPATHLEN PATH_MAX
278#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000279#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000280#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000281#endif /* MAXPATHLEN */
282
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000283#ifdef UNION_WAIT
284/* Emulate some macros on systems that have a union instead of macros */
285
286#ifndef WIFEXITED
287#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
288#endif
289
290#ifndef WEXITSTATUS
291#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
292#endif
293
294#ifndef WTERMSIG
295#define WTERMSIG(u_wait) ((u_wait).w_termsig)
296#endif
297
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000298#define WAIT_TYPE union wait
299#define WAIT_STATUS_INT(s) (s.w_status)
300
301#else /* !UNION_WAIT */
302#define WAIT_TYPE int
303#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000304#endif /* UNION_WAIT */
305
Antoine Pitrouc3ee1662009-05-23 16:02:33 +0000306/* Issue #1983: pid_t can be longer than a C long on some systems */
Antoine Pitrou7852c422009-05-24 11:58:35 +0000307#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
Antoine Pitrouc3ee1662009-05-23 16:02:33 +0000308#define PARSE_PID "i"
309#define PyLong_FromPid PyLong_FromLong
310#define PyLong_AsPid PyLong_AsLong
311#elif SIZEOF_PID_T == SIZEOF_LONG
312#define PARSE_PID "l"
313#define PyLong_FromPid PyLong_FromLong
314#define PyLong_AsPid PyLong_AsLong
315#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
316#define PARSE_PID "L"
317#define PyLong_FromPid PyLong_FromLongLong
318#define PyLong_AsPid PyLong_AsLongLong
319#else
320#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
Antoine Pitrouc3ee1662009-05-23 16:02:33 +0000321#endif /* SIZEOF_PID_T */
322
Greg Wardb48bc172000-03-01 21:51:56 +0000323/* Don't use the "_r" form if we don't need it (also, won't have a
324 prototype for it, at least on Solaris -- maybe others as well?). */
325#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
326#define USE_CTERMID_R
327#endif
328
Fred Drake699f3522000-06-29 21:12:41 +0000329/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000330#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000331#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +0000332# define STAT win32_stat
333# define FSTAT win32_fstat
334# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000335#else
Victor Stinner97b89882010-05-06 00:25:39 +0000336# define STAT stat
337# define FSTAT fstat
338# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000339#endif
340
Tim Peters11b23062003-04-23 02:39:17 +0000341#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000342#include <sys/mkdev.h>
343#else
344#if defined(MAJOR_IN_SYSMACROS)
345#include <sys/sysmacros.h>
346#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000347#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
348#include <sys/mkdev.h>
349#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000350#endif
Fred Drake699f3522000-06-29 21:12:41 +0000351
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000352#if defined _MSC_VER && _MSC_VER >= 1400
353/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
354 * valid and throw an assertion if it isn't.
355 * Normally, an invalid fd is likely to be a C program error and therefore
356 * an assertion can be useful, but it does contradict the POSIX standard
357 * which for write(2) states:
358 * "Otherwise, -1 shall be returned and errno set to indicate the error."
359 * "[EBADF] The fildes argument is not a valid file descriptor open for
360 * writing."
361 * Furthermore, python allows the user to enter any old integer
362 * as a fd and should merely raise a python exception on error.
363 * The Microsoft CRT doesn't provide an official way to check for the
364 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner97b89882010-05-06 00:25:39 +0000365 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000366 * internal structures involved.
367 * The structures below must be updated for each version of visual studio
368 * according to the file internal.h in the CRT source, until MS comes
369 * up with a less hacky way to do this.
370 * (all of this is to avoid globally modifying the CRT behaviour using
371 * _set_invalid_parameter_handler() and _CrtSetReportMode())
372 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000373/* The actual size of the structure is determined at runtime.
374 * Only the first items must be present.
375 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000376typedef struct {
Victor Stinner97b89882010-05-06 00:25:39 +0000377 intptr_t osfhnd;
378 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000379} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000380
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000381extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000382#define IOINFO_L2E 5
383#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
384#define IOINFO_ARRAYS 64
385#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
386#define FOPEN 0x01
387#define _NO_CONSOLE_FILENO (intptr_t)-2
388
389/* This function emulates what the windows CRT does to validate file handles */
390int
391_PyVerify_fd(int fd)
392{
Victor Stinner97b89882010-05-06 00:25:39 +0000393 const int i1 = fd >> IOINFO_L2E;
394 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000395
Antoine Pitrou835b4452010-08-15 18:32:16 +0000396 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000397
Victor Stinner97b89882010-05-06 00:25:39 +0000398 /* Determine the actual size of the ioinfo structure,
399 * as used by the CRT loaded in memory
400 */
401 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
402 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
403 }
404 if (sizeof_ioinfo == 0) {
405 /* This should not happen... */
406 goto fail;
407 }
408
409 /* See that it isn't a special CLEAR fileno */
410 if (fd != _NO_CONSOLE_FILENO) {
411 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
412 * we check pointer validity and other info
413 */
414 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
415 /* finally, check that the file is open */
416 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
417 if (info->osfile & FOPEN) {
418 return 1;
419 }
420 }
421 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000422 fail:
Victor Stinner97b89882010-05-06 00:25:39 +0000423 errno = EBADF;
424 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000425}
426
427/* the special case of checking dup2. The target fd must be in a sensible range */
428static int
429_PyVerify_fd_dup2(int fd1, int fd2)
430{
Victor Stinner97b89882010-05-06 00:25:39 +0000431 if (!_PyVerify_fd(fd1))
432 return 0;
433 if (fd2 == _NO_CONSOLE_FILENO)
434 return 0;
435 if ((unsigned)fd2 < _NHANDLE_)
436 return 1;
437 else
438 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000439}
440#else
441/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
442#define _PyVerify_fd_dup2(A, B) (1)
443#endif
444
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000445/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000446#ifdef WITH_NEXT_FRAMEWORK
447/* On Darwin/MacOSX a shared library or framework has no access to
448** environ directly, we must obtain it with _NSGetEnviron().
449*/
450#include <crt_externs.h>
451static char **environ;
452#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000454#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455
Barry Warsaw53699e91996-12-10 23:23:01 +0000456static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000457convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000458{
Victor Stinner97b89882010-05-06 00:25:39 +0000459 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000460#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +0000461 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000462#else
Victor Stinner97b89882010-05-06 00:25:39 +0000463 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000464#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000465#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +0000466 APIRET rc;
467 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
468#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000469
Victor Stinner97b89882010-05-06 00:25:39 +0000470 d = PyDict_New();
471 if (d == NULL)
472 return NULL;
473#ifdef WITH_NEXT_FRAMEWORK
474 if (environ == NULL)
475 environ = *_NSGetEnviron();
476#endif
477#ifdef MS_WINDOWS
478 /* _wenviron must be initialized in this way if the program is started
479 through main() instead of wmain(). */
480 _wgetenv(L"");
481 if (_wenviron == NULL)
482 return d;
483 /* This part ignores errors */
484 for (e = _wenviron; *e != NULL; e++) {
485 PyObject *k;
486 PyObject *v;
487 wchar_t *p = wcschr(*e, L'=');
488 if (p == NULL)
489 continue;
490 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
491 if (k == NULL) {
492 PyErr_Clear();
493 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000494 }
Victor Stinner97b89882010-05-06 00:25:39 +0000495 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
496 if (v == NULL) {
497 PyErr_Clear();
498 Py_DECREF(k);
499 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000500 }
Victor Stinner97b89882010-05-06 00:25:39 +0000501 if (PyDict_GetItem(d, k) == NULL) {
502 if (PyDict_SetItem(d, k, v) != 0)
503 PyErr_Clear();
504 }
505 Py_DECREF(k);
506 Py_DECREF(v);
507 }
508#else
509 if (environ == NULL)
510 return d;
511 /* This part ignores errors */
512 for (e = environ; *e != NULL; e++) {
513 PyObject *k;
514 PyObject *v;
515 char *p = strchr(*e, '=');
516 if (p == NULL)
517 continue;
518 k = PyUnicode_Decode(*e, (int)(p-*e),
519 Py_FileSystemDefaultEncoding, "surrogateescape");
520 if (k == NULL) {
521 PyErr_Clear();
522 continue;
523 }
524 v = PyUnicode_Decode(p+1, strlen(p+1),
525 Py_FileSystemDefaultEncoding, "surrogateescape");
526 if (v == NULL) {
527 PyErr_Clear();
528 Py_DECREF(k);
529 continue;
530 }
531 if (PyDict_GetItem(d, k) == NULL) {
532 if (PyDict_SetItem(d, k, v) != 0)
533 PyErr_Clear();
534 }
535 Py_DECREF(k);
536 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000537 }
538#endif
Victor Stinner97b89882010-05-06 00:25:39 +0000539#if defined(PYOS_OS2)
540 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
541 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
542 PyObject *v = PyBytes_FromString(buffer);
543 PyDict_SetItemString(d, "BEGINLIBPATH", v);
544 Py_DECREF(v);
545 }
546 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
547 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
548 PyObject *v = PyBytes_FromString(buffer);
549 PyDict_SetItemString(d, "ENDLIBPATH", v);
550 Py_DECREF(v);
551 }
552#endif
553 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000554}
555
Martin v. Löwis011e8422009-05-05 04:43:17 +0000556/* Convert a bytes object to a char*. Optionally lock the buffer if it is a
557 bytes array. */
558
559static char*
560bytes2str(PyObject* o, int lock)
561{
Victor Stinner97b89882010-05-06 00:25:39 +0000562 if(PyBytes_Check(o))
563 return PyBytes_AsString(o);
564 else if(PyByteArray_Check(o)) {
565 if (lock && PyObject_GetBuffer(o, NULL, 0) < 0)
566 /* On a bytearray, this should not fail. */
567 PyErr_BadInternalCall();
568 return PyByteArray_AsString(o);
569 } else {
570 /* The FS converter should have verified that this
571 is either bytes or bytearray. */
572 Py_FatalError("bad object passed to bytes2str");
573 /* not reached. */
574 return "";
575 }
Martin v. Löwis011e8422009-05-05 04:43:17 +0000576}
577
578/* Release the lock, decref the object. */
579static void
580release_bytes(PyObject* o)
581{
Victor Stinner97b89882010-05-06 00:25:39 +0000582 if (PyByteArray_Check(o))
583 o->ob_type->tp_as_buffer->bf_releasebuffer(o, 0);
584 Py_DECREF(o);
Martin v. Löwis011e8422009-05-05 04:43:17 +0000585}
586
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000587
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000588/* Set a POSIX-specific error from errno, and return NULL */
589
Barry Warsawd58d7641998-07-23 16:14:40 +0000590static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000591posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000592{
Victor Stinner97b89882010-05-06 00:25:39 +0000593 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000594}
Barry Warsawd58d7641998-07-23 16:14:40 +0000595static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000596posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000597{
Victor Stinner97b89882010-05-06 00:25:39 +0000598 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000599}
600
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000601#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000602static PyObject *
603posix_error_with_unicode_filename(Py_UNICODE* name)
604{
Victor Stinner97b89882010-05-06 00:25:39 +0000605 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000606}
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000607#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000608
609
Mark Hammondef8b6542001-05-13 08:04:26 +0000610static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000611posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000612{
Victor Stinner97b89882010-05-06 00:25:39 +0000613 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError,
614 bytes2str(name, 0));
615 release_bytes(name);
616 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000617}
618
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000619#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000620static PyObject *
621win32_error(char* function, char* filename)
622{
Victor Stinner97b89882010-05-06 00:25:39 +0000623 /* XXX We should pass the function name along in the future.
624 (winreg.c also wants to pass the function name.)
625 This would however require an additional param to the
626 Windows error object, which is non-trivial.
627 */
628 errno = GetLastError();
629 if (filename)
630 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
631 else
632 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000633}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000634
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000635static PyObject *
636win32_error_unicode(char* function, Py_UNICODE* filename)
637{
Victor Stinner97b89882010-05-06 00:25:39 +0000638 /* XXX - see win32_error for comments on 'function' */
639 errno = GetLastError();
640 if (filename)
641 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
642 else
643 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000644}
645
Thomas Wouters477c8d52006-05-27 19:21:47 +0000646static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000647convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000648{
Victor Stinner97b89882010-05-06 00:25:39 +0000649 if (PyUnicode_CheckExact(*param))
650 Py_INCREF(*param);
651 else if (PyUnicode_Check(*param))
652 /* For a Unicode subtype that's not a Unicode object,
653 return a true Unicode object with the same data. */
654 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
655 PyUnicode_GET_SIZE(*param));
656 else
657 *param = PyUnicode_FromEncodedObject(*param,
658 Py_FileSystemDefaultEncoding,
659 "strict");
660 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000661}
662
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000663#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664
Guido van Rossumd48f2521997-12-05 22:19:34 +0000665#if defined(PYOS_OS2)
666/**********************************************************************
667 * Helper Function to Trim and Format OS/2 Messages
668 **********************************************************************/
Victor Stinner97b89882010-05-06 00:25:39 +0000669static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000670os2_formatmsg(char *msgbuf, int msglen, char *reason)
671{
672 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
673
674 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
675 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
676
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000677 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000678 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
679 }
680
681 /* Add Optional Reason Text */
682 if (reason) {
683 strcat(msgbuf, " : ");
684 strcat(msgbuf, reason);
685 }
686}
687
688/**********************************************************************
689 * Decode an OS/2 Operating System Error Code
690 *
691 * A convenience function to lookup an OS/2 error code and return a
692 * text message we can use to raise a Python exception.
693 *
694 * Notes:
695 * The messages for errors returned from the OS/2 kernel reside in
696 * the file OSO001.MSG in the \OS2 directory hierarchy.
697 *
698 **********************************************************************/
Victor Stinner97b89882010-05-06 00:25:39 +0000699static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000700os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
701{
702 APIRET rc;
703 ULONG msglen;
704
705 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
706 Py_BEGIN_ALLOW_THREADS
707 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
708 errorcode, "oso001.msg", &msglen);
709 Py_END_ALLOW_THREADS
710
711 if (rc == NO_ERROR)
712 os2_formatmsg(msgbuf, msglen, reason);
713 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000714 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner97b89882010-05-06 00:25:39 +0000715 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000716
717 return msgbuf;
718}
719
720/* Set an OS/2-specific error and return NULL. OS/2 kernel
721 errors are not in a global variable e.g. 'errno' nor are
722 they congruent with posix error numbers. */
723
Victor Stinner97b89882010-05-06 00:25:39 +0000724static PyObject *
725os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000726{
727 char text[1024];
728 PyObject *v;
729
730 os2_strerror(text, sizeof(text), code, "");
731
732 v = Py_BuildValue("(is)", code, text);
733 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000734 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000735 Py_DECREF(v);
736 }
737 return NULL; /* Signal to Python that an Exception is Pending */
738}
739
740#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000741
742/* POSIX generic methods */
743
Barry Warsaw53699e91996-12-10 23:23:01 +0000744static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000745posix_fildes(PyObject *fdobj, int (*func)(int))
746{
Victor Stinner97b89882010-05-06 00:25:39 +0000747 int fd;
748 int res;
749 fd = PyObject_AsFileDescriptor(fdobj);
750 if (fd < 0)
751 return NULL;
752 if (!_PyVerify_fd(fd))
753 return posix_error();
754 Py_BEGIN_ALLOW_THREADS
755 res = (*func)(fd);
756 Py_END_ALLOW_THREADS
757 if (res < 0)
758 return posix_error();
759 Py_INCREF(Py_None);
760 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000761}
Guido van Rossum21142a01999-01-08 21:05:37 +0000762
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000763#ifdef MS_WINDOWS
Tim Peters11b23062003-04-23 02:39:17 +0000764static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000765unicode_file_names(void)
766{
Victor Stinner97b89882010-05-06 00:25:39 +0000767 static int canusewide = -1;
768 if (canusewide == -1) {
769 /* As per doc for ::GetVersion(), this is the correct test for
770 the Windows NT family. */
771 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
772 }
773 return canusewide;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000774}
775#endif
Tim Peters11b23062003-04-23 02:39:17 +0000776
Guido van Rossum21142a01999-01-08 21:05:37 +0000777static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000778posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000779{
Victor Stinner97b89882010-05-06 00:25:39 +0000780 PyObject *opath1 = NULL;
781 char *path1;
782 int res;
783 if (!PyArg_ParseTuple(args, format,
784 PyUnicode_FSConverter, &opath1))
785 return NULL;
786 path1 = bytes2str(opath1, 1);
787 Py_BEGIN_ALLOW_THREADS
788 res = (*func)(path1);
789 Py_END_ALLOW_THREADS
790 if (res < 0)
791 return posix_error_with_allocated_filename(opath1);
792 release_bytes(opath1);
793 Py_INCREF(Py_None);
794 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000795}
796
Barry Warsaw53699e91996-12-10 23:23:01 +0000797static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000798posix_2str(PyObject *args,
Victor Stinner97b89882010-05-06 00:25:39 +0000799 char *format,
800 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000801{
Victor Stinner97b89882010-05-06 00:25:39 +0000802 PyObject *opath1 = NULL, *opath2 = NULL;
803 char *path1, *path2;
804 int res;
805 if (!PyArg_ParseTuple(args, format,
806 PyUnicode_FSConverter, &opath1,
807 PyUnicode_FSConverter, &opath2)) {
808 return NULL;
809 }
810 path1 = bytes2str(opath1, 1);
811 path2 = bytes2str(opath2, 1);
812 Py_BEGIN_ALLOW_THREADS
813 res = (*func)(path1, path2);
814 Py_END_ALLOW_THREADS
815 release_bytes(opath1);
816 release_bytes(opath2);
817 if (res != 0)
818 /* XXX how to report both path1 and path2??? */
819 return posix_error();
820 Py_INCREF(Py_None);
821 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000822}
823
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000824#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000825static PyObject*
Victor Stinner97b89882010-05-06 00:25:39 +0000826win32_1str(PyObject* args, char* func,
827 char* format, BOOL (__stdcall *funcA)(LPCSTR),
828 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000829{
Victor Stinner97b89882010-05-06 00:25:39 +0000830 PyObject *uni;
831 char *ansi;
832 BOOL result;
833 if (unicode_file_names()) {
834 if (!PyArg_ParseTuple(args, wformat, &uni))
835 PyErr_Clear();
836 else {
837 Py_BEGIN_ALLOW_THREADS
838 result = funcW(PyUnicode_AsUnicode(uni));
839 Py_END_ALLOW_THREADS
840 if (!result)
841 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
842 Py_INCREF(Py_None);
843 return Py_None;
844 }
845 }
846 if (!PyArg_ParseTuple(args, format, &ansi))
847 return NULL;
848 Py_BEGIN_ALLOW_THREADS
849 result = funcA(ansi);
850 Py_END_ALLOW_THREADS
851 if (!result)
852 return win32_error(func, ansi);
853 Py_INCREF(Py_None);
854 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000855
856}
857
858/* This is a reimplementation of the C library's chdir function,
859 but one that produces Win32 errors instead of DOS error codes.
860 chdir is essentially a wrapper around SetCurrentDirectory; however,
861 it also needs to set "magic" environment variables indicating
862 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000863static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000864win32_chdir(LPCSTR path)
865{
Victor Stinner97b89882010-05-06 00:25:39 +0000866 char new_path[MAX_PATH+1];
867 int result;
868 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000869
Victor Stinner97b89882010-05-06 00:25:39 +0000870 if(!SetCurrentDirectoryA(path))
871 return FALSE;
872 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
873 if (!result)
874 return FALSE;
875 /* In the ANSI API, there should not be any paths longer
876 than MAX_PATH. */
877 assert(result <= MAX_PATH+1);
878 if (strncmp(new_path, "\\\\", 2) == 0 ||
879 strncmp(new_path, "//", 2) == 0)
880 /* UNC path, nothing to do. */
881 return TRUE;
882 env[1] = new_path[0];
883 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000884}
885
886/* The Unicode version differs from the ANSI version
887 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000888static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000889win32_wchdir(LPCWSTR path)
890{
Victor Stinner97b89882010-05-06 00:25:39 +0000891 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
892 int result;
893 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000894
Victor Stinner97b89882010-05-06 00:25:39 +0000895 if(!SetCurrentDirectoryW(path))
896 return FALSE;
897 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
898 if (!result)
899 return FALSE;
900 if (result > MAX_PATH+1) {
901 new_path = malloc(result * sizeof(wchar_t));
902 if (!new_path) {
903 SetLastError(ERROR_OUTOFMEMORY);
904 return FALSE;
905 }
906 result = GetCurrentDirectoryW(result, new_path);
907 if (!result) {
908 free(new_path);
909 return FALSE;
910 }
911 }
912 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
913 wcsncmp(new_path, L"//", 2) == 0)
914 /* UNC path, nothing to do. */
915 return TRUE;
916 env[1] = new_path[0];
917 result = SetEnvironmentVariableW(env, new_path);
918 if (new_path != _new_path)
919 free(new_path);
920 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000921}
922#endif
923
Martin v. Löwis14694662006-02-03 12:54:16 +0000924#ifdef MS_WINDOWS
925/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
926 - time stamps are restricted to second resolution
927 - file modification times suffer from forth-and-back conversions between
928 UTC and local time
929 Therefore, we implement our own stat, based on the Win32 API directly.
930*/
Victor Stinner97b89882010-05-06 00:25:39 +0000931#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000932
933struct win32_stat{
934 int st_dev;
935 __int64 st_ino;
936 unsigned short st_mode;
937 int st_nlink;
938 int st_uid;
939 int st_gid;
940 int st_rdev;
941 __int64 st_size;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000942 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000943 int st_atime_nsec;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000944 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000945 int st_mtime_nsec;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000946 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000947 int st_ctime_nsec;
948};
949
950static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
951
952static void
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000953FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +0000954{
Victor Stinner97b89882010-05-06 00:25:39 +0000955 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
956 /* Cannot simply cast and dereference in_ptr,
957 since it might not be aligned properly */
958 __int64 in;
959 memcpy(&in, in_ptr, sizeof(in));
960 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000961 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +0000962}
963
Thomas Wouters477c8d52006-05-27 19:21:47 +0000964static void
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000965time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000966{
Victor Stinner97b89882010-05-06 00:25:39 +0000967 /* XXX endianness */
968 __int64 out;
969 out = time_in + secs_between_epochs;
970 out = out * 10000000 + nsec_in / 100;
971 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000972}
973
Martin v. Löwis14694662006-02-03 12:54:16 +0000974/* Below, we *know* that ugo+r is 0444 */
975#if _S_IREAD != 0400
976#error Unsupported C library
977#endif
978static int
979attributes_to_mode(DWORD attr)
980{
Victor Stinner97b89882010-05-06 00:25:39 +0000981 int m = 0;
982 if (attr & FILE_ATTRIBUTE_DIRECTORY)
983 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
984 else
985 m |= _S_IFREG;
986 if (attr & FILE_ATTRIBUTE_READONLY)
987 m |= 0444;
988 else
989 m |= 0666;
990 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000991}
992
993static int
994attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
995{
Victor Stinner97b89882010-05-06 00:25:39 +0000996 memset(result, 0, sizeof(*result));
997 result->st_mode = attributes_to_mode(info->dwFileAttributes);
998 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
999 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1000 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1001 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +00001002
Victor Stinner97b89882010-05-06 00:25:39 +00001003 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001004}
1005
Thomas Wouters89f507f2006-12-13 04:49:30 +00001006/* Emulate GetFileAttributesEx[AW] on Windows 95 */
1007static int checked = 0;
1008static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
1009static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
1010static void
1011check_gfax()
1012{
Victor Stinner97b89882010-05-06 00:25:39 +00001013 HINSTANCE hKernel32;
1014 if (checked)
1015 return;
1016 checked = 1;
1017 hKernel32 = GetModuleHandle("KERNEL32");
1018 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
1019 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
Thomas Wouters89f507f2006-12-13 04:49:30 +00001020}
1021
Guido van Rossumd8faa362007-04-27 19:54:29 +00001022static BOOL
1023attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1024{
Victor Stinner97b89882010-05-06 00:25:39 +00001025 HANDLE hFindFile;
1026 WIN32_FIND_DATAA FileData;
1027 hFindFile = FindFirstFileA(pszFile, &FileData);
1028 if (hFindFile == INVALID_HANDLE_VALUE)
1029 return FALSE;
1030 FindClose(hFindFile);
1031 pfad->dwFileAttributes = FileData.dwFileAttributes;
1032 pfad->ftCreationTime = FileData.ftCreationTime;
1033 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1034 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1035 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1036 pfad->nFileSizeLow = FileData.nFileSizeLow;
1037 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001038}
1039
1040static BOOL
1041attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1042{
Victor Stinner97b89882010-05-06 00:25:39 +00001043 HANDLE hFindFile;
1044 WIN32_FIND_DATAW FileData;
1045 hFindFile = FindFirstFileW(pszFile, &FileData);
1046 if (hFindFile == INVALID_HANDLE_VALUE)
1047 return FALSE;
1048 FindClose(hFindFile);
1049 pfad->dwFileAttributes = FileData.dwFileAttributes;
1050 pfad->ftCreationTime = FileData.ftCreationTime;
1051 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1052 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1053 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1054 pfad->nFileSizeLow = FileData.nFileSizeLow;
1055 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001056}
1057
Thomas Wouters89f507f2006-12-13 04:49:30 +00001058static BOOL WINAPI
Victor Stinner97b89882010-05-06 00:25:39 +00001059Py_GetFileAttributesExA(LPCSTR pszFile,
1060 GET_FILEEX_INFO_LEVELS level,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001061 LPVOID pv)
1062{
Victor Stinner97b89882010-05-06 00:25:39 +00001063 BOOL result;
1064 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1065 /* First try to use the system's implementation, if that is
1066 available and either succeeds to gives an error other than
1067 that it isn't implemented. */
1068 check_gfax();
1069 if (gfaxa) {
1070 result = gfaxa(pszFile, level, pv);
1071 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1072 return result;
1073 }
1074 /* It's either not present, or not implemented.
1075 Emulate using FindFirstFile. */
1076 if (level != GetFileExInfoStandard) {
1077 SetLastError(ERROR_INVALID_PARAMETER);
1078 return FALSE;
1079 }
1080 /* Use GetFileAttributes to validate that the file name
1081 does not contain wildcards (which FindFirstFile would
1082 accept). */
1083 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1084 return FALSE;
1085 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001086}
1087
1088static BOOL WINAPI
Victor Stinner97b89882010-05-06 00:25:39 +00001089Py_GetFileAttributesExW(LPCWSTR pszFile,
1090 GET_FILEEX_INFO_LEVELS level,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001091 LPVOID pv)
1092{
Victor Stinner97b89882010-05-06 00:25:39 +00001093 BOOL result;
1094 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1095 /* First try to use the system's implementation, if that is
1096 available and either succeeds to gives an error other than
1097 that it isn't implemented. */
1098 check_gfax();
1099 if (gfaxa) {
1100 result = gfaxw(pszFile, level, pv);
1101 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1102 return result;
1103 }
1104 /* It's either not present, or not implemented.
1105 Emulate using FindFirstFile. */
1106 if (level != GetFileExInfoStandard) {
1107 SetLastError(ERROR_INVALID_PARAMETER);
1108 return FALSE;
1109 }
1110 /* Use GetFileAttributes to validate that the file name
1111 does not contain wildcards (which FindFirstFile would
1112 accept). */
1113 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1114 return FALSE;
1115 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001116}
1117
Victor Stinner97b89882010-05-06 00:25:39 +00001118static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001119win32_stat(const char* path, struct win32_stat *result)
1120{
Victor Stinner97b89882010-05-06 00:25:39 +00001121 WIN32_FILE_ATTRIBUTE_DATA info;
1122 int code;
1123 char *dot;
1124 /* XXX not supported on Win95 and NT 3.x */
1125 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1126 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1127 /* Protocol violation: we explicitly clear errno, instead of
1128 setting it to a POSIX error. Callers should use GetLastError. */
1129 errno = 0;
1130 return -1;
1131 } else {
1132 /* Could not get attributes on open file. Fall back to
1133 reading the directory. */
1134 if (!attributes_from_dir(path, &info)) {
1135 /* Very strange. This should not fail now */
1136 errno = 0;
1137 return -1;
1138 }
1139 }
1140 }
1141 code = attribute_data_to_stat(&info, result);
1142 if (code != 0)
1143 return code;
1144 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1145 dot = strrchr(path, '.');
1146 if (dot) {
1147 if (stricmp(dot, ".bat") == 0 ||
1148 stricmp(dot, ".cmd") == 0 ||
1149 stricmp(dot, ".exe") == 0 ||
1150 stricmp(dot, ".com") == 0)
1151 result->st_mode |= 0111;
1152 }
1153 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001154}
1155
Victor Stinner97b89882010-05-06 00:25:39 +00001156static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001157win32_wstat(const wchar_t* path, struct win32_stat *result)
1158{
Victor Stinner97b89882010-05-06 00:25:39 +00001159 int code;
1160 const wchar_t *dot;
1161 WIN32_FILE_ATTRIBUTE_DATA info;
1162 /* XXX not supported on Win95 and NT 3.x */
1163 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1164 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1165 /* Protocol violation: we explicitly clear errno, instead of
1166 setting it to a POSIX error. Callers should use GetLastError. */
1167 errno = 0;
1168 return -1;
1169 } else {
1170 /* Could not get attributes on open file. Fall back to
1171 reading the directory. */
1172 if (!attributes_from_dir_w(path, &info)) {
1173 /* Very strange. This should not fail now */
1174 errno = 0;
1175 return -1;
1176 }
1177 }
1178 }
1179 code = attribute_data_to_stat(&info, result);
1180 if (code < 0)
1181 return code;
1182 /* Set IFEXEC if it is an .exe, .bat, ... */
1183 dot = wcsrchr(path, '.');
1184 if (dot) {
1185 if (_wcsicmp(dot, L".bat") == 0 ||
1186 _wcsicmp(dot, L".cmd") == 0 ||
1187 _wcsicmp(dot, L".exe") == 0 ||
1188 _wcsicmp(dot, L".com") == 0)
1189 result->st_mode |= 0111;
1190 }
1191 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001192}
1193
1194static int
1195win32_fstat(int file_number, struct win32_stat *result)
1196{
Victor Stinner97b89882010-05-06 00:25:39 +00001197 BY_HANDLE_FILE_INFORMATION info;
1198 HANDLE h;
1199 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001200
Victor Stinner97b89882010-05-06 00:25:39 +00001201 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001202
Victor Stinner97b89882010-05-06 00:25:39 +00001203 /* Protocol violation: we explicitly clear errno, instead of
1204 setting it to a POSIX error. Callers should use GetLastError. */
1205 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001206
Victor Stinner97b89882010-05-06 00:25:39 +00001207 if (h == INVALID_HANDLE_VALUE) {
1208 /* This is really a C library error (invalid file handle).
1209 We set the Win32 error to the closes one matching. */
1210 SetLastError(ERROR_INVALID_HANDLE);
1211 return -1;
1212 }
1213 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001214
Victor Stinner97b89882010-05-06 00:25:39 +00001215 type = GetFileType(h);
1216 if (type == FILE_TYPE_UNKNOWN) {
1217 DWORD error = GetLastError();
1218 if (error != 0) {
1219 return -1;
1220 }
1221 /* else: valid but unknown file */
1222 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001223
Victor Stinner97b89882010-05-06 00:25:39 +00001224 if (type != FILE_TYPE_DISK) {
1225 if (type == FILE_TYPE_CHAR)
1226 result->st_mode = _S_IFCHR;
1227 else if (type == FILE_TYPE_PIPE)
1228 result->st_mode = _S_IFIFO;
1229 return 0;
1230 }
1231
1232 if (!GetFileInformationByHandle(h, &info)) {
1233 return -1;
1234 }
1235
1236 /* similar to stat() */
1237 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1238 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1239 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1240 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1241 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1242 /* specific to fstat() */
1243 result->st_nlink = info.nNumberOfLinks;
1244 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1245 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001246}
1247
1248#endif /* MS_WINDOWS */
1249
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001250PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001251"stat_result: Result from stat or lstat.\n\n\
1252This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001253 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001254or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1255\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001256Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1257or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001258\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001259See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001260
1261static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner97b89882010-05-06 00:25:39 +00001262 {"st_mode", "protection bits"},
1263 {"st_ino", "inode"},
1264 {"st_dev", "device"},
1265 {"st_nlink", "number of hard links"},
1266 {"st_uid", "user ID of owner"},
1267 {"st_gid", "group ID of owner"},
1268 {"st_size", "total size, in bytes"},
1269 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1270 {NULL, "integer time of last access"},
1271 {NULL, "integer time of last modification"},
1272 {NULL, "integer time of last change"},
1273 {"st_atime", "time of last access"},
1274 {"st_mtime", "time of last modification"},
1275 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001276#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner97b89882010-05-06 00:25:39 +00001277 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001278#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001279#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner97b89882010-05-06 00:25:39 +00001280 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001281#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001282#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner97b89882010-05-06 00:25:39 +00001283 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001284#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001285#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00001286 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001287#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001288#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner97b89882010-05-06 00:25:39 +00001289 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001290#endif
1291#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner97b89882010-05-06 00:25:39 +00001292 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001293#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001294 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001295};
1296
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001297#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001298#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001299#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001300#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001301#endif
1302
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001303#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001304#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1305#else
1306#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1307#endif
1308
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001309#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001310#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1311#else
1312#define ST_RDEV_IDX ST_BLOCKS_IDX
1313#endif
1314
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001315#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1316#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1317#else
1318#define ST_FLAGS_IDX ST_RDEV_IDX
1319#endif
1320
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001321#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001322#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001323#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001324#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001325#endif
1326
1327#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1328#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1329#else
1330#define ST_BIRTHTIME_IDX ST_GEN_IDX
1331#endif
1332
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001333static PyStructSequence_Desc stat_result_desc = {
Victor Stinner97b89882010-05-06 00:25:39 +00001334 "stat_result", /* name */
1335 stat_result__doc__, /* doc */
1336 stat_result_fields,
1337 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001338};
1339
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001340PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001341"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1342This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001343 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001344or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001345\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001346See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001347
1348static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner97b89882010-05-06 00:25:39 +00001349 {"f_bsize", },
1350 {"f_frsize", },
1351 {"f_blocks", },
1352 {"f_bfree", },
1353 {"f_bavail", },
1354 {"f_files", },
1355 {"f_ffree", },
1356 {"f_favail", },
1357 {"f_flag", },
1358 {"f_namemax",},
1359 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001360};
1361
1362static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner97b89882010-05-06 00:25:39 +00001363 "statvfs_result", /* name */
1364 statvfs_result__doc__, /* doc */
1365 statvfs_result_fields,
1366 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001367};
1368
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001369static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001370static PyTypeObject StatResultType;
1371static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001372static newfunc structseq_new;
1373
1374static PyObject *
1375statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1376{
Victor Stinner97b89882010-05-06 00:25:39 +00001377 PyStructSequence *result;
1378 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001379
Victor Stinner97b89882010-05-06 00:25:39 +00001380 result = (PyStructSequence*)structseq_new(type, args, kwds);
1381 if (!result)
1382 return NULL;
1383 /* If we have been initialized from a tuple,
1384 st_?time might be set to None. Initialize it
1385 from the int slots. */
1386 for (i = 7; i <= 9; i++) {
1387 if (result->ob_item[i+3] == Py_None) {
1388 Py_DECREF(Py_None);
1389 Py_INCREF(result->ob_item[i]);
1390 result->ob_item[i+3] = result->ob_item[i];
1391 }
1392 }
1393 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001394}
1395
1396
1397
1398/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001399static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001400
1401PyDoc_STRVAR(stat_float_times__doc__,
1402"stat_float_times([newval]) -> oldval\n\n\
1403Determine whether os.[lf]stat represents time stamps as float objects.\n\
1404If newval is True, future calls to stat() return floats, if it is False,\n\
1405future calls return ints. \n\
1406If newval is omitted, return the current setting.\n");
1407
1408static PyObject*
1409stat_float_times(PyObject* self, PyObject *args)
1410{
Victor Stinner97b89882010-05-06 00:25:39 +00001411 int newval = -1;
1412 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1413 return NULL;
1414 if (newval == -1)
1415 /* Return old value */
1416 return PyBool_FromLong(_stat_float_times);
1417 _stat_float_times = newval;
1418 Py_INCREF(Py_None);
1419 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001420}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001421
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001422static void
1423fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1424{
Victor Stinner97b89882010-05-06 00:25:39 +00001425 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001426#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner97b89882010-05-06 00:25:39 +00001427 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001428#else
Victor Stinner97b89882010-05-06 00:25:39 +00001429 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001430#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001431 if (!ival)
1432 return;
1433 if (_stat_float_times) {
1434 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1435 } else {
1436 fval = ival;
1437 Py_INCREF(fval);
1438 }
1439 PyStructSequence_SET_ITEM(v, index, ival);
1440 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001441}
1442
Tim Peters5aa91602002-01-30 05:46:57 +00001443/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001444 (used by posix_stat() and posix_fstat()) */
1445static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001446_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001447{
Victor Stinner97b89882010-05-06 00:25:39 +00001448 unsigned long ansec, mnsec, cnsec;
1449 PyObject *v = PyStructSequence_New(&StatResultType);
1450 if (v == NULL)
1451 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001452
Victor Stinner97b89882010-05-06 00:25:39 +00001453 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001454#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner97b89882010-05-06 00:25:39 +00001455 PyStructSequence_SET_ITEM(v, 1,
1456 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001457#else
Victor Stinner97b89882010-05-06 00:25:39 +00001458 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001459#endif
1460#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +00001461 PyStructSequence_SET_ITEM(v, 2,
1462 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001463#else
Victor Stinner97b89882010-05-06 00:25:39 +00001464 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001465#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001466 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1467 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1468 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001469#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner97b89882010-05-06 00:25:39 +00001470 PyStructSequence_SET_ITEM(v, 6,
1471 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001472#else
Victor Stinner97b89882010-05-06 00:25:39 +00001473 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001474#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001475
Martin v. Löwis14694662006-02-03 12:54:16 +00001476#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner97b89882010-05-06 00:25:39 +00001477 ansec = st->st_atim.tv_nsec;
1478 mnsec = st->st_mtim.tv_nsec;
1479 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001480#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner97b89882010-05-06 00:25:39 +00001481 ansec = st->st_atimespec.tv_nsec;
1482 mnsec = st->st_mtimespec.tv_nsec;
1483 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001484#elif defined(HAVE_STAT_NSEC)
Victor Stinner97b89882010-05-06 00:25:39 +00001485 ansec = st->st_atime_nsec;
1486 mnsec = st->st_mtime_nsec;
1487 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001488#else
Victor Stinner97b89882010-05-06 00:25:39 +00001489 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001490#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001491 fill_time(v, 7, st->st_atime, ansec);
1492 fill_time(v, 8, st->st_mtime, mnsec);
1493 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001494
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001495#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner97b89882010-05-06 00:25:39 +00001496 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1497 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001498#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001499#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner97b89882010-05-06 00:25:39 +00001500 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1501 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001502#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001503#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner97b89882010-05-06 00:25:39 +00001504 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1505 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001506#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001507#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner97b89882010-05-06 00:25:39 +00001508 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1509 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001510#endif
1511#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner97b89882010-05-06 00:25:39 +00001512 {
1513 PyObject *val;
1514 unsigned long bsec,bnsec;
1515 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001516#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner97b89882010-05-06 00:25:39 +00001517 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001518#else
Victor Stinner97b89882010-05-06 00:25:39 +00001519 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001520#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001521 if (_stat_float_times) {
1522 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1523 } else {
1524 val = PyLong_FromLong((long)bsec);
1525 }
1526 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1527 val);
1528 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001529#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001530#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00001531 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1532 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001533#endif
Fred Drake699f3522000-06-29 21:12:41 +00001534
Victor Stinner97b89882010-05-06 00:25:39 +00001535 if (PyErr_Occurred()) {
1536 Py_DECREF(v);
1537 return NULL;
1538 }
Fred Drake699f3522000-06-29 21:12:41 +00001539
Victor Stinner97b89882010-05-06 00:25:39 +00001540 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001541}
1542
Martin v. Löwisd8948722004-06-02 09:57:56 +00001543#ifdef MS_WINDOWS
1544
1545/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1546 where / can be used in place of \ and the trailing slash is optional.
1547 Both SERVER and SHARE must have at least one character.
1548*/
1549
1550#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1551#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001552#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001553#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001554#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001555
Tim Peters4ad82172004-08-30 17:02:04 +00001556static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001557IsUNCRootA(char *path, int pathlen)
1558{
Victor Stinner97b89882010-05-06 00:25:39 +00001559 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001560
Victor Stinner97b89882010-05-06 00:25:39 +00001561 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001562
Victor Stinner97b89882010-05-06 00:25:39 +00001563 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1564 /* minimum UNCRoot is \\x\y */
1565 return FALSE;
1566 for (i = 2; i < pathlen ; i++)
1567 if (ISSLASH(path[i])) break;
1568 if (i == 2 || i == pathlen)
1569 /* do not allow \\\SHARE or \\SERVER */
1570 return FALSE;
1571 share = i+1;
1572 for (i = share; i < pathlen; i++)
1573 if (ISSLASH(path[i])) break;
1574 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001575
Victor Stinner97b89882010-05-06 00:25:39 +00001576 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001577}
1578
Tim Peters4ad82172004-08-30 17:02:04 +00001579static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001580IsUNCRootW(Py_UNICODE *path, int pathlen)
1581{
Victor Stinner97b89882010-05-06 00:25:39 +00001582 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001583
Victor Stinner97b89882010-05-06 00:25:39 +00001584 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001585
Victor Stinner97b89882010-05-06 00:25:39 +00001586 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1587 /* minimum UNCRoot is \\x\y */
1588 return FALSE;
1589 for (i = 2; i < pathlen ; i++)
1590 if (ISSLASH(path[i])) break;
1591 if (i == 2 || i == pathlen)
1592 /* do not allow \\\SHARE or \\SERVER */
1593 return FALSE;
1594 share = i+1;
1595 for (i = share; i < pathlen; i++)
1596 if (ISSLASH(path[i])) break;
1597 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001598
Victor Stinner97b89882010-05-06 00:25:39 +00001599 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001600}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001601#endif /* MS_WINDOWS */
1602
Barry Warsaw53699e91996-12-10 23:23:01 +00001603static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001604posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner97b89882010-05-06 00:25:39 +00001605 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001606#ifdef __VMS
Victor Stinner97b89882010-05-06 00:25:39 +00001607 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001608#else
Victor Stinner97b89882010-05-06 00:25:39 +00001609 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001610#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001611 char *wformat,
1612 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001613{
Victor Stinner97b89882010-05-06 00:25:39 +00001614 STRUCT_STAT st;
1615 PyObject *opath;
1616 char *path;
1617 int res;
1618 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001619
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001620#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001621 /* If on wide-character-capable OS see if argument
1622 is Unicode and if so use wide API. */
1623 if (unicode_file_names()) {
1624 PyUnicodeObject *po;
1625 if (PyArg_ParseTuple(args, wformat, &po)) {
1626 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001627
Victor Stinner97b89882010-05-06 00:25:39 +00001628 Py_BEGIN_ALLOW_THREADS
1629 /* PyUnicode_AS_UNICODE result OK without
1630 thread lock as it is a simple dereference. */
1631 res = wstatfunc(wpath, &st);
1632 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001633
Victor Stinner97b89882010-05-06 00:25:39 +00001634 if (res != 0)
1635 return win32_error_unicode("stat", wpath);
1636 return _pystat_fromstructstat(&st);
1637 }
1638 /* Drop the argument parsing error as narrow strings
1639 are also valid. */
1640 PyErr_Clear();
1641 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001642#endif
1643
Victor Stinner97b89882010-05-06 00:25:39 +00001644 if (!PyArg_ParseTuple(args, format,
1645 PyUnicode_FSConverter, &opath))
1646 return NULL;
1647 path = bytes2str(opath, 1);
1648 Py_BEGIN_ALLOW_THREADS
1649 res = (*statfunc)(path, &st);
1650 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001651
Victor Stinner97b89882010-05-06 00:25:39 +00001652 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001653#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001654 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001655#else
Victor Stinner97b89882010-05-06 00:25:39 +00001656 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001657#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001658 }
1659 else
1660 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001661
Victor Stinner97b89882010-05-06 00:25:39 +00001662 release_bytes(opath);
1663 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001664}
1665
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001666/* POSIX methods */
1667
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001668PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001669"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001670Use the real uid/gid to test for access to a path. Note that most\n\
1671operations will use the effective uid/gid, therefore this routine can\n\
1672be used in a suid/sgid environment to test if the invoking user has the\n\
1673specified access to the path. The mode argument can be F_OK to test\n\
1674existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001675
1676static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001677posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001678{
Victor Stinner97b89882010-05-06 00:25:39 +00001679 PyObject *opath;
1680 char *path;
1681 int mode;
1682
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001683#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001684 DWORD attr;
1685 if (unicode_file_names()) {
1686 PyUnicodeObject *po;
1687 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1688 Py_BEGIN_ALLOW_THREADS
1689 /* PyUnicode_AS_UNICODE OK without thread lock as
1690 it is a simple dereference. */
1691 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1692 Py_END_ALLOW_THREADS
1693 goto finish;
1694 }
1695 /* Drop the argument parsing error as narrow strings
1696 are also valid. */
1697 PyErr_Clear();
1698 }
1699 if (!PyArg_ParseTuple(args, "O&i:access",
1700 PyUnicode_FSConverter, &opath, &mode))
1701 return 0;
1702 path = bytes2str(opath, 1);
1703 Py_BEGIN_ALLOW_THREADS
1704 attr = GetFileAttributesA(path);
1705 Py_END_ALLOW_THREADS
1706 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001707finish:
Victor Stinner97b89882010-05-06 00:25:39 +00001708 if (attr == 0xFFFFFFFF)
1709 /* File does not exist, or cannot read attributes */
1710 return PyBool_FromLong(0);
1711 /* Access is possible if either write access wasn't requested, or
1712 the file isn't read-only, or if it's a directory, as there are
1713 no read-only directories on Windows. */
1714 return PyBool_FromLong(!(mode & 2)
1715 || !(attr & FILE_ATTRIBUTE_READONLY)
1716 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001717#else
Victor Stinner97b89882010-05-06 00:25:39 +00001718 int res;
1719 if (!PyArg_ParseTuple(args, "O&i:access",
1720 PyUnicode_FSConverter, &opath, &mode))
1721 return NULL;
1722 path = bytes2str(opath, 1);
1723 Py_BEGIN_ALLOW_THREADS
1724 res = access(path, mode);
1725 Py_END_ALLOW_THREADS
1726 release_bytes(opath);
1727 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001728#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001729}
1730
Guido van Rossumd371ff11999-01-25 16:12:23 +00001731#ifndef F_OK
1732#define F_OK 0
1733#endif
1734#ifndef R_OK
1735#define R_OK 4
1736#endif
1737#ifndef W_OK
1738#define W_OK 2
1739#endif
1740#ifndef X_OK
1741#define X_OK 1
1742#endif
1743
1744#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001745PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001746"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001747Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001748
1749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001750posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001751{
Victor Stinner97b89882010-05-06 00:25:39 +00001752 int id;
1753 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001754
Victor Stinner97b89882010-05-06 00:25:39 +00001755 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1756 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001757
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001758#if defined(__VMS)
Victor Stinner97b89882010-05-06 00:25:39 +00001759 /* file descriptor 0 only, the default input device (stdin) */
1760 if (id == 0) {
1761 ret = ttyname();
1762 }
1763 else {
1764 ret = NULL;
1765 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001766#else
Victor Stinner97b89882010-05-06 00:25:39 +00001767 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001768#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001769 if (ret == NULL)
1770 return posix_error();
Victor Stinnerbae0e622010-08-15 09:15:02 +00001771 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001772}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001773#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001774
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001775#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001776PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001777"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001778Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001779
1780static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001781posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001782{
Victor Stinner97b89882010-05-06 00:25:39 +00001783 char *ret;
1784 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001785
Greg Wardb48bc172000-03-01 21:51:56 +00001786#ifdef USE_CTERMID_R
Victor Stinner97b89882010-05-06 00:25:39 +00001787 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001788#else
Victor Stinner97b89882010-05-06 00:25:39 +00001789 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001790#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001791 if (ret == NULL)
1792 return posix_error();
Victor Stinnerbae0e622010-08-15 09:15:02 +00001793 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001794}
1795#endif
1796
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001797PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001798"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001799Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001800
Barry Warsaw53699e91996-12-10 23:23:01 +00001801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001802posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001803{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001804#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001805 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001806#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00001807 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001808#elif defined(__VMS)
Victor Stinner97b89882010-05-06 00:25:39 +00001809 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001810#else
Victor Stinner97b89882010-05-06 00:25:39 +00001811 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001812#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001813}
1814
Fred Drake4d1e64b2002-04-15 19:40:07 +00001815#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001816PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001817"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001818Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001819opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001820
1821static PyObject *
1822posix_fchdir(PyObject *self, PyObject *fdobj)
1823{
Victor Stinner97b89882010-05-06 00:25:39 +00001824 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001825}
1826#endif /* HAVE_FCHDIR */
1827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001828
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001829PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001830"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001831Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001832
Barry Warsaw53699e91996-12-10 23:23:01 +00001833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001834posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001835{
Victor Stinner97b89882010-05-06 00:25:39 +00001836 PyObject *opath = NULL;
1837 char *path = NULL;
1838 int i;
1839 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001840#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001841 DWORD attr;
1842 if (unicode_file_names()) {
1843 PyUnicodeObject *po;
1844 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1845 Py_BEGIN_ALLOW_THREADS
1846 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1847 if (attr != 0xFFFFFFFF) {
1848 if (i & _S_IWRITE)
1849 attr &= ~FILE_ATTRIBUTE_READONLY;
1850 else
1851 attr |= FILE_ATTRIBUTE_READONLY;
1852 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1853 }
1854 else
1855 res = 0;
1856 Py_END_ALLOW_THREADS
1857 if (!res)
1858 return win32_error_unicode("chmod",
1859 PyUnicode_AS_UNICODE(po));
1860 Py_INCREF(Py_None);
1861 return Py_None;
1862 }
1863 /* Drop the argument parsing error as narrow strings
1864 are also valid. */
1865 PyErr_Clear();
1866 }
1867 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1868 &opath, &i))
1869 return NULL;
1870 path = bytes2str(opath, 1);
1871 Py_BEGIN_ALLOW_THREADS
1872 attr = GetFileAttributesA(path);
1873 if (attr != 0xFFFFFFFF) {
1874 if (i & _S_IWRITE)
1875 attr &= ~FILE_ATTRIBUTE_READONLY;
1876 else
1877 attr |= FILE_ATTRIBUTE_READONLY;
1878 res = SetFileAttributesA(path, attr);
1879 }
1880 else
1881 res = 0;
1882 Py_END_ALLOW_THREADS
1883 if (!res) {
1884 win32_error("chmod", path);
1885 release_bytes(opath);
1886 return NULL;
1887 }
1888 release_bytes(opath);
1889 Py_INCREF(Py_None);
1890 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001891#else /* MS_WINDOWS */
Victor Stinner97b89882010-05-06 00:25:39 +00001892 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1893 &opath, &i))
1894 return NULL;
1895 path = bytes2str(opath, 1);
1896 Py_BEGIN_ALLOW_THREADS
1897 res = chmod(path, i);
1898 Py_END_ALLOW_THREADS
1899 if (res < 0)
1900 return posix_error_with_allocated_filename(opath);
1901 release_bytes(opath);
1902 Py_INCREF(Py_None);
1903 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001904#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001905}
1906
Christian Heimes4e30a842007-11-30 22:12:06 +00001907#ifdef HAVE_FCHMOD
1908PyDoc_STRVAR(posix_fchmod__doc__,
1909"fchmod(fd, mode)\n\n\
1910Change the access permissions of the file given by file\n\
1911descriptor fd.");
1912
1913static PyObject *
1914posix_fchmod(PyObject *self, PyObject *args)
1915{
Victor Stinner97b89882010-05-06 00:25:39 +00001916 int fd, mode, res;
1917 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1918 return NULL;
1919 Py_BEGIN_ALLOW_THREADS
1920 res = fchmod(fd, mode);
1921 Py_END_ALLOW_THREADS
1922 if (res < 0)
1923 return posix_error();
1924 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001925}
1926#endif /* HAVE_FCHMOD */
1927
1928#ifdef HAVE_LCHMOD
1929PyDoc_STRVAR(posix_lchmod__doc__,
1930"lchmod(path, mode)\n\n\
1931Change the access permissions of a file. If path is a symlink, this\n\
1932affects the link itself rather than the target.");
1933
1934static PyObject *
1935posix_lchmod(PyObject *self, PyObject *args)
1936{
Victor Stinner97b89882010-05-06 00:25:39 +00001937 PyObject *opath;
1938 char *path;
1939 int i;
1940 int res;
1941 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1942 &opath, &i))
1943 return NULL;
1944 path = bytes2str(opath, 1);
1945 Py_BEGIN_ALLOW_THREADS
1946 res = lchmod(path, i);
1947 Py_END_ALLOW_THREADS
1948 if (res < 0)
1949 return posix_error_with_allocated_filename(opath);
1950 release_bytes(opath);
1951 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001952}
1953#endif /* HAVE_LCHMOD */
1954
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001955
Thomas Wouterscf297e42007-02-23 15:07:44 +00001956#ifdef HAVE_CHFLAGS
1957PyDoc_STRVAR(posix_chflags__doc__,
1958"chflags(path, flags)\n\n\
1959Set file flags.");
1960
1961static PyObject *
1962posix_chflags(PyObject *self, PyObject *args)
1963{
Victor Stinner97b89882010-05-06 00:25:39 +00001964 PyObject *opath;
1965 char *path;
1966 unsigned long flags;
1967 int res;
1968 if (!PyArg_ParseTuple(args, "O&k:chflags",
1969 PyUnicode_FSConverter, &opath, &flags))
1970 return NULL;
1971 path = bytes2str(opath, 1);
1972 Py_BEGIN_ALLOW_THREADS
1973 res = chflags(path, flags);
1974 Py_END_ALLOW_THREADS
1975 if (res < 0)
1976 return posix_error_with_allocated_filename(opath);
1977 release_bytes(opath);
1978 Py_INCREF(Py_None);
1979 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00001980}
1981#endif /* HAVE_CHFLAGS */
1982
1983#ifdef HAVE_LCHFLAGS
1984PyDoc_STRVAR(posix_lchflags__doc__,
1985"lchflags(path, flags)\n\n\
1986Set file flags.\n\
1987This function will not follow symbolic links.");
1988
1989static PyObject *
1990posix_lchflags(PyObject *self, PyObject *args)
1991{
Victor Stinner97b89882010-05-06 00:25:39 +00001992 PyObject *opath;
1993 char *path;
1994 unsigned long flags;
1995 int res;
1996 if (!PyArg_ParseTuple(args, "O&k:lchflags",
1997 PyUnicode_FSConverter, &opath, &flags))
1998 return NULL;
1999 path = bytes2str(opath, 1);
2000 Py_BEGIN_ALLOW_THREADS
2001 res = lchflags(path, flags);
2002 Py_END_ALLOW_THREADS
2003 if (res < 0)
2004 return posix_error_with_allocated_filename(opath);
2005 release_bytes(opath);
2006 Py_INCREF(Py_None);
2007 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002008}
2009#endif /* HAVE_LCHFLAGS */
2010
Martin v. Löwis244edc82001-10-04 22:44:26 +00002011#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002012PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002013"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002014Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002015
2016static PyObject *
2017posix_chroot(PyObject *self, PyObject *args)
2018{
Victor Stinner97b89882010-05-06 00:25:39 +00002019 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002020}
2021#endif
2022
Guido van Rossum21142a01999-01-08 21:05:37 +00002023#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002024PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002025"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002026force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002027
2028static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002029posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002030{
Stefan Krah67733312010-11-26 17:04:40 +00002031 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002032}
2033#endif /* HAVE_FSYNC */
2034
2035#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002036
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002037#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002038extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2039#endif
2040
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002041PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002042"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002043force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002044 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002045
2046static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002047posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002048{
Stefan Krah67733312010-11-26 17:04:40 +00002049 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002050}
2051#endif /* HAVE_FDATASYNC */
2052
2053
Fredrik Lundh10723342000-07-10 16:38:09 +00002054#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002055PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002056"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002057Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002058
Barry Warsaw53699e91996-12-10 23:23:01 +00002059static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002060posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002061{
Victor Stinner97b89882010-05-06 00:25:39 +00002062 PyObject *opath;
2063 char *path;
2064 long uid, gid;
2065 int res;
2066 if (!PyArg_ParseTuple(args, "O&ll:chown",
2067 PyUnicode_FSConverter, &opath,
2068 &uid, &gid))
2069 return NULL;
2070 path = bytes2str(opath, 1);
2071 Py_BEGIN_ALLOW_THREADS
2072 res = chown(path, (uid_t) uid, (gid_t) gid);
2073 Py_END_ALLOW_THREADS
2074 if (res < 0)
2075 return posix_error_with_allocated_filename(opath);
2076 release_bytes(opath);
2077 Py_INCREF(Py_None);
2078 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002079}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002080#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002081
Christian Heimes4e30a842007-11-30 22:12:06 +00002082#ifdef HAVE_FCHOWN
2083PyDoc_STRVAR(posix_fchown__doc__,
2084"fchown(fd, uid, gid)\n\n\
2085Change the owner and group id of the file given by file descriptor\n\
2086fd to the numeric uid and gid.");
2087
2088static PyObject *
2089posix_fchown(PyObject *self, PyObject *args)
2090{
Victor Stinner97b89882010-05-06 00:25:39 +00002091 int fd;
2092 long uid, gid;
2093 int res;
2094 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2095 return NULL;
2096 Py_BEGIN_ALLOW_THREADS
2097 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2098 Py_END_ALLOW_THREADS
2099 if (res < 0)
2100 return posix_error();
2101 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002102}
2103#endif /* HAVE_FCHOWN */
2104
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002105#ifdef HAVE_LCHOWN
2106PyDoc_STRVAR(posix_lchown__doc__,
2107"lchown(path, uid, gid)\n\n\
2108Change the owner and group id of path to the numeric uid and gid.\n\
2109This function will not follow symbolic links.");
2110
2111static PyObject *
2112posix_lchown(PyObject *self, PyObject *args)
2113{
Victor Stinner97b89882010-05-06 00:25:39 +00002114 PyObject *opath;
2115 char *path;
2116 long uid, gid;
2117 int res;
2118 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2119 PyUnicode_FSConverter, &opath,
2120 &uid, &gid))
2121 return NULL;
2122 path = bytes2str(opath, 1);
2123 Py_BEGIN_ALLOW_THREADS
2124 res = lchown(path, (uid_t) uid, (gid_t) gid);
2125 Py_END_ALLOW_THREADS
2126 if (res < 0)
2127 return posix_error_with_allocated_filename(opath);
2128 release_bytes(opath);
2129 Py_INCREF(Py_None);
2130 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002131}
2132#endif /* HAVE_LCHOWN */
2133
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002134
Guido van Rossum36bc6801995-06-14 22:54:23 +00002135#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002136static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002137posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002138{
Victor Stinner97b89882010-05-06 00:25:39 +00002139 char buf[1026];
2140 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002141
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002142#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002143 if (!use_bytes && unicode_file_names()) {
2144 wchar_t wbuf[1026];
2145 wchar_t *wbuf2 = wbuf;
2146 PyObject *resobj;
2147 DWORD len;
2148 Py_BEGIN_ALLOW_THREADS
2149 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2150 /* If the buffer is large enough, len does not include the
2151 terminating \0. If the buffer is too small, len includes
2152 the space needed for the terminator. */
2153 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2154 wbuf2 = malloc(len * sizeof(wchar_t));
2155 if (wbuf2)
2156 len = GetCurrentDirectoryW(len, wbuf2);
2157 }
2158 Py_END_ALLOW_THREADS
2159 if (!wbuf2) {
2160 PyErr_NoMemory();
2161 return NULL;
2162 }
2163 if (!len) {
2164 if (wbuf2 != wbuf) free(wbuf2);
2165 return win32_error("getcwdu", NULL);
2166 }
2167 resobj = PyUnicode_FromWideChar(wbuf2, len);
2168 if (wbuf2 != wbuf) free(wbuf2);
2169 return resobj;
2170 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002171#endif
2172
Victor Stinner97b89882010-05-06 00:25:39 +00002173 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002174#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00002175 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002176#else
Victor Stinner97b89882010-05-06 00:25:39 +00002177 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002178#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002179 Py_END_ALLOW_THREADS
2180 if (res == NULL)
2181 return posix_error();
2182 if (use_bytes)
2183 return PyBytes_FromStringAndSize(buf, strlen(buf));
2184 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"surrogateescape");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002185}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002186
2187PyDoc_STRVAR(posix_getcwd__doc__,
2188"getcwd() -> path\n\n\
2189Return a unicode string representing the current working directory.");
2190
2191static PyObject *
2192posix_getcwd_unicode(PyObject *self)
2193{
2194 return posix_getcwd(0);
2195}
2196
2197PyDoc_STRVAR(posix_getcwdb__doc__,
2198"getcwdb() -> path\n\n\
2199Return a bytes string representing the current working directory.");
2200
2201static PyObject *
2202posix_getcwd_bytes(PyObject *self)
2203{
2204 return posix_getcwd(1);
2205}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002206#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002207
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002208
Guido van Rossumb6775db1994-08-01 11:34:53 +00002209#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002210PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002211"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002212Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002213
Barry Warsaw53699e91996-12-10 23:23:01 +00002214static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002215posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002216{
Victor Stinner97b89882010-05-06 00:25:39 +00002217 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002218}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002219#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002220
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002221
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002222PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002223"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002224Return a list containing the names of the entries in the directory.\n\
2225\n\
Victor Stinner97b89882010-05-06 00:25:39 +00002226 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002227\n\
2228The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002229entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002230
Barry Warsaw53699e91996-12-10 23:23:01 +00002231static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002232posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002233{
Victor Stinner97b89882010-05-06 00:25:39 +00002234 /* XXX Should redo this putting the (now four) versions of opendir
2235 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002236#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002237
Victor Stinner97b89882010-05-06 00:25:39 +00002238 PyObject *d, *v;
2239 HANDLE hFindFile;
2240 BOOL result;
2241 WIN32_FIND_DATA FileData;
2242 PyObject *opath;
2243 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2244 char *bufptr = namebuf;
2245 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002246
Victor Stinner97b89882010-05-06 00:25:39 +00002247 /* If on wide-character-capable OS see if argument
2248 is Unicode and if so use wide API. */
2249 if (unicode_file_names()) {
2250 PyObject *po;
2251 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2252 WIN32_FIND_DATAW wFileData;
2253 Py_UNICODE *wnamebuf;
2254 /* Overallocate for \\*.*\0 */
2255 len = PyUnicode_GET_SIZE(po);
2256 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2257 if (!wnamebuf) {
2258 PyErr_NoMemory();
2259 return NULL;
2260 }
2261 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2262 if (len > 0) {
2263 Py_UNICODE wch = wnamebuf[len-1];
2264 if (wch != L'/' && wch != L'\\' && wch != L':')
2265 wnamebuf[len++] = L'\\';
2266 wcscpy(wnamebuf + len, L"*.*");
2267 }
2268 if ((d = PyList_New(0)) == NULL) {
2269 free(wnamebuf);
2270 return NULL;
2271 }
Antoine Pitroubd25d592010-08-09 23:47:57 +00002272 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002273 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroubd25d592010-08-09 23:47:57 +00002274 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002275 if (hFindFile == INVALID_HANDLE_VALUE) {
2276 int error = GetLastError();
2277 if (error == ERROR_FILE_NOT_FOUND) {
2278 free(wnamebuf);
2279 return d;
2280 }
2281 Py_DECREF(d);
2282 win32_error_unicode("FindFirstFileW", wnamebuf);
2283 free(wnamebuf);
2284 return NULL;
2285 }
2286 do {
2287 /* Skip over . and .. */
2288 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2289 wcscmp(wFileData.cFileName, L"..") != 0) {
2290 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2291 if (v == NULL) {
2292 Py_DECREF(d);
2293 d = NULL;
2294 break;
2295 }
2296 if (PyList_Append(d, v) != 0) {
2297 Py_DECREF(v);
2298 Py_DECREF(d);
2299 d = NULL;
2300 break;
2301 }
2302 Py_DECREF(v);
2303 }
2304 Py_BEGIN_ALLOW_THREADS
2305 result = FindNextFileW(hFindFile, &wFileData);
2306 Py_END_ALLOW_THREADS
2307 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2308 it got to the end of the directory. */
2309 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2310 Py_DECREF(d);
2311 win32_error_unicode("FindNextFileW", wnamebuf);
2312 FindClose(hFindFile);
2313 free(wnamebuf);
2314 return NULL;
2315 }
2316 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002317
Victor Stinner97b89882010-05-06 00:25:39 +00002318 if (FindClose(hFindFile) == FALSE) {
2319 Py_DECREF(d);
2320 win32_error_unicode("FindClose", wnamebuf);
2321 free(wnamebuf);
2322 return NULL;
2323 }
2324 free(wnamebuf);
2325 return d;
2326 }
2327 /* Drop the argument parsing error as narrow strings
2328 are also valid. */
2329 PyErr_Clear();
2330 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002331
Victor Stinner97b89882010-05-06 00:25:39 +00002332 if (!PyArg_ParseTuple(args, "O&:listdir",
2333 PyUnicode_FSConverter, &opath))
2334 return NULL;
2335 if (PyObject_Size(opath)+1 > MAX_PATH) {
2336 PyErr_SetString(PyExc_ValueError, "path too long");
2337 Py_DECREF(opath);
2338 return NULL;
2339 }
2340 strcpy(namebuf, bytes2str(opath, 0));
2341 len = PyObject_Size(opath);
2342 if (len > 0) {
2343 char ch = namebuf[len-1];
2344 if (ch != SEP && ch != ALTSEP && ch != ':')
2345 namebuf[len++] = '/';
2346 strcpy(namebuf + len, "*.*");
2347 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002348
Victor Stinner97b89882010-05-06 00:25:39 +00002349 if ((d = PyList_New(0)) == NULL)
2350 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002351
Antoine Pitroubd25d592010-08-09 23:47:57 +00002352 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002353 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroubd25d592010-08-09 23:47:57 +00002354 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002355 if (hFindFile == INVALID_HANDLE_VALUE) {
2356 int error = GetLastError();
2357 if (error == ERROR_FILE_NOT_FOUND)
2358 return d;
2359 Py_DECREF(d);
2360 return win32_error("FindFirstFile", namebuf);
2361 }
2362 do {
2363 /* Skip over . and .. */
2364 if (strcmp(FileData.cFileName, ".") != 0 &&
2365 strcmp(FileData.cFileName, "..") != 0) {
2366 v = PyBytes_FromString(FileData.cFileName);
2367 if (v == NULL) {
2368 Py_DECREF(d);
2369 d = NULL;
2370 break;
2371 }
2372 if (PyList_Append(d, v) != 0) {
2373 Py_DECREF(v);
2374 Py_DECREF(d);
2375 d = NULL;
2376 break;
2377 }
2378 Py_DECREF(v);
2379 }
2380 Py_BEGIN_ALLOW_THREADS
2381 result = FindNextFile(hFindFile, &FileData);
2382 Py_END_ALLOW_THREADS
2383 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2384 it got to the end of the directory. */
2385 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2386 Py_DECREF(d);
2387 win32_error("FindNextFile", namebuf);
2388 FindClose(hFindFile);
2389 return NULL;
2390 }
2391 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002392
Victor Stinner97b89882010-05-06 00:25:39 +00002393 if (FindClose(hFindFile) == FALSE) {
2394 Py_DECREF(d);
2395 return win32_error("FindClose", namebuf);
2396 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002397
Victor Stinner97b89882010-05-06 00:25:39 +00002398 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002399
Tim Peters0bb44a42000-09-15 07:44:49 +00002400#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002401
2402#ifndef MAX_PATH
2403#define MAX_PATH CCHMAXPATH
2404#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002405 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002406 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002407 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002408 PyObject *d, *v;
2409 char namebuf[MAX_PATH+5];
2410 HDIR hdir = 1;
2411 ULONG srchcnt = 1;
2412 FILEFINDBUF3 ep;
2413 APIRET rc;
2414
Victor Stinner97b89882010-05-06 00:25:39 +00002415 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002416 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002417 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002418 name = bytes2str(oname);
2419 len = PyObject_Size(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002420 if (len >= MAX_PATH) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002421 release_bytes(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002422 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002423 return NULL;
2424 }
2425 strcpy(namebuf, name);
2426 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002427 if (*pt == ALTSEP)
2428 *pt = SEP;
2429 if (namebuf[len-1] != SEP)
2430 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002431 strcpy(namebuf + len, "*.*");
2432
Neal Norwitz6c913782007-10-14 03:23:09 +00002433 if ((d = PyList_New(0)) == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002434 release_bytes(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002435 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002436 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002437
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002438 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2439 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002440 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002441 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2442 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2443 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002444
2445 if (rc != NO_ERROR) {
2446 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002447 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002448 }
2449
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002450 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002451 do {
2452 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002453 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002454 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002455
2456 strcpy(namebuf, ep.achName);
2457
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002458 /* Leave Case of Name Alone -- In Native Form */
2459 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002460
Christian Heimes72b710a2008-05-26 13:28:38 +00002461 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002462 if (v == NULL) {
2463 Py_DECREF(d);
2464 d = NULL;
2465 break;
2466 }
2467 if (PyList_Append(d, v) != 0) {
2468 Py_DECREF(v);
2469 Py_DECREF(d);
2470 d = NULL;
2471 break;
2472 }
2473 Py_DECREF(v);
2474 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2475 }
2476
Martin v. Löwis011e8422009-05-05 04:43:17 +00002477 release_bytes(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002478 return d;
2479#else
Victor Stinner97b89882010-05-06 00:25:39 +00002480 PyObject *oname;
2481 char *name;
2482 PyObject *d, *v;
2483 DIR *dirp;
2484 struct dirent *ep;
2485 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002486
Victor Stinner97b89882010-05-06 00:25:39 +00002487 errno = 0;
2488 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2489 arg_is_unicode = 0;
2490 PyErr_Clear();
2491 }
2492 if (!PyArg_ParseTuple(args, "O&:listdir", PyUnicode_FSConverter, &oname))
2493 return NULL;
2494 name = bytes2str(oname, 1);
Antoine Pitrou037077f2010-09-04 17:26:01 +00002495 Py_BEGIN_ALLOW_THREADS
2496 dirp = opendir(name);
2497 Py_END_ALLOW_THREADS
2498 if (dirp == NULL) {
Victor Stinner97b89882010-05-06 00:25:39 +00002499 return posix_error_with_allocated_filename(oname);
2500 }
2501 if ((d = PyList_New(0)) == NULL) {
Antoine Pitrou037077f2010-09-04 17:26:01 +00002502 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002503 closedir(dirp);
Antoine Pitrou037077f2010-09-04 17:26:01 +00002504 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002505 release_bytes(oname);
2506 return NULL;
2507 }
2508 for (;;) {
2509 errno = 0;
2510 Py_BEGIN_ALLOW_THREADS
2511 ep = readdir(dirp);
2512 Py_END_ALLOW_THREADS
2513 if (ep == NULL) {
2514 if (errno == 0) {
2515 break;
2516 } else {
Antoine Pitrou037077f2010-09-04 17:26:01 +00002517 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002518 closedir(dirp);
Antoine Pitrou037077f2010-09-04 17:26:01 +00002519 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002520 Py_DECREF(d);
2521 return posix_error_with_allocated_filename(oname);
2522 }
2523 }
2524 if (ep->d_name[0] == '.' &&
2525 (NAMLEN(ep) == 1 ||
2526 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2527 continue;
Victor Stinner203406c2010-05-14 18:07:39 +00002528 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner97b89882010-05-06 00:25:39 +00002529 if (v == NULL) {
Victor Stinner203406c2010-05-14 18:07:39 +00002530 Py_DECREF(d);
2531 d = NULL;
Victor Stinner97b89882010-05-06 00:25:39 +00002532 break;
2533 }
Victor Stinner203406c2010-05-14 18:07:39 +00002534 if (arg_is_unicode) {
2535 PyObject *w;
2536
2537 w = PyUnicode_FromEncodedObject(v,
2538 Py_FileSystemDefaultEncoding,
2539 "surrogateescape");
2540 Py_DECREF(v);
2541 if (w != NULL)
2542 v = w;
2543 else {
2544 /* Encoding failed to decode ASCII bytes.
2545 Raise exception. */
2546 Py_DECREF(d);
2547 d = NULL;
2548 break;
2549 }
2550 }
Victor Stinner97b89882010-05-06 00:25:39 +00002551 if (PyList_Append(d, v) != 0) {
2552 Py_DECREF(v);
Victor Stinner203406c2010-05-14 18:07:39 +00002553 Py_DECREF(d);
2554 d = NULL;
Victor Stinner97b89882010-05-06 00:25:39 +00002555 break;
2556 }
2557 Py_DECREF(v);
2558 }
Antoine Pitrou037077f2010-09-04 17:26:01 +00002559 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002560 closedir(dirp);
Antoine Pitrou037077f2010-09-04 17:26:01 +00002561 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002562 release_bytes(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002563
Victor Stinner97b89882010-05-06 00:25:39 +00002564 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002565
Tim Peters0bb44a42000-09-15 07:44:49 +00002566#endif /* which OS */
2567} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002568
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002569#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002570/* A helper function for abspath on win32 */
2571static PyObject *
2572posix__getfullpathname(PyObject *self, PyObject *args)
2573{
Victor Stinner97b89882010-05-06 00:25:39 +00002574 PyObject *opath;
2575 char *path;
2576 char outbuf[MAX_PATH*2];
2577 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002578#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002579 if (unicode_file_names()) {
2580 PyUnicodeObject *po;
2581 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2582 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2583 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2584 Py_UNICODE *wtemp;
2585 DWORD result;
2586 PyObject *v;
2587 result = GetFullPathNameW(wpath,
2588 sizeof(woutbuf)/sizeof(woutbuf[0]),
2589 woutbuf, &wtemp);
2590 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2591 woutbufp = malloc(result * sizeof(Py_UNICODE));
2592 if (!woutbufp)
2593 return PyErr_NoMemory();
2594 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2595 }
2596 if (result)
2597 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2598 else
2599 v = win32_error_unicode("GetFullPathNameW", wpath);
2600 if (woutbufp != woutbuf)
2601 free(woutbufp);
2602 return v;
2603 }
2604 /* Drop the argument parsing error as narrow strings
2605 are also valid. */
2606 PyErr_Clear();
2607 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002608#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002609 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2610 PyUnicode_FSConverter, &opath))
2611 return NULL;
2612 path = bytes2str(opath, 1);
2613 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2614 outbuf, &temp)) {
2615 win32_error("GetFullPathName", path);
2616 release_bytes(opath);
2617 return NULL;
2618 }
2619 release_bytes(opath);
2620 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2621 return PyUnicode_Decode(outbuf, strlen(outbuf),
2622 Py_FileSystemDefaultEncoding, NULL);
2623 }
2624 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002625} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002626#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002627
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002628PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002629"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002630Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002631
Barry Warsaw53699e91996-12-10 23:23:01 +00002632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002633posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002634{
Victor Stinner97b89882010-05-06 00:25:39 +00002635 int res;
2636 PyObject *opath;
2637 char *path;
2638 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002639
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002640#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002641 if (unicode_file_names()) {
2642 PyUnicodeObject *po;
2643 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2644 Py_BEGIN_ALLOW_THREADS
2645 /* PyUnicode_AS_UNICODE OK without thread lock as
2646 it is a simple dereference. */
2647 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2648 Py_END_ALLOW_THREADS
2649 if (!res)
2650 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2651 Py_INCREF(Py_None);
2652 return Py_None;
2653 }
2654 /* Drop the argument parsing error as narrow strings
2655 are also valid. */
2656 PyErr_Clear();
2657 }
2658 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2659 PyUnicode_FSConverter, &opath, &mode))
2660 return NULL;
2661 path = bytes2str(opath, 1);
2662 Py_BEGIN_ALLOW_THREADS
2663 /* PyUnicode_AS_UNICODE OK without thread lock as
2664 it is a simple dereference. */
2665 res = CreateDirectoryA(path, NULL);
2666 Py_END_ALLOW_THREADS
2667 if (!res) {
2668 win32_error("mkdir", path);
2669 release_bytes(opath);
2670 return NULL;
2671 }
2672 release_bytes(opath);
2673 Py_INCREF(Py_None);
2674 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002675#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002676
Victor Stinner97b89882010-05-06 00:25:39 +00002677 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2678 PyUnicode_FSConverter, &opath, &mode))
2679 return NULL;
2680 path = bytes2str(opath, 1);
2681 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002682#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner97b89882010-05-06 00:25:39 +00002683 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002684#else
Victor Stinner97b89882010-05-06 00:25:39 +00002685 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002686#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002687 Py_END_ALLOW_THREADS
2688 if (res < 0)
2689 return posix_error_with_allocated_filename(opath);
2690 release_bytes(opath);
2691 Py_INCREF(Py_None);
2692 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002693#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002694}
2695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002696
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002697/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2698#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002699#include <sys/resource.h>
2700#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002701
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002702
2703#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002704PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002705"nice(inc) -> new_priority\n\n\
2706Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002707
Barry Warsaw53699e91996-12-10 23:23:01 +00002708static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002709posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002710{
Victor Stinner97b89882010-05-06 00:25:39 +00002711 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002712
Victor Stinner97b89882010-05-06 00:25:39 +00002713 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2714 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002715
Victor Stinner97b89882010-05-06 00:25:39 +00002716 /* There are two flavours of 'nice': one that returns the new
2717 priority (as required by almost all standards out there) and the
2718 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2719 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002720
Victor Stinner97b89882010-05-06 00:25:39 +00002721 If we are of the nice family that returns the new priority, we
2722 need to clear errno before the call, and check if errno is filled
2723 before calling posix_error() on a returnvalue of -1, because the
2724 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002725
Victor Stinner97b89882010-05-06 00:25:39 +00002726 errno = 0;
2727 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002728#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner97b89882010-05-06 00:25:39 +00002729 if (value == 0)
2730 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002731#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002732 if (value == -1 && errno != 0)
2733 /* either nice() or getpriority() returned an error */
2734 return posix_error();
2735 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002736}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002737#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002738
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002739PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002740"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002741Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002742
Barry Warsaw53699e91996-12-10 23:23:01 +00002743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002744posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002745{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002746#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002747 PyObject *o1, *o2;
2748 char *p1, *p2;
2749 BOOL result;
2750 if (unicode_file_names()) {
2751 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2752 goto error;
2753 if (!convert_to_unicode(&o1))
2754 goto error;
2755 if (!convert_to_unicode(&o2)) {
2756 Py_DECREF(o1);
2757 goto error;
2758 }
2759 Py_BEGIN_ALLOW_THREADS
2760 result = MoveFileW(PyUnicode_AsUnicode(o1),
2761 PyUnicode_AsUnicode(o2));
2762 Py_END_ALLOW_THREADS
2763 Py_DECREF(o1);
2764 Py_DECREF(o2);
2765 if (!result)
2766 return win32_error("rename", NULL);
2767 Py_INCREF(Py_None);
2768 return Py_None;
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002769error:
Victor Stinner97b89882010-05-06 00:25:39 +00002770 PyErr_Clear();
2771 }
2772 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2773 return NULL;
2774 Py_BEGIN_ALLOW_THREADS
2775 result = MoveFileA(p1, p2);
2776 Py_END_ALLOW_THREADS
2777 if (!result)
2778 return win32_error("rename", NULL);
2779 Py_INCREF(Py_None);
2780 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002781#else
Victor Stinner97b89882010-05-06 00:25:39 +00002782 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002783#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002784}
2785
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002786
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002787PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002788"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002789Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002790
Barry Warsaw53699e91996-12-10 23:23:01 +00002791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002792posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002793{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002794#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002795 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002796#else
Victor Stinner97b89882010-05-06 00:25:39 +00002797 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002798#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002799}
2800
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002801
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002802PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002803"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002804Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002805
Barry Warsaw53699e91996-12-10 23:23:01 +00002806static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002807posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002808{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002809#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002810 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002811#else
Victor Stinner97b89882010-05-06 00:25:39 +00002812 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002813#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002814}
2815
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002816
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002817#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002818PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002819"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002820Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002821
Barry Warsaw53699e91996-12-10 23:23:01 +00002822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002823posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002824{
Victor Stinner97b89882010-05-06 00:25:39 +00002825 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002826#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002827 wchar_t *command;
2828 if (!PyArg_ParseTuple(args, "u:system", &command))
2829 return NULL;
Victor Stinnera5ab4fc2010-04-16 12:47:52 +00002830
Victor Stinner97b89882010-05-06 00:25:39 +00002831 Py_BEGIN_ALLOW_THREADS
2832 sts = _wsystem(command);
2833 Py_END_ALLOW_THREADS
Victor Stinnera5ab4fc2010-04-16 12:47:52 +00002834#else
Victor Stinner97b89882010-05-06 00:25:39 +00002835 PyObject *command_obj;
2836 char *command;
2837 if (!PyArg_ParseTuple(args, "O&:system",
2838 PyUnicode_FSConverter, &command_obj))
2839 return NULL;
Victor Stinnera5ab4fc2010-04-16 12:47:52 +00002840
Victor Stinner97b89882010-05-06 00:25:39 +00002841 command = bytes2str(command_obj, 1);
2842 Py_BEGIN_ALLOW_THREADS
2843 sts = system(command);
2844 Py_END_ALLOW_THREADS
2845 release_bytes(command_obj);
Victor Stinnera5ab4fc2010-04-16 12:47:52 +00002846#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002847 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002848}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002849#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002850
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002851
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002852PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002853"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002854Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002855
Barry Warsaw53699e91996-12-10 23:23:01 +00002856static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002857posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002858{
Victor Stinner97b89882010-05-06 00:25:39 +00002859 int i;
2860 if (!PyArg_ParseTuple(args, "i:umask", &i))
2861 return NULL;
2862 i = (int)umask(i);
2863 if (i < 0)
2864 return posix_error();
2865 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002866}
2867
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002868
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002869PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002870"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002871Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002872
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002873PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002874"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002875Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002876
Barry Warsaw53699e91996-12-10 23:23:01 +00002877static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002878posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002879{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002880#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002881 return win32_1str(args, "remove", "y:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002882#else
Victor Stinner97b89882010-05-06 00:25:39 +00002883 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002884#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002885}
2886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002887
Guido van Rossumb6775db1994-08-01 11:34:53 +00002888#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002889PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002890"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002891Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002892
Barry Warsaw53699e91996-12-10 23:23:01 +00002893static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002894posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002895{
Victor Stinner97b89882010-05-06 00:25:39 +00002896 struct utsname u;
2897 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002898
Victor Stinner97b89882010-05-06 00:25:39 +00002899 Py_BEGIN_ALLOW_THREADS
2900 res = uname(&u);
2901 Py_END_ALLOW_THREADS
2902 if (res < 0)
2903 return posix_error();
2904 return Py_BuildValue("(sssss)",
2905 u.sysname,
2906 u.nodename,
2907 u.release,
2908 u.version,
2909 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002910}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002911#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002912
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002913static int
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002914extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002915{
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002916 time_t intval;
Victor Stinner97b89882010-05-06 00:25:39 +00002917 if (PyFloat_Check(t)) {
2918 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002919 PyObject *intobj = PyNumber_Long(t);
Victor Stinner97b89882010-05-06 00:25:39 +00002920 if (!intobj)
2921 return -1;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002922#if SIZEOF_TIME_T > SIZEOF_LONG
2923 intval = PyLong_AsUnsignedLongLongMask(intobj);
2924#else
Victor Stinner97b89882010-05-06 00:25:39 +00002925 intval = PyLong_AsLong(intobj);
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002926#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002927 Py_DECREF(intobj);
2928 if (intval == -1 && PyErr_Occurred())
2929 return -1;
2930 *sec = intval;
2931 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2932 if (*usec < 0)
2933 /* If rounding gave us a negative number,
2934 truncate. */
2935 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002936 return 0;
Victor Stinner97b89882010-05-06 00:25:39 +00002937 }
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002938#if SIZEOF_TIME_T > SIZEOF_LONG
2939 intval = PyLong_AsUnsignedLongLongMask(t);
2940#else
Victor Stinner97b89882010-05-06 00:25:39 +00002941 intval = PyLong_AsLong(t);
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002942#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002943 if (intval == -1 && PyErr_Occurred())
2944 return -1;
2945 *sec = intval;
2946 *usec = 0;
2947 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002948}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002949
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002950PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002951"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002952utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002953Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002954second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002955
Barry Warsaw53699e91996-12-10 23:23:01 +00002956static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002957posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002958{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002959#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002960 PyObject *arg;
2961 PyUnicodeObject *obwpath;
2962 wchar_t *wpath = NULL;
2963 PyObject *oapath;
2964 char *apath;
2965 HANDLE hFile;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002966 time_t atimesec, mtimesec;
2967 long ausec, musec;
Victor Stinner97b89882010-05-06 00:25:39 +00002968 FILETIME atime, mtime;
2969 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002970
Victor Stinner97b89882010-05-06 00:25:39 +00002971 if (unicode_file_names()) {
2972 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2973 wpath = PyUnicode_AS_UNICODE(obwpath);
2974 Py_BEGIN_ALLOW_THREADS
2975 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2976 NULL, OPEN_EXISTING,
2977 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2978 Py_END_ALLOW_THREADS
2979 if (hFile == INVALID_HANDLE_VALUE)
2980 return win32_error_unicode("utime", wpath);
2981 } else
2982 /* Drop the argument parsing error as narrow strings
2983 are also valid. */
2984 PyErr_Clear();
2985 }
2986 if (!wpath) {
2987 if (!PyArg_ParseTuple(args, "O&O:utime",
2988 PyUnicode_FSConverter, &oapath, &arg))
2989 return NULL;
2990 apath = bytes2str(oapath, 1);
2991 Py_BEGIN_ALLOW_THREADS
2992 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2993 NULL, OPEN_EXISTING,
2994 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2995 Py_END_ALLOW_THREADS
2996 if (hFile == INVALID_HANDLE_VALUE) {
2997 win32_error("utime", apath);
2998 release_bytes(oapath);
2999 return NULL;
3000 }
3001 release_bytes(oapath);
3002 }
3003
3004 if (arg == Py_None) {
3005 SYSTEMTIME now;
3006 GetSystemTime(&now);
3007 if (!SystemTimeToFileTime(&now, &mtime) ||
3008 !SystemTimeToFileTime(&now, &atime)) {
3009 win32_error("utime", NULL);
3010 goto done;
Stefan Krah67733312010-11-26 17:04:40 +00003011 }
Victor Stinner97b89882010-05-06 00:25:39 +00003012 }
3013 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3014 PyErr_SetString(PyExc_TypeError,
3015 "utime() arg 2 must be a tuple (atime, mtime)");
3016 goto done;
3017 }
3018 else {
3019 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3020 &atimesec, &ausec) == -1)
3021 goto done;
3022 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3023 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3024 &mtimesec, &musec) == -1)
3025 goto done;
3026 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3027 }
3028 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3029 /* Avoid putting the file name into the error here,
3030 as that may confuse the user into believing that
3031 something is wrong with the file, when it also
3032 could be the time stamp that gives a problem. */
3033 win32_error("utime", NULL);
Antoine Pitrouff173852011-01-06 18:29:05 +00003034 goto done;
Victor Stinner97b89882010-05-06 00:25:39 +00003035 }
3036 Py_INCREF(Py_None);
3037 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003038done:
Victor Stinner97b89882010-05-06 00:25:39 +00003039 CloseHandle(hFile);
3040 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003041#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003042
Victor Stinner97b89882010-05-06 00:25:39 +00003043 PyObject *opath;
3044 char *path;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00003045 time_t atime, mtime;
3046 long ausec, musec;
Victor Stinner97b89882010-05-06 00:25:39 +00003047 int res;
3048 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003049
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003050#if defined(HAVE_UTIMES)
Victor Stinner97b89882010-05-06 00:25:39 +00003051 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003052#define ATIME buf[0].tv_sec
3053#define MTIME buf[1].tv_sec
3054#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003055/* XXX should define struct utimbuf instead, above */
Victor Stinner97b89882010-05-06 00:25:39 +00003056 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003057#define ATIME buf.actime
3058#define MTIME buf.modtime
3059#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003060#else /* HAVE_UTIMES */
Victor Stinner97b89882010-05-06 00:25:39 +00003061 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003062#define ATIME buf[0]
3063#define MTIME buf[1]
3064#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003065#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003066
Mark Hammond817c9292003-12-03 01:22:38 +00003067
Victor Stinner97b89882010-05-06 00:25:39 +00003068 if (!PyArg_ParseTuple(args, "O&O:utime",
3069 PyUnicode_FSConverter, &opath, &arg))
3070 return NULL;
3071 path = bytes2str(opath, 1);
3072 if (arg == Py_None) {
3073 /* optional time values not given */
3074 Py_BEGIN_ALLOW_THREADS
3075 res = utime(path, NULL);
3076 Py_END_ALLOW_THREADS
3077 }
3078 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3079 PyErr_SetString(PyExc_TypeError,
3080 "utime() arg 2 must be a tuple (atime, mtime)");
3081 release_bytes(opath);
3082 return NULL;
3083 }
3084 else {
3085 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3086 &atime, &ausec) == -1) {
3087 release_bytes(opath);
3088 return NULL;
3089 }
3090 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3091 &mtime, &musec) == -1) {
3092 release_bytes(opath);
3093 return NULL;
3094 }
3095 ATIME = atime;
3096 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003097#ifdef HAVE_UTIMES
Victor Stinner97b89882010-05-06 00:25:39 +00003098 buf[0].tv_usec = ausec;
3099 buf[1].tv_usec = musec;
3100 Py_BEGIN_ALLOW_THREADS
3101 res = utimes(path, buf);
3102 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003103#else
Victor Stinner97b89882010-05-06 00:25:39 +00003104 Py_BEGIN_ALLOW_THREADS
3105 res = utime(path, UTIME_ARG);
3106 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003107#endif /* HAVE_UTIMES */
Victor Stinner97b89882010-05-06 00:25:39 +00003108 }
3109 if (res < 0) {
3110 return posix_error_with_allocated_filename(opath);
3111 }
3112 release_bytes(opath);
3113 Py_INCREF(Py_None);
3114 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003115#undef UTIME_ARG
3116#undef ATIME
3117#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003118#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003119}
3120
Guido van Rossum85e3b011991-06-03 12:42:10 +00003121
Guido van Rossum3b066191991-06-04 19:40:25 +00003122/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003123
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003124PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003125"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003126Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003127
Barry Warsaw53699e91996-12-10 23:23:01 +00003128static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003129posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003130{
Victor Stinner97b89882010-05-06 00:25:39 +00003131 int sts;
3132 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3133 return NULL;
3134 _exit(sts);
3135 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003136}
3137
Martin v. Löwis114619e2002-10-07 06:44:21 +00003138#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3139static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003140free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003141{
Victor Stinner97b89882010-05-06 00:25:39 +00003142 Py_ssize_t i;
3143 for (i = 0; i < count; i++)
3144 PyMem_Free(array[i]);
3145 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003146}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003147
Antoine Pitrou69f71142009-05-24 21:25:49 +00003148static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003149int fsconvert_strdup(PyObject *o, char**out)
3150{
Victor Stinner97b89882010-05-06 00:25:39 +00003151 PyObject *bytes;
3152 Py_ssize_t size;
3153 if (!PyUnicode_FSConverter(o, &bytes))
3154 return 0;
3155 size = PyObject_Size(bytes);
3156 *out = PyMem_Malloc(size+1);
3157 if (!*out)
3158 return 0;
3159 /* Don't lock bytes, as we hold the GIL */
3160 memcpy(*out, bytes2str(bytes, 0), size+1);
3161 Py_DECREF(bytes);
3162 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003163}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003164#endif
3165
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003166
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003167#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003168PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003169"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003170Execute an executable path with arguments, replacing current process.\n\
3171\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003172 path: path of executable file\n\
3173 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003174
Barry Warsaw53699e91996-12-10 23:23:01 +00003175static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003176posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003177{
Victor Stinner97b89882010-05-06 00:25:39 +00003178 PyObject *opath;
3179 char *path;
3180 PyObject *argv;
3181 char **argvlist;
3182 Py_ssize_t i, argc;
3183 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003184
Victor Stinner97b89882010-05-06 00:25:39 +00003185 /* execv has two arguments: (path, argv), where
3186 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003187
Victor Stinner97b89882010-05-06 00:25:39 +00003188 if (!PyArg_ParseTuple(args, "O&O:execv",
3189 PyUnicode_FSConverter,
3190 &opath, &argv))
3191 return NULL;
3192 path = bytes2str(opath, 1);
3193 if (PyList_Check(argv)) {
3194 argc = PyList_Size(argv);
3195 getitem = PyList_GetItem;
3196 }
3197 else if (PyTuple_Check(argv)) {
3198 argc = PyTuple_Size(argv);
3199 getitem = PyTuple_GetItem;
3200 }
3201 else {
3202 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3203 release_bytes(opath);
3204 return NULL;
3205 }
3206 if (argc < 1) {
3207 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3208 release_bytes(opath);
3209 return NULL;
3210 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003211
Victor Stinner97b89882010-05-06 00:25:39 +00003212 argvlist = PyMem_NEW(char *, argc+1);
3213 if (argvlist == NULL) {
3214 release_bytes(opath);
3215 return PyErr_NoMemory();
3216 }
3217 for (i = 0; i < argc; i++) {
3218 if (!fsconvert_strdup((*getitem)(argv, i),
3219 &argvlist[i])) {
3220 free_string_array(argvlist, i);
3221 PyErr_SetString(PyExc_TypeError,
3222 "execv() arg 2 must contain only strings");
3223 release_bytes(opath);
3224 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003225
Victor Stinner97b89882010-05-06 00:25:39 +00003226 }
3227 }
3228 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003229
Victor Stinner97b89882010-05-06 00:25:39 +00003230 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003231
Victor Stinner97b89882010-05-06 00:25:39 +00003232 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003233
Victor Stinner97b89882010-05-06 00:25:39 +00003234 free_string_array(argvlist, argc);
3235 release_bytes(opath);
3236 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003237}
3238
Victor Stinnera27dcb72010-04-25 22:39:07 +00003239static char**
3240parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3241{
Victor Stinner97b89882010-05-06 00:25:39 +00003242 char **envlist;
3243 Py_ssize_t i, pos, envc;
3244 PyObject *keys=NULL, *vals=NULL;
3245 PyObject *key, *val, *key2, *val2;
3246 char *p, *k, *v;
3247 size_t len;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003248
Victor Stinner97b89882010-05-06 00:25:39 +00003249 i = PyMapping_Size(env);
3250 if (i < 0)
3251 return NULL;
3252 envlist = PyMem_NEW(char *, i + 1);
3253 if (envlist == NULL) {
3254 PyErr_NoMemory();
3255 return NULL;
3256 }
3257 envc = 0;
3258 keys = PyMapping_Keys(env);
3259 vals = PyMapping_Values(env);
3260 if (!keys || !vals)
3261 goto error;
3262 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3263 PyErr_Format(PyExc_TypeError,
3264 "env.keys() or env.values() is not a list");
3265 goto error;
3266 }
Victor Stinnera27dcb72010-04-25 22:39:07 +00003267
Victor Stinner97b89882010-05-06 00:25:39 +00003268 for (pos = 0; pos < i; pos++) {
3269 key = PyList_GetItem(keys, pos);
3270 val = PyList_GetItem(vals, pos);
3271 if (!key || !val)
3272 goto error;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003273
Victor Stinner97b89882010-05-06 00:25:39 +00003274 if (PyUnicode_FSConverter(key, &key2) == 0)
3275 goto error;
3276 if (PyUnicode_FSConverter(val, &val2) == 0) {
3277 Py_DECREF(key2);
3278 goto error;
3279 }
Victor Stinnera27dcb72010-04-25 22:39:07 +00003280
3281#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +00003282 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3283 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinnera27dcb72010-04-25 22:39:07 +00003284#endif
Victor Stinner97b89882010-05-06 00:25:39 +00003285 k = PyBytes_AsString(key2);
3286 v = PyBytes_AsString(val2);
3287 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003288
Victor Stinner97b89882010-05-06 00:25:39 +00003289 p = PyMem_NEW(char, len);
3290 if (p == NULL) {
3291 PyErr_NoMemory();
3292 Py_DECREF(key2);
3293 Py_DECREF(val2);
3294 goto error;
3295 }
3296 PyOS_snprintf(p, len, "%s=%s", k, v);
3297 envlist[envc++] = p;
3298 Py_DECREF(key2);
3299 Py_DECREF(val2);
Victor Stinnera27dcb72010-04-25 22:39:07 +00003300#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +00003301 }
Victor Stinnera27dcb72010-04-25 22:39:07 +00003302#endif
Victor Stinner97b89882010-05-06 00:25:39 +00003303 }
3304 Py_DECREF(vals);
3305 Py_DECREF(keys);
Victor Stinnera27dcb72010-04-25 22:39:07 +00003306
Victor Stinner97b89882010-05-06 00:25:39 +00003307 envlist[envc] = 0;
3308 *envc_ptr = envc;
3309 return envlist;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003310
3311error:
Victor Stinner97b89882010-05-06 00:25:39 +00003312 Py_XDECREF(keys);
3313 Py_XDECREF(vals);
3314 while (--envc >= 0)
3315 PyMem_DEL(envlist[envc]);
3316 PyMem_DEL(envlist);
3317 return NULL;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003318}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003319
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003320PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003321"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003322Execute a path with arguments and environment, replacing current process.\n\
3323\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003324 path: path of executable file\n\
3325 args: tuple or list of arguments\n\
3326 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003327
Barry Warsaw53699e91996-12-10 23:23:01 +00003328static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003329posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003330{
Victor Stinner97b89882010-05-06 00:25:39 +00003331 PyObject *opath;
3332 char *path;
3333 PyObject *argv, *env;
3334 char **argvlist;
3335 char **envlist;
3336 Py_ssize_t i, argc, envc;
3337 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3338 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003339
Victor Stinner97b89882010-05-06 00:25:39 +00003340 /* execve has three arguments: (path, argv, env), where
3341 argv is a list or tuple of strings and env is a dictionary
3342 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003343
Victor Stinner97b89882010-05-06 00:25:39 +00003344 if (!PyArg_ParseTuple(args, "O&OO:execve",
3345 PyUnicode_FSConverter,
3346 &opath, &argv, &env))
3347 return NULL;
3348 path = bytes2str(opath, 1);
3349 if (PyList_Check(argv)) {
3350 argc = PyList_Size(argv);
3351 getitem = PyList_GetItem;
3352 }
3353 else if (PyTuple_Check(argv)) {
3354 argc = PyTuple_Size(argv);
3355 getitem = PyTuple_GetItem;
3356 }
3357 else {
3358 PyErr_SetString(PyExc_TypeError,
3359 "execve() arg 2 must be a tuple or list");
3360 goto fail_0;
3361 }
3362 if (!PyMapping_Check(env)) {
3363 PyErr_SetString(PyExc_TypeError,
3364 "execve() arg 3 must be a mapping object");
3365 goto fail_0;
3366 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003367
Victor Stinner97b89882010-05-06 00:25:39 +00003368 argvlist = PyMem_NEW(char *, argc+1);
3369 if (argvlist == NULL) {
3370 PyErr_NoMemory();
3371 goto fail_0;
3372 }
3373 for (i = 0; i < argc; i++) {
3374 if (!fsconvert_strdup((*getitem)(argv, i),
3375 &argvlist[i]))
3376 {
3377 lastarg = i;
3378 goto fail_1;
3379 }
3380 }
3381 lastarg = argc;
3382 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003383
Victor Stinner97b89882010-05-06 00:25:39 +00003384 envlist = parse_envlist(env, &envc);
3385 if (envlist == NULL)
3386 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003387
Victor Stinner97b89882010-05-06 00:25:39 +00003388 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003389
Victor Stinner97b89882010-05-06 00:25:39 +00003390 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003391
Victor Stinner97b89882010-05-06 00:25:39 +00003392 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003393
Victor Stinner97b89882010-05-06 00:25:39 +00003394 while (--envc >= 0)
3395 PyMem_DEL(envlist[envc]);
3396 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003397 fail_1:
Victor Stinner97b89882010-05-06 00:25:39 +00003398 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003399 fail_0:
Victor Stinner97b89882010-05-06 00:25:39 +00003400 release_bytes(opath);
3401 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003402}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003403#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003404
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003405
Guido van Rossuma1065681999-01-25 23:20:23 +00003406#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003407PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003408"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003409Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003410\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003411 mode: mode of process creation\n\
3412 path: path of executable file\n\
3413 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003414
3415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003416posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003417{
Victor Stinner97b89882010-05-06 00:25:39 +00003418 PyObject *opath;
3419 char *path;
3420 PyObject *argv;
3421 char **argvlist;
3422 int mode, i;
3423 Py_ssize_t argc;
3424 Py_intptr_t spawnval;
3425 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003426
Victor Stinner97b89882010-05-06 00:25:39 +00003427 /* spawnv has three arguments: (mode, path, argv), where
3428 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003429
Victor Stinner97b89882010-05-06 00:25:39 +00003430 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3431 PyUnicode_FSConverter,
3432 &opath, &argv))
3433 return NULL;
3434 path = bytes2str(opath, 1);
3435 if (PyList_Check(argv)) {
3436 argc = PyList_Size(argv);
3437 getitem = PyList_GetItem;
3438 }
3439 else if (PyTuple_Check(argv)) {
3440 argc = PyTuple_Size(argv);
3441 getitem = PyTuple_GetItem;
3442 }
3443 else {
3444 PyErr_SetString(PyExc_TypeError,
3445 "spawnv() arg 2 must be a tuple or list");
3446 release_bytes(opath);
3447 return NULL;
3448 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003449
Victor Stinner97b89882010-05-06 00:25:39 +00003450 argvlist = PyMem_NEW(char *, argc+1);
3451 if (argvlist == NULL) {
3452 release_bytes(opath);
3453 return PyErr_NoMemory();
3454 }
3455 for (i = 0; i < argc; i++) {
3456 if (!fsconvert_strdup((*getitem)(argv, i),
3457 &argvlist[i])) {
3458 free_string_array(argvlist, i);
3459 PyErr_SetString(
3460 PyExc_TypeError,
3461 "spawnv() arg 2 must contain only strings");
3462 release_bytes(opath);
3463 return NULL;
3464 }
3465 }
3466 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003467
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003468#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00003469 Py_BEGIN_ALLOW_THREADS
3470 spawnval = spawnv(mode, path, argvlist);
3471 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003472#else
Victor Stinner97b89882010-05-06 00:25:39 +00003473 if (mode == _OLD_P_OVERLAY)
3474 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003475
Victor Stinner97b89882010-05-06 00:25:39 +00003476 Py_BEGIN_ALLOW_THREADS
3477 spawnval = _spawnv(mode, path, argvlist);
3478 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003479#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003480
Victor Stinner97b89882010-05-06 00:25:39 +00003481 free_string_array(argvlist, argc);
3482 release_bytes(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003483
Victor Stinner97b89882010-05-06 00:25:39 +00003484 if (spawnval == -1)
3485 return posix_error();
3486 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003487#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner97b89882010-05-06 00:25:39 +00003488 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003489#else
Victor Stinner97b89882010-05-06 00:25:39 +00003490 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003491#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003492}
3493
3494
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003495PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003496"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003497Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003498\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003499 mode: mode of process creation\n\
3500 path: path of executable file\n\
3501 args: tuple or list of arguments\n\
3502 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003503
3504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003505posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003506{
Victor Stinner97b89882010-05-06 00:25:39 +00003507 PyObject *opath;
3508 char *path;
3509 PyObject *argv, *env;
3510 char **argvlist;
3511 char **envlist;
3512 PyObject *res = NULL;
Antoine Pitrou835b4452010-08-15 18:32:16 +00003513 int mode;
3514 Py_ssize_t argc, i, envc;
Victor Stinner97b89882010-05-06 00:25:39 +00003515 Py_intptr_t spawnval;
3516 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3517 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003518
Victor Stinner97b89882010-05-06 00:25:39 +00003519 /* spawnve has four arguments: (mode, path, argv, env), where
3520 argv is a list or tuple of strings and env is a dictionary
3521 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003522
Victor Stinner97b89882010-05-06 00:25:39 +00003523 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3524 PyUnicode_FSConverter,
3525 &opath, &argv, &env))
3526 return NULL;
3527 path = bytes2str(opath, 1);
3528 if (PyList_Check(argv)) {
3529 argc = PyList_Size(argv);
3530 getitem = PyList_GetItem;
3531 }
3532 else if (PyTuple_Check(argv)) {
3533 argc = PyTuple_Size(argv);
3534 getitem = PyTuple_GetItem;
3535 }
3536 else {
3537 PyErr_SetString(PyExc_TypeError,
3538 "spawnve() arg 2 must be a tuple or list");
3539 goto fail_0;
3540 }
3541 if (!PyMapping_Check(env)) {
3542 PyErr_SetString(PyExc_TypeError,
3543 "spawnve() arg 3 must be a mapping object");
3544 goto fail_0;
3545 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003546
Victor Stinner97b89882010-05-06 00:25:39 +00003547 argvlist = PyMem_NEW(char *, argc+1);
3548 if (argvlist == NULL) {
3549 PyErr_NoMemory();
3550 goto fail_0;
3551 }
3552 for (i = 0; i < argc; i++) {
3553 if (!fsconvert_strdup((*getitem)(argv, i),
3554 &argvlist[i]))
3555 {
3556 lastarg = i;
3557 goto fail_1;
3558 }
3559 }
3560 lastarg = argc;
3561 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003562
Victor Stinner97b89882010-05-06 00:25:39 +00003563 envlist = parse_envlist(env, &envc);
3564 if (envlist == NULL)
3565 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003566
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003567#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00003568 Py_BEGIN_ALLOW_THREADS
3569 spawnval = spawnve(mode, path, argvlist, envlist);
3570 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003571#else
Victor Stinner97b89882010-05-06 00:25:39 +00003572 if (mode == _OLD_P_OVERLAY)
3573 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003574
Victor Stinner97b89882010-05-06 00:25:39 +00003575 Py_BEGIN_ALLOW_THREADS
3576 spawnval = _spawnve(mode, path, argvlist, envlist);
3577 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003578#endif
Tim Peters25059d32001-12-07 20:35:43 +00003579
Victor Stinner97b89882010-05-06 00:25:39 +00003580 if (spawnval == -1)
3581 (void) posix_error();
3582 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003583#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner97b89882010-05-06 00:25:39 +00003584 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003585#else
Victor Stinner97b89882010-05-06 00:25:39 +00003586 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003587#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003588
Victor Stinner97b89882010-05-06 00:25:39 +00003589 while (--envc >= 0)
3590 PyMem_DEL(envlist[envc]);
3591 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003592 fail_1:
Victor Stinner97b89882010-05-06 00:25:39 +00003593 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003594 fail_0:
Victor Stinner97b89882010-05-06 00:25:39 +00003595 release_bytes(opath);
3596 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003597}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003598
3599/* OS/2 supports spawnvp & spawnvpe natively */
3600#if defined(PYOS_OS2)
3601PyDoc_STRVAR(posix_spawnvp__doc__,
3602"spawnvp(mode, file, args)\n\n\
3603Execute the program 'file' in a new process, using the environment\n\
3604search path to find the file.\n\
3605\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003606 mode: mode of process creation\n\
3607 file: executable file name\n\
3608 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003609
3610static PyObject *
3611posix_spawnvp(PyObject *self, PyObject *args)
3612{
Victor Stinner97b89882010-05-06 00:25:39 +00003613 PyObject *opath;
3614 char *path;
3615 PyObject *argv;
3616 char **argvlist;
3617 int mode, i, argc;
3618 Py_intptr_t spawnval;
3619 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003620
Victor Stinner97b89882010-05-06 00:25:39 +00003621 /* spawnvp has three arguments: (mode, path, argv), where
3622 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003623
Victor Stinner97b89882010-05-06 00:25:39 +00003624 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3625 PyUnicode_FSConverter,
3626 &opath, &argv))
3627 return NULL;
3628 path = bytes2str(opath);
3629 if (PyList_Check(argv)) {
3630 argc = PyList_Size(argv);
3631 getitem = PyList_GetItem;
3632 }
3633 else if (PyTuple_Check(argv)) {
3634 argc = PyTuple_Size(argv);
3635 getitem = PyTuple_GetItem;
3636 }
3637 else {
3638 PyErr_SetString(PyExc_TypeError,
3639 "spawnvp() arg 2 must be a tuple or list");
3640 release_bytes(opath);
3641 return NULL;
3642 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003643
Victor Stinner97b89882010-05-06 00:25:39 +00003644 argvlist = PyMem_NEW(char *, argc+1);
3645 if (argvlist == NULL) {
3646 release_bytes(opath);
3647 return PyErr_NoMemory();
3648 }
3649 for (i = 0; i < argc; i++) {
3650 if (!fsconvert_strdup((*getitem)(argv, i),
3651 &argvlist[i])) {
3652 free_string_array(argvlist, i);
3653 PyErr_SetString(
3654 PyExc_TypeError,
3655 "spawnvp() arg 2 must contain only strings");
3656 release_bytes(opath);
3657 return NULL;
3658 }
3659 }
3660 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003661
Victor Stinner97b89882010-05-06 00:25:39 +00003662 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003663#if defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00003664 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003665#else
Victor Stinner97b89882010-05-06 00:25:39 +00003666 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003667#endif
Victor Stinner97b89882010-05-06 00:25:39 +00003668 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003669
Victor Stinner97b89882010-05-06 00:25:39 +00003670 free_string_array(argvlist, argc);
3671 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003672
Victor Stinner97b89882010-05-06 00:25:39 +00003673 if (spawnval == -1)
3674 return posix_error();
3675 else
3676 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003677}
3678
3679
3680PyDoc_STRVAR(posix_spawnvpe__doc__,
3681"spawnvpe(mode, file, args, env)\n\n\
3682Execute the program 'file' in a new process, using the environment\n\
3683search path to find the file.\n\
3684\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003685 mode: mode of process creation\n\
3686 file: executable file name\n\
3687 args: tuple or list of arguments\n\
3688 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003689
3690static PyObject *
3691posix_spawnvpe(PyObject *self, PyObject *args)
3692{
Victor Stinner97b89882010-05-06 00:25:39 +00003693 PyObject *opath
3694 char *path;
3695 PyObject *argv, *env;
3696 char **argvlist;
3697 char **envlist;
3698 PyObject *res=NULL;
Antoine Pitrou835b4452010-08-15 18:32:16 +00003699 int mode;
3700 Py_ssize_t argc, i, envc;
Victor Stinner97b89882010-05-06 00:25:39 +00003701 Py_intptr_t spawnval;
3702 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3703 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003704
Victor Stinner97b89882010-05-06 00:25:39 +00003705 /* spawnvpe has four arguments: (mode, path, argv, env), where
3706 argv is a list or tuple of strings and env is a dictionary
3707 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003708
Victor Stinner97b89882010-05-06 00:25:39 +00003709 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3710 PyUnicode_FSConverter,
3711 &opath, &argv, &env))
3712 return NULL;
3713 path = bytes2str(opath);
3714 if (PyList_Check(argv)) {
3715 argc = PyList_Size(argv);
3716 getitem = PyList_GetItem;
3717 }
3718 else if (PyTuple_Check(argv)) {
3719 argc = PyTuple_Size(argv);
3720 getitem = PyTuple_GetItem;
3721 }
3722 else {
3723 PyErr_SetString(PyExc_TypeError,
3724 "spawnvpe() arg 2 must be a tuple or list");
3725 goto fail_0;
3726 }
3727 if (!PyMapping_Check(env)) {
3728 PyErr_SetString(PyExc_TypeError,
3729 "spawnvpe() arg 3 must be a mapping object");
3730 goto fail_0;
3731 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003732
Victor Stinner97b89882010-05-06 00:25:39 +00003733 argvlist = PyMem_NEW(char *, argc+1);
3734 if (argvlist == NULL) {
3735 PyErr_NoMemory();
3736 goto fail_0;
3737 }
3738 for (i = 0; i < argc; i++) {
3739 if (!fsconvert_strdup((*getitem)(argv, i),
3740 &argvlist[i]))
3741 {
3742 lastarg = i;
3743 goto fail_1;
3744 }
3745 }
3746 lastarg = argc;
3747 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003748
Victor Stinner97b89882010-05-06 00:25:39 +00003749 envlist = parse_envlist(env, &envc);
3750 if (envlist == NULL)
3751 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003752
Victor Stinner97b89882010-05-06 00:25:39 +00003753 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003754#if defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00003755 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003756#else
Victor Stinner97b89882010-05-06 00:25:39 +00003757 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003758#endif
Victor Stinner97b89882010-05-06 00:25:39 +00003759 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003760
Victor Stinner97b89882010-05-06 00:25:39 +00003761 if (spawnval == -1)
3762 (void) posix_error();
3763 else
3764 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003765
Victor Stinner97b89882010-05-06 00:25:39 +00003766 while (--envc >= 0)
3767 PyMem_DEL(envlist[envc]);
3768 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003769 fail_1:
Victor Stinner97b89882010-05-06 00:25:39 +00003770 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003771 fail_0:
Victor Stinner97b89882010-05-06 00:25:39 +00003772 release_bytes(opath);
3773 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003774}
3775#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003776#endif /* HAVE_SPAWNV */
3777
3778
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003779#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003780PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003781"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003782Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3783\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003784Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003785
3786static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003787posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003788{
Victor Stinner97b89882010-05-06 00:25:39 +00003789 pid_t pid;
3790 int result;
3791 _PyImport_AcquireLock();
3792 pid = fork1();
3793 result = _PyImport_ReleaseLock();
3794 if (pid == -1)
3795 return posix_error();
3796 if (pid == 0)
3797 PyOS_AfterFork();
3798 if (result < 0) {
3799 /* Don't clobber the OSError if the fork failed. */
3800 PyErr_SetString(PyExc_RuntimeError,
3801 "not holding the import lock");
3802 return NULL;
3803 }
3804 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003805}
3806#endif
3807
3808
Guido van Rossumad0ee831995-03-01 10:34:45 +00003809#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003810PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003811"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003812Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003813Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003814
Barry Warsaw53699e91996-12-10 23:23:01 +00003815static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003816posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003817{
Victor Stinner97b89882010-05-06 00:25:39 +00003818 pid_t pid;
3819 int result;
3820 _PyImport_AcquireLock();
3821 pid = fork();
3822 result = _PyImport_ReleaseLock();
3823 if (pid == -1)
3824 return posix_error();
3825 if (pid == 0)
3826 PyOS_AfterFork();
3827 if (result < 0) {
3828 /* Don't clobber the OSError if the fork failed. */
3829 PyErr_SetString(PyExc_RuntimeError,
3830 "not holding the import lock");
3831 return NULL;
3832 }
3833 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003834}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003835#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003836
Neal Norwitzb59798b2003-03-21 01:43:31 +00003837/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003838/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3839#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003840#define DEV_PTY_FILE "/dev/ptc"
3841#define HAVE_DEV_PTMX
3842#else
3843#define DEV_PTY_FILE "/dev/ptmx"
3844#endif
3845
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003846#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003847#ifdef HAVE_PTY_H
3848#include <pty.h>
3849#else
3850#ifdef HAVE_LIBUTIL_H
3851#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003852#endif /* HAVE_LIBUTIL_H */
3853#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003854#ifdef HAVE_STROPTS_H
3855#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003856#endif
3857#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003858
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003859#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003860PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003861"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003862Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003863
3864static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003865posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003866{
Victor Stinner97b89882010-05-06 00:25:39 +00003867 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003868#ifndef HAVE_OPENPTY
Victor Stinner97b89882010-05-06 00:25:39 +00003869 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003870#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003871#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner97b89882010-05-06 00:25:39 +00003872 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003873#ifdef sun
Victor Stinner97b89882010-05-06 00:25:39 +00003874 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003875#endif
3876#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003877
Thomas Wouters70c21a12000-07-14 14:28:33 +00003878#ifdef HAVE_OPENPTY
Victor Stinner97b89882010-05-06 00:25:39 +00003879 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3880 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003881#elif defined(HAVE__GETPTY)
Victor Stinner97b89882010-05-06 00:25:39 +00003882 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3883 if (slave_name == NULL)
3884 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003885
Victor Stinner97b89882010-05-06 00:25:39 +00003886 slave_fd = open(slave_name, O_RDWR);
3887 if (slave_fd < 0)
3888 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003889#else
Victor Stinner97b89882010-05-06 00:25:39 +00003890 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3891 if (master_fd < 0)
3892 return posix_error();
3893 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3894 /* change permission of slave */
3895 if (grantpt(master_fd) < 0) {
3896 PyOS_setsig(SIGCHLD, sig_saved);
3897 return posix_error();
3898 }
3899 /* unlock slave */
3900 if (unlockpt(master_fd) < 0) {
3901 PyOS_setsig(SIGCHLD, sig_saved);
3902 return posix_error();
3903 }
3904 PyOS_setsig(SIGCHLD, sig_saved);
3905 slave_name = ptsname(master_fd); /* get name of slave */
3906 if (slave_name == NULL)
3907 return posix_error();
3908 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3909 if (slave_fd < 0)
3910 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003911#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner97b89882010-05-06 00:25:39 +00003912 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3913 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003914#ifndef __hpux
Victor Stinner97b89882010-05-06 00:25:39 +00003915 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003916#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003917#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003918#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003919
Victor Stinner97b89882010-05-06 00:25:39 +00003920 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003921
Fred Drake8cef4cf2000-06-28 16:40:38 +00003922}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003923#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003924
3925#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003926PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003927"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003928Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3929Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003930To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003931
3932static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003933posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003934{
Victor Stinner97b89882010-05-06 00:25:39 +00003935 int master_fd = -1, result;
3936 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003937
Victor Stinner97b89882010-05-06 00:25:39 +00003938 _PyImport_AcquireLock();
3939 pid = forkpty(&master_fd, NULL, NULL, NULL);
3940 result = _PyImport_ReleaseLock();
3941 if (pid == -1)
3942 return posix_error();
3943 if (pid == 0)
3944 PyOS_AfterFork();
3945 if (result < 0) {
3946 /* Don't clobber the OSError if the fork failed. */
3947 PyErr_SetString(PyExc_RuntimeError,
3948 "not holding the import lock");
3949 return NULL;
3950 }
3951 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003952}
3953#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003954
Guido van Rossumad0ee831995-03-01 10:34:45 +00003955#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003956PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003957"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003958Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003959
Barry Warsaw53699e91996-12-10 23:23:01 +00003960static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003961posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003962{
Victor Stinner97b89882010-05-06 00:25:39 +00003963 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003964}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003965#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003967
Guido van Rossumad0ee831995-03-01 10:34:45 +00003968#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003969PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003970"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003971Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003972
Barry Warsaw53699e91996-12-10 23:23:01 +00003973static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003974posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003975{
Victor Stinner97b89882010-05-06 00:25:39 +00003976 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003977}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003978#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003979
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003980
Guido van Rossumad0ee831995-03-01 10:34:45 +00003981#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003982PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003983"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003984Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003985
Barry Warsaw53699e91996-12-10 23:23:01 +00003986static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003987posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003988{
Victor Stinner97b89882010-05-06 00:25:39 +00003989 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003990}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003991#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003993
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003994PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003995"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003996Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003997
Barry Warsaw53699e91996-12-10 23:23:01 +00003998static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003999posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004000{
Victor Stinner97b89882010-05-06 00:25:39 +00004001 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004002}
4003
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004004
Fred Drakec9680921999-12-13 16:37:25 +00004005#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004006PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004007"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004008Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004009
4010static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004011posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004012{
4013 PyObject *result = NULL;
4014
Fred Drakec9680921999-12-13 16:37:25 +00004015#ifdef NGROUPS_MAX
4016#define MAX_GROUPS NGROUPS_MAX
4017#else
Victor Stinner97b89882010-05-06 00:25:39 +00004018 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004019#define MAX_GROUPS 64
4020#endif
Victor Stinner97b89882010-05-06 00:25:39 +00004021 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren47076f72010-07-23 15:46:03 +00004022
4023 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4024 * This is a helper variable to store the intermediate result when
4025 * that happens.
4026 *
4027 * To keep the code readable the OSX behaviour is unconditional,
4028 * according to the POSIX spec this should be safe on all unix-y
4029 * systems.
4030 */
4031 gid_t* alt_grouplist = grouplist;
Victor Stinner97b89882010-05-06 00:25:39 +00004032 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004033
Victor Stinner97b89882010-05-06 00:25:39 +00004034 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren47076f72010-07-23 15:46:03 +00004035 if (n < 0) {
4036 if (errno == EINVAL) {
4037 n = getgroups(0, NULL);
4038 if (n == -1) {
4039 return posix_error();
4040 }
4041 if (n == 0) {
4042 /* Avoid malloc(0) */
4043 alt_grouplist = grouplist;
4044 } else {
4045 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4046 if (alt_grouplist == NULL) {
4047 errno = EINVAL;
4048 return posix_error();
4049 }
4050 n = getgroups(n, alt_grouplist);
4051 if (n == -1) {
4052 PyMem_Free(alt_grouplist);
4053 return posix_error();
4054 }
4055 }
4056 } else {
4057 return posix_error();
4058 }
4059 }
4060 result = PyList_New(n);
4061 if (result != NULL) {
Victor Stinner97b89882010-05-06 00:25:39 +00004062 int i;
4063 for (i = 0; i < n; ++i) {
Ronald Oussoren47076f72010-07-23 15:46:03 +00004064 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner97b89882010-05-06 00:25:39 +00004065 if (o == NULL) {
Stefan Krah67733312010-11-26 17:04:40 +00004066 Py_DECREF(result);
4067 result = NULL;
4068 break;
Fred Drakec9680921999-12-13 16:37:25 +00004069 }
Victor Stinner97b89882010-05-06 00:25:39 +00004070 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004071 }
Ronald Oussoren47076f72010-07-23 15:46:03 +00004072 }
4073
4074 if (alt_grouplist != grouplist) {
4075 PyMem_Free(alt_grouplist);
Victor Stinner97b89882010-05-06 00:25:39 +00004076 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004077
Fred Drakec9680921999-12-13 16:37:25 +00004078 return result;
4079}
4080#endif
4081
Martin v. Löwis606edc12002-06-13 21:09:11 +00004082#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004083PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004084"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004085Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004086
4087static PyObject *
4088posix_getpgid(PyObject *self, PyObject *args)
4089{
Victor Stinner97b89882010-05-06 00:25:39 +00004090 pid_t pid, pgid;
4091 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
4092 return NULL;
4093 pgid = getpgid(pid);
4094 if (pgid < 0)
4095 return posix_error();
4096 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004097}
4098#endif /* HAVE_GETPGID */
4099
4100
Guido van Rossumb6775db1994-08-01 11:34:53 +00004101#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004102PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004103"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004104Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004105
Barry Warsaw53699e91996-12-10 23:23:01 +00004106static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004107posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004108{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004109#ifdef GETPGRP_HAVE_ARG
Victor Stinner97b89882010-05-06 00:25:39 +00004110 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004111#else /* GETPGRP_HAVE_ARG */
Victor Stinner97b89882010-05-06 00:25:39 +00004112 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004113#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004114}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004115#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004116
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004117
Guido van Rossumb6775db1994-08-01 11:34:53 +00004118#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004119PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004120"setpgrp()\n\n\
Senthil Kumaran28fdadb2010-06-17 16:51:08 +00004121Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004122
Barry Warsaw53699e91996-12-10 23:23:01 +00004123static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004124posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004125{
Guido van Rossum64933891994-10-20 21:56:42 +00004126#ifdef SETPGRP_HAVE_ARG
Victor Stinner97b89882010-05-06 00:25:39 +00004127 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004128#else /* SETPGRP_HAVE_ARG */
Victor Stinner97b89882010-05-06 00:25:39 +00004129 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004130#endif /* SETPGRP_HAVE_ARG */
Victor Stinner97b89882010-05-06 00:25:39 +00004131 return posix_error();
4132 Py_INCREF(Py_None);
4133 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004134}
4135
Guido van Rossumb6775db1994-08-01 11:34:53 +00004136#endif /* HAVE_SETPGRP */
4137
Guido van Rossumad0ee831995-03-01 10:34:45 +00004138#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004139PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004140"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004141Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004142
Barry Warsaw53699e91996-12-10 23:23:01 +00004143static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004144posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004145{
Victor Stinner97b89882010-05-06 00:25:39 +00004146 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004147}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004148#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004149
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004150
Fred Drake12c6e2d1999-12-14 21:25:03 +00004151#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004152PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004153"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004154Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004155
4156static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004157posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004158{
Victor Stinner97b89882010-05-06 00:25:39 +00004159 PyObject *result = NULL;
4160 char *name;
4161 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004162
Victor Stinner97b89882010-05-06 00:25:39 +00004163 errno = 0;
4164 name = getlogin();
4165 if (name == NULL) {
4166 if (errno)
Victor Stinner85675992010-08-15 09:35:13 +00004167 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004168 else
Victor Stinner85675992010-08-15 09:35:13 +00004169 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner97b89882010-05-06 00:25:39 +00004170 }
4171 else
Victor Stinner85675992010-08-15 09:35:13 +00004172 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner97b89882010-05-06 00:25:39 +00004173 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004174
Fred Drake12c6e2d1999-12-14 21:25:03 +00004175 return result;
4176}
4177#endif
4178
Guido van Rossumad0ee831995-03-01 10:34:45 +00004179#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004180PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004181"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004182Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004183
Barry Warsaw53699e91996-12-10 23:23:01 +00004184static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004185posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004186{
Victor Stinner97b89882010-05-06 00:25:39 +00004187 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004188}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004189#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004190
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004191
Guido van Rossumad0ee831995-03-01 10:34:45 +00004192#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004193PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004194"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004195Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004196
Barry Warsaw53699e91996-12-10 23:23:01 +00004197static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004198posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004199{
Victor Stinner97b89882010-05-06 00:25:39 +00004200 pid_t pid;
4201 int sig;
4202 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4203 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004204#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004205 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4206 APIRET rc;
4207 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004208 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004209
4210 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4211 APIRET rc;
4212 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004213 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004214
4215 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004216 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004217#else
Victor Stinner97b89882010-05-06 00:25:39 +00004218 if (kill(pid, sig) == -1)
4219 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004220#endif
Victor Stinner97b89882010-05-06 00:25:39 +00004221 Py_INCREF(Py_None);
4222 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004223}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004224#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004225
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004226#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004227PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004228"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004229Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004230
4231static PyObject *
4232posix_killpg(PyObject *self, PyObject *args)
4233{
Victor Stinner97b89882010-05-06 00:25:39 +00004234 int sig;
4235 pid_t pgid;
4236 /* XXX some man pages make the `pgid` parameter an int, others
4237 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4238 take the same type. Moreover, pid_t is always at least as wide as
4239 int (else compilation of this module fails), which is safe. */
4240 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4241 return NULL;
4242 if (killpg(pgid, sig) == -1)
4243 return posix_error();
4244 Py_INCREF(Py_None);
4245 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004246}
4247#endif
4248
Guido van Rossumc0125471996-06-28 18:55:32 +00004249#ifdef HAVE_PLOCK
4250
4251#ifdef HAVE_SYS_LOCK_H
4252#include <sys/lock.h>
4253#endif
4254
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004255PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004256"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004257Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004258
Barry Warsaw53699e91996-12-10 23:23:01 +00004259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004260posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004261{
Victor Stinner97b89882010-05-06 00:25:39 +00004262 int op;
4263 if (!PyArg_ParseTuple(args, "i:plock", &op))
4264 return NULL;
4265 if (plock(op) == -1)
4266 return posix_error();
4267 Py_INCREF(Py_None);
4268 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004269}
4270#endif
4271
Guido van Rossumb6775db1994-08-01 11:34:53 +00004272#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004273PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004274"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004275Set the current process's user id.");
4276
Barry Warsaw53699e91996-12-10 23:23:01 +00004277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004278posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004279{
Victor Stinner97b89882010-05-06 00:25:39 +00004280 long uid_arg;
4281 uid_t uid;
4282 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4283 return NULL;
4284 uid = uid_arg;
4285 if (uid != uid_arg) {
4286 PyErr_SetString(PyExc_OverflowError, "user id too big");
4287 return NULL;
4288 }
4289 if (setuid(uid) < 0)
4290 return posix_error();
4291 Py_INCREF(Py_None);
4292 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004293}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004294#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004295
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004296
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004297#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004298PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004299"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004300Set the current process's effective user id.");
4301
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004302static PyObject *
4303posix_seteuid (PyObject *self, PyObject *args)
4304{
Victor Stinner97b89882010-05-06 00:25:39 +00004305 long euid_arg;
4306 uid_t euid;
4307 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4308 return NULL;
4309 euid = euid_arg;
4310 if (euid != euid_arg) {
4311 PyErr_SetString(PyExc_OverflowError, "user id too big");
4312 return NULL;
4313 }
4314 if (seteuid(euid) < 0) {
4315 return posix_error();
4316 } else {
4317 Py_INCREF(Py_None);
4318 return Py_None;
4319 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004320}
4321#endif /* HAVE_SETEUID */
4322
4323#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004324PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004325"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004326Set the current process's effective group id.");
4327
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004328static PyObject *
4329posix_setegid (PyObject *self, PyObject *args)
4330{
Victor Stinner97b89882010-05-06 00:25:39 +00004331 long egid_arg;
4332 gid_t egid;
4333 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4334 return NULL;
4335 egid = egid_arg;
4336 if (egid != egid_arg) {
4337 PyErr_SetString(PyExc_OverflowError, "group id too big");
4338 return NULL;
4339 }
4340 if (setegid(egid) < 0) {
4341 return posix_error();
4342 } else {
4343 Py_INCREF(Py_None);
4344 return Py_None;
4345 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004346}
4347#endif /* HAVE_SETEGID */
4348
4349#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004350PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004351"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004352Set the current process's real and effective user ids.");
4353
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004354static PyObject *
4355posix_setreuid (PyObject *self, PyObject *args)
4356{
Victor Stinner97b89882010-05-06 00:25:39 +00004357 long ruid_arg, euid_arg;
4358 uid_t ruid, euid;
4359 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4360 return NULL;
4361 if (ruid_arg == -1)
4362 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4363 else
4364 ruid = ruid_arg; /* otherwise, assign from our long */
4365 if (euid_arg == -1)
4366 euid = (uid_t)-1;
4367 else
4368 euid = euid_arg;
4369 if ((euid_arg != -1 && euid != euid_arg) ||
4370 (ruid_arg != -1 && ruid != ruid_arg)) {
4371 PyErr_SetString(PyExc_OverflowError, "user id too big");
4372 return NULL;
4373 }
4374 if (setreuid(ruid, euid) < 0) {
4375 return posix_error();
4376 } else {
4377 Py_INCREF(Py_None);
4378 return Py_None;
4379 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004380}
4381#endif /* HAVE_SETREUID */
4382
4383#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004384PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004385"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004386Set the current process's real and effective group ids.");
4387
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004388static PyObject *
4389posix_setregid (PyObject *self, PyObject *args)
4390{
Victor Stinner97b89882010-05-06 00:25:39 +00004391 long rgid_arg, egid_arg;
4392 gid_t rgid, egid;
4393 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4394 return NULL;
4395 if (rgid_arg == -1)
4396 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4397 else
4398 rgid = rgid_arg; /* otherwise, assign from our long */
4399 if (egid_arg == -1)
4400 egid = (gid_t)-1;
4401 else
4402 egid = egid_arg;
4403 if ((egid_arg != -1 && egid != egid_arg) ||
4404 (rgid_arg != -1 && rgid != rgid_arg)) {
4405 PyErr_SetString(PyExc_OverflowError, "group id too big");
4406 return NULL;
4407 }
4408 if (setregid(rgid, egid) < 0) {
4409 return posix_error();
4410 } else {
4411 Py_INCREF(Py_None);
4412 return Py_None;
4413 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004414}
4415#endif /* HAVE_SETREGID */
4416
Guido van Rossumb6775db1994-08-01 11:34:53 +00004417#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004418PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004419"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004420Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004421
Barry Warsaw53699e91996-12-10 23:23:01 +00004422static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004423posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004424{
Victor Stinner97b89882010-05-06 00:25:39 +00004425 long gid_arg;
4426 gid_t gid;
4427 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4428 return NULL;
4429 gid = gid_arg;
4430 if (gid != gid_arg) {
4431 PyErr_SetString(PyExc_OverflowError, "group id too big");
4432 return NULL;
4433 }
4434 if (setgid(gid) < 0)
4435 return posix_error();
4436 Py_INCREF(Py_None);
4437 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004438}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004439#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004440
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004441#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004442PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004443"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004444Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004445
4446static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004447posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004448{
Victor Stinner97b89882010-05-06 00:25:39 +00004449 int i, len;
4450 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004451
Victor Stinner97b89882010-05-06 00:25:39 +00004452 if (!PySequence_Check(groups)) {
4453 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4454 return NULL;
4455 }
4456 len = PySequence_Size(groups);
4457 if (len > MAX_GROUPS) {
4458 PyErr_SetString(PyExc_ValueError, "too many groups");
4459 return NULL;
4460 }
4461 for(i = 0; i < len; i++) {
4462 PyObject *elem;
4463 elem = PySequence_GetItem(groups, i);
4464 if (!elem)
4465 return NULL;
4466 if (!PyLong_Check(elem)) {
4467 PyErr_SetString(PyExc_TypeError,
4468 "groups must be integers");
4469 Py_DECREF(elem);
4470 return NULL;
4471 } else {
4472 unsigned long x = PyLong_AsUnsignedLong(elem);
4473 if (PyErr_Occurred()) {
4474 PyErr_SetString(PyExc_TypeError,
4475 "group id too big");
4476 Py_DECREF(elem);
4477 return NULL;
4478 }
4479 grouplist[i] = x;
4480 /* read back the value to see if it fitted in gid_t */
4481 if (grouplist[i] != x) {
4482 PyErr_SetString(PyExc_TypeError,
4483 "group id too big");
4484 Py_DECREF(elem);
4485 return NULL;
4486 }
4487 }
4488 Py_DECREF(elem);
4489 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004490
Victor Stinner97b89882010-05-06 00:25:39 +00004491 if (setgroups(len, grouplist) < 0)
4492 return posix_error();
4493 Py_INCREF(Py_None);
4494 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004495}
4496#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004497
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004498#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4499static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004500wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004501{
Victor Stinner97b89882010-05-06 00:25:39 +00004502 PyObject *result;
4503 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004504
Victor Stinner97b89882010-05-06 00:25:39 +00004505 if (pid == -1)
4506 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004507
Victor Stinner97b89882010-05-06 00:25:39 +00004508 if (struct_rusage == NULL) {
4509 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4510 if (m == NULL)
4511 return NULL;
4512 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4513 Py_DECREF(m);
4514 if (struct_rusage == NULL)
4515 return NULL;
4516 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004517
Victor Stinner97b89882010-05-06 00:25:39 +00004518 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4519 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4520 if (!result)
4521 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004522
4523#ifndef doubletime
4524#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4525#endif
4526
Victor Stinner97b89882010-05-06 00:25:39 +00004527 PyStructSequence_SET_ITEM(result, 0,
4528 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4529 PyStructSequence_SET_ITEM(result, 1,
4530 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004531#define SET_INT(result, index, value)\
Victor Stinner97b89882010-05-06 00:25:39 +00004532 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4533 SET_INT(result, 2, ru->ru_maxrss);
4534 SET_INT(result, 3, ru->ru_ixrss);
4535 SET_INT(result, 4, ru->ru_idrss);
4536 SET_INT(result, 5, ru->ru_isrss);
4537 SET_INT(result, 6, ru->ru_minflt);
4538 SET_INT(result, 7, ru->ru_majflt);
4539 SET_INT(result, 8, ru->ru_nswap);
4540 SET_INT(result, 9, ru->ru_inblock);
4541 SET_INT(result, 10, ru->ru_oublock);
4542 SET_INT(result, 11, ru->ru_msgsnd);
4543 SET_INT(result, 12, ru->ru_msgrcv);
4544 SET_INT(result, 13, ru->ru_nsignals);
4545 SET_INT(result, 14, ru->ru_nvcsw);
4546 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004547#undef SET_INT
4548
Victor Stinner97b89882010-05-06 00:25:39 +00004549 if (PyErr_Occurred()) {
4550 Py_DECREF(result);
4551 return NULL;
4552 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004553
Victor Stinner97b89882010-05-06 00:25:39 +00004554 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004555}
4556#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4557
4558#ifdef HAVE_WAIT3
4559PyDoc_STRVAR(posix_wait3__doc__,
4560"wait3(options) -> (pid, status, rusage)\n\n\
4561Wait for completion of a child process.");
4562
4563static PyObject *
4564posix_wait3(PyObject *self, PyObject *args)
4565{
Victor Stinner97b89882010-05-06 00:25:39 +00004566 pid_t pid;
4567 int options;
4568 struct rusage ru;
4569 WAIT_TYPE status;
4570 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004571
Victor Stinner97b89882010-05-06 00:25:39 +00004572 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4573 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004574
Victor Stinner97b89882010-05-06 00:25:39 +00004575 Py_BEGIN_ALLOW_THREADS
4576 pid = wait3(&status, options, &ru);
4577 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004578
Victor Stinner97b89882010-05-06 00:25:39 +00004579 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004580}
4581#endif /* HAVE_WAIT3 */
4582
4583#ifdef HAVE_WAIT4
4584PyDoc_STRVAR(posix_wait4__doc__,
4585"wait4(pid, options) -> (pid, status, rusage)\n\n\
4586Wait for completion of a given child process.");
4587
4588static PyObject *
4589posix_wait4(PyObject *self, PyObject *args)
4590{
Victor Stinner97b89882010-05-06 00:25:39 +00004591 pid_t pid;
4592 int options;
4593 struct rusage ru;
4594 WAIT_TYPE status;
4595 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004596
Victor Stinner97b89882010-05-06 00:25:39 +00004597 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
4598 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004599
Victor Stinner97b89882010-05-06 00:25:39 +00004600 Py_BEGIN_ALLOW_THREADS
4601 pid = wait4(pid, &status, options, &ru);
4602 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004603
Victor Stinner97b89882010-05-06 00:25:39 +00004604 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004605}
4606#endif /* HAVE_WAIT4 */
4607
Guido van Rossumb6775db1994-08-01 11:34:53 +00004608#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004609PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004610"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004611Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004612
Barry Warsaw53699e91996-12-10 23:23:01 +00004613static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004614posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004615{
Victor Stinner97b89882010-05-06 00:25:39 +00004616 pid_t pid;
4617 int options;
4618 WAIT_TYPE status;
4619 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004620
Victor Stinner97b89882010-05-06 00:25:39 +00004621 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
4622 return NULL;
4623 Py_BEGIN_ALLOW_THREADS
4624 pid = waitpid(pid, &status, options);
4625 Py_END_ALLOW_THREADS
4626 if (pid == -1)
4627 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004628
Victor Stinner97b89882010-05-06 00:25:39 +00004629 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004630}
4631
Tim Petersab034fa2002-02-01 11:27:43 +00004632#elif defined(HAVE_CWAIT)
4633
4634/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004635PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004636"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004637"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004638
4639static PyObject *
4640posix_waitpid(PyObject *self, PyObject *args)
4641{
Victor Stinner97b89882010-05-06 00:25:39 +00004642 Py_intptr_t pid;
4643 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004644
Victor Stinner97b89882010-05-06 00:25:39 +00004645 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
4646 return NULL;
4647 Py_BEGIN_ALLOW_THREADS
4648 pid = _cwait(&status, pid, options);
4649 Py_END_ALLOW_THREADS
4650 if (pid == -1)
4651 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004652
Victor Stinner97b89882010-05-06 00:25:39 +00004653 /* shift the status left a byte so this is more like the POSIX waitpid */
4654 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004655}
4656#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004657
Guido van Rossumad0ee831995-03-01 10:34:45 +00004658#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004659PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004660"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004661Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004662
Barry Warsaw53699e91996-12-10 23:23:01 +00004663static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004664posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004665{
Victor Stinner97b89882010-05-06 00:25:39 +00004666 pid_t pid;
4667 WAIT_TYPE status;
4668 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004669
Victor Stinner97b89882010-05-06 00:25:39 +00004670 Py_BEGIN_ALLOW_THREADS
4671 pid = wait(&status);
4672 Py_END_ALLOW_THREADS
4673 if (pid == -1)
4674 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004675
Victor Stinner97b89882010-05-06 00:25:39 +00004676 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004677}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004678#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004679
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004680
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004681PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004682"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004683Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004684
Barry Warsaw53699e91996-12-10 23:23:01 +00004685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004686posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004687{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004688#ifdef HAVE_LSTAT
Victor Stinner97b89882010-05-06 00:25:39 +00004689 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004690#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004691#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00004692 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004693#else
Victor Stinner97b89882010-05-06 00:25:39 +00004694 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004695#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004696#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004697}
4698
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004699
Guido van Rossumb6775db1994-08-01 11:34:53 +00004700#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004701PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004702"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004703Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004704
Barry Warsaw53699e91996-12-10 23:23:01 +00004705static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004706posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004707{
Victor Stinner97b89882010-05-06 00:25:39 +00004708 PyObject* v;
4709 char buf[MAXPATHLEN];
4710 PyObject *opath;
4711 char *path;
4712 int n;
4713 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004714
Victor Stinner97b89882010-05-06 00:25:39 +00004715 if (!PyArg_ParseTuple(args, "O&:readlink",
4716 PyUnicode_FSConverter, &opath))
4717 return NULL;
4718 path = bytes2str(opath, 1);
4719 v = PySequence_GetItem(args, 0);
4720 if (v == NULL) {
4721 release_bytes(opath);
4722 return NULL;
4723 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004724
Victor Stinner97b89882010-05-06 00:25:39 +00004725 if (PyUnicode_Check(v)) {
4726 arg_is_unicode = 1;
4727 }
4728 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004729
Victor Stinner97b89882010-05-06 00:25:39 +00004730 Py_BEGIN_ALLOW_THREADS
4731 n = readlink(path, buf, (int) sizeof buf);
4732 Py_END_ALLOW_THREADS
4733 if (n < 0)
4734 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004735
Victor Stinner97b89882010-05-06 00:25:39 +00004736 release_bytes(opath);
Victor Stinner203406c2010-05-14 18:07:39 +00004737 v = PyBytes_FromStringAndSize(buf, n);
4738 if (arg_is_unicode) {
4739 PyObject *w;
4740
4741 w = PyUnicode_FromEncodedObject(v,
4742 Py_FileSystemDefaultEncoding,
4743 "surrogateescape");
4744 if (w != NULL) {
4745 Py_DECREF(v);
4746 v = w;
4747 }
4748 else {
4749 v = NULL;
4750 }
4751 }
4752 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004753}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004754#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004755
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004756
Guido van Rossumb6775db1994-08-01 11:34:53 +00004757#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004758PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004759"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004760Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004761
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004763posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004764{
Victor Stinner97b89882010-05-06 00:25:39 +00004765 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004766}
4767#endif /* HAVE_SYMLINK */
4768
4769
4770#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00004771#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4772static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004773system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004774{
4775 ULONG value = 0;
4776
4777 Py_BEGIN_ALLOW_THREADS
4778 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4779 Py_END_ALLOW_THREADS
4780
4781 return value;
4782}
4783
4784static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004785posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004786{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004787 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner97b89882010-05-06 00:25:39 +00004788 return Py_BuildValue("ddddd",
4789 (double)0 /* t.tms_utime / HZ */,
4790 (double)0 /* t.tms_stime / HZ */,
4791 (double)0 /* t.tms_cutime / HZ */,
4792 (double)0 /* t.tms_cstime / HZ */,
4793 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004794}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004795#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00004796#define NEED_TICKS_PER_SECOND
4797static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00004798static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004799posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004800{
Victor Stinner97b89882010-05-06 00:25:39 +00004801 struct tms t;
4802 clock_t c;
4803 errno = 0;
4804 c = times(&t);
4805 if (c == (clock_t) -1)
4806 return posix_error();
4807 return Py_BuildValue("ddddd",
4808 (double)t.tms_utime / ticks_per_second,
4809 (double)t.tms_stime / ticks_per_second,
4810 (double)t.tms_cutime / ticks_per_second,
4811 (double)t.tms_cstime / ticks_per_second,
4812 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004813}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004814#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004815#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004816
4817
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004818#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00004819#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004820static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004821posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004822{
Victor Stinner97b89882010-05-06 00:25:39 +00004823 FILETIME create, exit, kernel, user;
4824 HANDLE hProc;
4825 hProc = GetCurrentProcess();
4826 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4827 /* The fields of a FILETIME structure are the hi and lo part
4828 of a 64-bit value expressed in 100 nanosecond units.
4829 1e7 is one second in such units; 1e-7 the inverse.
4830 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4831 */
4832 return Py_BuildValue(
4833 "ddddd",
4834 (double)(user.dwHighDateTime*429.4967296 +
4835 user.dwLowDateTime*1e-7),
4836 (double)(kernel.dwHighDateTime*429.4967296 +
4837 kernel.dwLowDateTime*1e-7),
4838 (double)0,
4839 (double)0,
4840 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004841}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004842#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004843
4844#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004845PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004846"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004847Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004848#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004849
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004850
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004851#ifdef HAVE_GETSID
4852PyDoc_STRVAR(posix_getsid__doc__,
4853"getsid(pid) -> sid\n\n\
4854Call the system call getsid().");
4855
4856static PyObject *
4857posix_getsid(PyObject *self, PyObject *args)
4858{
Victor Stinner97b89882010-05-06 00:25:39 +00004859 pid_t pid;
4860 int sid;
4861 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
4862 return NULL;
4863 sid = getsid(pid);
4864 if (sid < 0)
4865 return posix_error();
4866 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004867}
4868#endif /* HAVE_GETSID */
4869
4870
Guido van Rossumb6775db1994-08-01 11:34:53 +00004871#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004872PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004873"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004874Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004875
Barry Warsaw53699e91996-12-10 23:23:01 +00004876static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004877posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004878{
Victor Stinner97b89882010-05-06 00:25:39 +00004879 if (setsid() < 0)
4880 return posix_error();
4881 Py_INCREF(Py_None);
4882 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004883}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004884#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004885
Guido van Rossumb6775db1994-08-01 11:34:53 +00004886#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004887PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004888"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004889Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004890
Barry Warsaw53699e91996-12-10 23:23:01 +00004891static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004892posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004893{
Victor Stinner97b89882010-05-06 00:25:39 +00004894 pid_t pid;
4895 int pgrp;
4896 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
4897 return NULL;
4898 if (setpgid(pid, pgrp) < 0)
4899 return posix_error();
4900 Py_INCREF(Py_None);
4901 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004902}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004903#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004904
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004905
Guido van Rossumb6775db1994-08-01 11:34:53 +00004906#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004907PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004908"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004909Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004910
Barry Warsaw53699e91996-12-10 23:23:01 +00004911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004912posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004913{
Victor Stinner97b89882010-05-06 00:25:39 +00004914 int fd;
4915 pid_t pgid;
4916 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
4917 return NULL;
4918 pgid = tcgetpgrp(fd);
4919 if (pgid < 0)
4920 return posix_error();
4921 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004922}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004923#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004924
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004925
Guido van Rossumb6775db1994-08-01 11:34:53 +00004926#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004927PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004928"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004929Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004930
Barry Warsaw53699e91996-12-10 23:23:01 +00004931static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004932posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004933{
Victor Stinner97b89882010-05-06 00:25:39 +00004934 int fd;
4935 pid_t pgid;
4936 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
4937 return NULL;
4938 if (tcsetpgrp(fd, pgid) < 0)
4939 return posix_error();
4940 Py_INCREF(Py_None);
4941 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004942}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004943#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004944
Guido van Rossum687dd131993-05-17 08:34:16 +00004945/* Functions acting on file descriptors */
4946
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004947PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004948"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004949Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004950
Barry Warsaw53699e91996-12-10 23:23:01 +00004951static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004952posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004953{
Victor Stinner97b89882010-05-06 00:25:39 +00004954 PyObject *ofile;
4955 char *file;
4956 int flag;
4957 int mode = 0777;
4958 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004959
4960#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00004961 if (unicode_file_names()) {
4962 PyUnicodeObject *po;
4963 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4964 Py_BEGIN_ALLOW_THREADS
4965 /* PyUnicode_AS_UNICODE OK without thread
4966 lock as it is a simple dereference. */
4967 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4968 Py_END_ALLOW_THREADS
4969 if (fd < 0)
4970 return posix_error();
4971 return PyLong_FromLong((long)fd);
4972 }
4973 /* Drop the argument parsing error as narrow strings
4974 are also valid. */
4975 PyErr_Clear();
4976 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004977#endif
4978
Victor Stinner97b89882010-05-06 00:25:39 +00004979 if (!PyArg_ParseTuple(args, "O&i|i",
4980 PyUnicode_FSConverter, &ofile,
4981 &flag, &mode))
4982 return NULL;
4983 file = bytes2str(ofile, 1);
4984 Py_BEGIN_ALLOW_THREADS
4985 fd = open(file, flag, mode);
4986 Py_END_ALLOW_THREADS
4987 if (fd < 0)
4988 return posix_error_with_allocated_filename(ofile);
4989 release_bytes(ofile);
4990 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004991}
4992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004993
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004994PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004995"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004996Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004997
Barry Warsaw53699e91996-12-10 23:23:01 +00004998static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004999posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005000{
Victor Stinner97b89882010-05-06 00:25:39 +00005001 int fd, res;
5002 if (!PyArg_ParseTuple(args, "i:close", &fd))
5003 return NULL;
5004 if (!_PyVerify_fd(fd))
5005 return posix_error();
5006 Py_BEGIN_ALLOW_THREADS
5007 res = close(fd);
5008 Py_END_ALLOW_THREADS
5009 if (res < 0)
5010 return posix_error();
5011 Py_INCREF(Py_None);
5012 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005013}
5014
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005015
Victor Stinner97b89882010-05-06 00:25:39 +00005016PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005017"closerange(fd_low, fd_high)\n\n\
5018Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5019
5020static PyObject *
5021posix_closerange(PyObject *self, PyObject *args)
5022{
Victor Stinner97b89882010-05-06 00:25:39 +00005023 int fd_from, fd_to, i;
5024 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5025 return NULL;
5026 Py_BEGIN_ALLOW_THREADS
5027 for (i = fd_from; i < fd_to; i++)
5028 if (_PyVerify_fd(i))
5029 close(i);
5030 Py_END_ALLOW_THREADS
5031 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005032}
5033
5034
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005035PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005036"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005037Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005038
Barry Warsaw53699e91996-12-10 23:23:01 +00005039static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005040posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005041{
Victor Stinner97b89882010-05-06 00:25:39 +00005042 int fd;
5043 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5044 return NULL;
5045 if (!_PyVerify_fd(fd))
5046 return posix_error();
5047 Py_BEGIN_ALLOW_THREADS
5048 fd = dup(fd);
5049 Py_END_ALLOW_THREADS
5050 if (fd < 0)
5051 return posix_error();
5052 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005053}
5054
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005055
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005056PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005057"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005058Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005059
Barry Warsaw53699e91996-12-10 23:23:01 +00005060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005061posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005062{
Victor Stinner97b89882010-05-06 00:25:39 +00005063 int fd, fd2, res;
5064 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5065 return NULL;
5066 if (!_PyVerify_fd_dup2(fd, fd2))
5067 return posix_error();
5068 Py_BEGIN_ALLOW_THREADS
5069 res = dup2(fd, fd2);
5070 Py_END_ALLOW_THREADS
5071 if (res < 0)
5072 return posix_error();
5073 Py_INCREF(Py_None);
5074 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005075}
5076
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005077
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005078PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005079"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005080Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005081
Barry Warsaw53699e91996-12-10 23:23:01 +00005082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005083posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005084{
Victor Stinner97b89882010-05-06 00:25:39 +00005085 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005086#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +00005087 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005088#else
Victor Stinner97b89882010-05-06 00:25:39 +00005089 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005090#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005091 PyObject *posobj;
5092 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5093 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005094#ifdef SEEK_SET
Victor Stinner97b89882010-05-06 00:25:39 +00005095 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5096 switch (how) {
5097 case 0: how = SEEK_SET; break;
5098 case 1: how = SEEK_CUR; break;
5099 case 2: how = SEEK_END; break;
5100 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005101#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005102
5103#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner97b89882010-05-06 00:25:39 +00005104 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005105#else
Victor Stinner97b89882010-05-06 00:25:39 +00005106 pos = PyLong_Check(posobj) ?
5107 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005108#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005109 if (PyErr_Occurred())
5110 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005111
Victor Stinner97b89882010-05-06 00:25:39 +00005112 if (!_PyVerify_fd(fd))
5113 return posix_error();
5114 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005115#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +00005116 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005117#else
Victor Stinner97b89882010-05-06 00:25:39 +00005118 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005119#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005120 Py_END_ALLOW_THREADS
5121 if (res < 0)
5122 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005123
5124#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner97b89882010-05-06 00:25:39 +00005125 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005126#else
Victor Stinner97b89882010-05-06 00:25:39 +00005127 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005128#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005129}
5130
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005131
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005132PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005133"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005134Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005135
Barry Warsaw53699e91996-12-10 23:23:01 +00005136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005137posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005138{
Victor Stinner97b89882010-05-06 00:25:39 +00005139 int fd, size;
5140 Py_ssize_t n;
5141 PyObject *buffer;
5142 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5143 return NULL;
5144 if (size < 0) {
5145 errno = EINVAL;
5146 return posix_error();
5147 }
5148 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5149 if (buffer == NULL)
5150 return NULL;
Stefan Krah40b61232010-11-26 15:08:59 +00005151 if (!_PyVerify_fd(fd)) {
5152 Py_DECREF(buffer);
Victor Stinner97b89882010-05-06 00:25:39 +00005153 return posix_error();
Stefan Krah40b61232010-11-26 15:08:59 +00005154 }
Victor Stinner97b89882010-05-06 00:25:39 +00005155 Py_BEGIN_ALLOW_THREADS
5156 n = read(fd, PyBytes_AS_STRING(buffer), size);
5157 Py_END_ALLOW_THREADS
5158 if (n < 0) {
5159 Py_DECREF(buffer);
5160 return posix_error();
5161 }
5162 if (n != size)
5163 _PyBytes_Resize(&buffer, n);
5164 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005165}
5166
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005167
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005168PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005169"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005170Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005171
Barry Warsaw53699e91996-12-10 23:23:01 +00005172static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005173posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005174{
Victor Stinner97b89882010-05-06 00:25:39 +00005175 Py_buffer pbuf;
5176 int fd;
5177 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005178
Victor Stinner97b89882010-05-06 00:25:39 +00005179 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5180 return NULL;
Stefan Krah40b61232010-11-26 15:08:59 +00005181 if (!_PyVerify_fd(fd)) {
5182 PyBuffer_Release(&pbuf);
Victor Stinner97b89882010-05-06 00:25:39 +00005183 return posix_error();
Stefan Krah40b61232010-11-26 15:08:59 +00005184 }
Victor Stinner97b89882010-05-06 00:25:39 +00005185 Py_BEGIN_ALLOW_THREADS
5186 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5187 Py_END_ALLOW_THREADS
Stefan Krah40b61232010-11-26 15:08:59 +00005188 PyBuffer_Release(&pbuf);
Victor Stinner97b89882010-05-06 00:25:39 +00005189 if (size < 0)
5190 return posix_error();
5191 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005192}
5193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005194
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005195PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005196"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005197Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005198
Barry Warsaw53699e91996-12-10 23:23:01 +00005199static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005200posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005201{
Victor Stinner97b89882010-05-06 00:25:39 +00005202 int fd;
5203 STRUCT_STAT st;
5204 int res;
5205 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5206 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005207#ifdef __VMS
Victor Stinner97b89882010-05-06 00:25:39 +00005208 /* on OpenVMS we must ensure that all bytes are written to the file */
5209 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005210#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005211 if (!_PyVerify_fd(fd))
5212 return posix_error();
5213 Py_BEGIN_ALLOW_THREADS
5214 res = FSTAT(fd, &st);
5215 Py_END_ALLOW_THREADS
5216 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005217#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005218 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005219#else
Victor Stinner97b89882010-05-06 00:25:39 +00005220 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005221#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005222 }
Tim Peters5aa91602002-01-30 05:46:57 +00005223
Victor Stinner97b89882010-05-06 00:25:39 +00005224 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005225}
5226
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005227PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005228"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005229Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005230connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005231
5232static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005233posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005234{
Victor Stinner97b89882010-05-06 00:25:39 +00005235 int fd;
5236 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5237 return NULL;
5238 if (!_PyVerify_fd(fd))
5239 return PyBool_FromLong(0);
5240 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005241}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005242
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005243#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005244PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005245"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005246Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005247
Barry Warsaw53699e91996-12-10 23:23:01 +00005248static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005249posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005250{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005251#if defined(PYOS_OS2)
5252 HFILE read, write;
5253 APIRET rc;
5254
Victor Stinner97b89882010-05-06 00:25:39 +00005255 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005256 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner97b89882010-05-06 00:25:39 +00005257 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005258 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005259 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005260
5261 return Py_BuildValue("(ii)", read, write);
5262#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005263#if !defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +00005264 int fds[2];
5265 int res;
5266 Py_BEGIN_ALLOW_THREADS
5267 res = pipe(fds);
5268 Py_END_ALLOW_THREADS
5269 if (res != 0)
5270 return posix_error();
5271 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005272#else /* MS_WINDOWS */
Victor Stinner97b89882010-05-06 00:25:39 +00005273 HANDLE read, write;
5274 int read_fd, write_fd;
5275 BOOL ok;
5276 Py_BEGIN_ALLOW_THREADS
5277 ok = CreatePipe(&read, &write, NULL, 0);
5278 Py_END_ALLOW_THREADS
5279 if (!ok)
5280 return win32_error("CreatePipe", NULL);
5281 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5282 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5283 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005284#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005285#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005286}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005287#endif /* HAVE_PIPE */
5288
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005289
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005290#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005291PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005292"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005293Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005294
Barry Warsaw53699e91996-12-10 23:23:01 +00005295static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005296posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005297{
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005298 PyObject *opath;
Victor Stinner97b89882010-05-06 00:25:39 +00005299 char *filename;
5300 int mode = 0666;
5301 int res;
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005302 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5303 &mode))
Victor Stinner97b89882010-05-06 00:25:39 +00005304 return NULL;
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005305 filename = PyBytes_AS_STRING(opath);
Victor Stinner97b89882010-05-06 00:25:39 +00005306 Py_BEGIN_ALLOW_THREADS
5307 res = mkfifo(filename, mode);
5308 Py_END_ALLOW_THREADS
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005309 Py_DECREF(opath);
Victor Stinner97b89882010-05-06 00:25:39 +00005310 if (res < 0)
5311 return posix_error();
5312 Py_INCREF(Py_None);
5313 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005314}
5315#endif
5316
5317
Neal Norwitz11690112002-07-30 01:08:28 +00005318#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005319PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005320"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005321Create a filesystem node (file, device special file or named pipe)\n\
5322named filename. mode specifies both the permissions to use and the\n\
5323type of node to be created, being combined (bitwise OR) with one of\n\
5324S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005325device defines the newly created device special file (probably using\n\
5326os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005327
5328
5329static PyObject *
5330posix_mknod(PyObject *self, PyObject *args)
5331{
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005332 PyObject *opath;
Victor Stinner97b89882010-05-06 00:25:39 +00005333 char *filename;
5334 int mode = 0600;
5335 int device = 0;
5336 int res;
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005337 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5338 &mode, &device))
Victor Stinner97b89882010-05-06 00:25:39 +00005339 return NULL;
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005340 filename = PyBytes_AS_STRING(opath);
Victor Stinner97b89882010-05-06 00:25:39 +00005341 Py_BEGIN_ALLOW_THREADS
5342 res = mknod(filename, mode, device);
5343 Py_END_ALLOW_THREADS
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005344 Py_DECREF(opath);
Victor Stinner97b89882010-05-06 00:25:39 +00005345 if (res < 0)
5346 return posix_error();
5347 Py_INCREF(Py_None);
5348 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005349}
5350#endif
5351
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005352#ifdef HAVE_DEVICE_MACROS
5353PyDoc_STRVAR(posix_major__doc__,
5354"major(device) -> major number\n\
5355Extracts a device major number from a raw device number.");
5356
5357static PyObject *
5358posix_major(PyObject *self, PyObject *args)
5359{
Victor Stinner97b89882010-05-06 00:25:39 +00005360 int device;
5361 if (!PyArg_ParseTuple(args, "i:major", &device))
5362 return NULL;
5363 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005364}
5365
5366PyDoc_STRVAR(posix_minor__doc__,
5367"minor(device) -> minor number\n\
5368Extracts a device minor number from a raw device number.");
5369
5370static PyObject *
5371posix_minor(PyObject *self, PyObject *args)
5372{
Victor Stinner97b89882010-05-06 00:25:39 +00005373 int device;
5374 if (!PyArg_ParseTuple(args, "i:minor", &device))
5375 return NULL;
5376 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005377}
5378
5379PyDoc_STRVAR(posix_makedev__doc__,
5380"makedev(major, minor) -> device number\n\
5381Composes a raw device number from the major and minor device numbers.");
5382
5383static PyObject *
5384posix_makedev(PyObject *self, PyObject *args)
5385{
Victor Stinner97b89882010-05-06 00:25:39 +00005386 int major, minor;
5387 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5388 return NULL;
5389 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005390}
5391#endif /* device macros */
5392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005393
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005394#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005395PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005396"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005397Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005398
Barry Warsaw53699e91996-12-10 23:23:01 +00005399static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005400posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005401{
Victor Stinner97b89882010-05-06 00:25:39 +00005402 int fd;
5403 off_t length;
5404 int res;
5405 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005406
Victor Stinner97b89882010-05-06 00:25:39 +00005407 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5408 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005409
5410#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner97b89882010-05-06 00:25:39 +00005411 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005412#else
Victor Stinner97b89882010-05-06 00:25:39 +00005413 length = PyLong_Check(lenobj) ?
5414 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005415#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005416 if (PyErr_Occurred())
5417 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005418
Victor Stinner97b89882010-05-06 00:25:39 +00005419 Py_BEGIN_ALLOW_THREADS
5420 res = ftruncate(fd, length);
5421 Py_END_ALLOW_THREADS
5422 if (res < 0)
5423 return posix_error();
5424 Py_INCREF(Py_None);
5425 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005426}
5427#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005428
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005429#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005430PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005431"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005432Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005433
Fred Drake762e2061999-08-26 17:23:54 +00005434/* Save putenv() parameters as values here, so we can collect them when they
5435 * get re-set with another call for the same key. */
5436static PyObject *posix_putenv_garbage;
5437
Tim Peters5aa91602002-01-30 05:46:57 +00005438static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005439posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005440{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005441#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005442 wchar_t *s1, *s2;
5443 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005444#else
Victor Stinner97b89882010-05-06 00:25:39 +00005445 PyObject *os1, *os2;
5446 char *s1, *s2;
5447 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005448#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005449 PyObject *newstr;
5450 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005451
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005452#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005453 if (!PyArg_ParseTuple(args,
5454 "uu:putenv",
5455 &s1, &s2))
5456 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005457#else
Victor Stinner97b89882010-05-06 00:25:39 +00005458 if (!PyArg_ParseTuple(args,
5459 "O&O&:putenv",
5460 PyUnicode_FSConverter, &os1,
5461 PyUnicode_FSConverter, &os2))
5462 return NULL;
5463 s1 = bytes2str(os1, 1);
5464 s2 = bytes2str(os2, 1);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005465#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005466
5467#if defined(PYOS_OS2)
5468 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5469 APIRET rc;
5470
Guido van Rossumd48f2521997-12-05 22:19:34 +00005471 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5472 if (rc != NO_ERROR)
5473 return os2_error(rc);
5474
5475 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5476 APIRET rc;
5477
Guido van Rossumd48f2521997-12-05 22:19:34 +00005478 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5479 if (rc != NO_ERROR)
5480 return os2_error(rc);
5481 } else {
5482#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005483 /* XXX This can leak memory -- not easy to fix :-( */
5484 /* len includes space for a trailing \0; the size arg to
5485 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005486#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005487 len = wcslen(s1) + wcslen(s2) + 2;
5488 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005489#else
Victor Stinner97b89882010-05-06 00:25:39 +00005490 len = strlen(s1) + strlen(s2) + 2;
5491 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005492#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005493 if (newstr == NULL)
5494 return PyErr_NoMemory();
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005495#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005496 newenv = PyUnicode_AsUnicode(newstr);
5497 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5498 if (_wputenv(newenv)) {
5499 Py_DECREF(newstr);
5500 posix_error();
5501 return NULL;
5502 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005503#else
Victor Stinner97b89882010-05-06 00:25:39 +00005504 newenv = PyBytes_AS_STRING(newstr);
5505 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5506 if (putenv(newenv)) {
5507 Py_DECREF(newstr);
5508 release_bytes(os1);
5509 release_bytes(os2);
5510 posix_error();
5511 return NULL;
5512 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005513#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005514 /* Install the first arg and newstr in posix_putenv_garbage;
5515 * this will cause previous value to be collected. This has to
5516 * happen after the real putenv() call because the old value
5517 * was still accessible until then. */
5518 if (PyDict_SetItem(posix_putenv_garbage,
5519 PyTuple_GET_ITEM(args, 0), newstr)) {
5520 /* really not much we can do; just leak */
5521 PyErr_Clear();
5522 }
5523 else {
5524 Py_DECREF(newstr);
5525 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005526
5527#if defined(PYOS_OS2)
5528 }
5529#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00005530#ifndef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005531 release_bytes(os1);
5532 release_bytes(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005533#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005534 Py_INCREF(Py_None);
5535 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005536}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005537#endif /* putenv */
5538
Guido van Rossumc524d952001-10-19 01:31:59 +00005539#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005540PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005541"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005542Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005543
5544static PyObject *
5545posix_unsetenv(PyObject *self, PyObject *args)
5546{
Victor Stinner97b89882010-05-06 00:25:39 +00005547 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00005548
Victor Stinner97b89882010-05-06 00:25:39 +00005549 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5550 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00005551
Victor Stinner97b89882010-05-06 00:25:39 +00005552 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00005553
Victor Stinner97b89882010-05-06 00:25:39 +00005554 /* Remove the key from posix_putenv_garbage;
5555 * this will cause it to be collected. This has to
5556 * happen after the real unsetenv() call because the
5557 * old value was still accessible until then.
5558 */
5559 if (PyDict_DelItem(posix_putenv_garbage,
5560 PyTuple_GET_ITEM(args, 0))) {
5561 /* really not much we can do; just leak */
5562 PyErr_Clear();
5563 }
Guido van Rossumc524d952001-10-19 01:31:59 +00005564
Victor Stinner97b89882010-05-06 00:25:39 +00005565 Py_INCREF(Py_None);
5566 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00005567}
5568#endif /* unsetenv */
5569
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005570PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005571"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005572Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005573
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005574static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005575posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005576{
Victor Stinner97b89882010-05-06 00:25:39 +00005577 int code;
5578 char *message;
5579 if (!PyArg_ParseTuple(args, "i:strerror", &code))
5580 return NULL;
5581 message = strerror(code);
5582 if (message == NULL) {
5583 PyErr_SetString(PyExc_ValueError,
5584 "strerror() argument out of range");
5585 return NULL;
5586 }
5587 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005588}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005589
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005590
Guido van Rossumc9641791998-08-04 15:26:23 +00005591#ifdef HAVE_SYS_WAIT_H
5592
Fred Drake106c1a02002-04-23 15:58:02 +00005593#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005594PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005595"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005596Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005597
5598static PyObject *
5599posix_WCOREDUMP(PyObject *self, PyObject *args)
5600{
Victor Stinner97b89882010-05-06 00:25:39 +00005601 WAIT_TYPE status;
5602 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005603
Victor Stinner97b89882010-05-06 00:25:39 +00005604 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
5605 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005606
Victor Stinner97b89882010-05-06 00:25:39 +00005607 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005608}
5609#endif /* WCOREDUMP */
5610
5611#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005612PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005613"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005614Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005615job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005616
5617static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005618posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005619{
Victor Stinner97b89882010-05-06 00:25:39 +00005620 WAIT_TYPE status;
5621 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005622
Victor Stinner97b89882010-05-06 00:25:39 +00005623 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
5624 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005625
Victor Stinner97b89882010-05-06 00:25:39 +00005626 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005627}
5628#endif /* WIFCONTINUED */
5629
Guido van Rossumc9641791998-08-04 15:26:23 +00005630#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005631PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005632"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005633Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005634
5635static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005636posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005637{
Victor Stinner97b89882010-05-06 00:25:39 +00005638 WAIT_TYPE status;
5639 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005640
Victor Stinner97b89882010-05-06 00:25:39 +00005641 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
5642 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005643
Victor Stinner97b89882010-05-06 00:25:39 +00005644 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005645}
5646#endif /* WIFSTOPPED */
5647
5648#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005649PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005650"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005651Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005652
5653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005654posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005655{
Victor Stinner97b89882010-05-06 00:25:39 +00005656 WAIT_TYPE status;
5657 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005658
Victor Stinner97b89882010-05-06 00:25:39 +00005659 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
5660 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005661
Victor Stinner97b89882010-05-06 00:25:39 +00005662 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005663}
5664#endif /* WIFSIGNALED */
5665
5666#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005667PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005668"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005669Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005670system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005671
5672static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005673posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005674{
Victor Stinner97b89882010-05-06 00:25:39 +00005675 WAIT_TYPE status;
5676 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005677
Victor Stinner97b89882010-05-06 00:25:39 +00005678 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
5679 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005680
Victor Stinner97b89882010-05-06 00:25:39 +00005681 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005682}
5683#endif /* WIFEXITED */
5684
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005685#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005686PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005687"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005689
5690static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005691posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005692{
Victor Stinner97b89882010-05-06 00:25:39 +00005693 WAIT_TYPE status;
5694 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005695
Victor Stinner97b89882010-05-06 00:25:39 +00005696 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
5697 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005698
Victor Stinner97b89882010-05-06 00:25:39 +00005699 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005700}
5701#endif /* WEXITSTATUS */
5702
5703#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005704PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005705"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005706Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005707value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005708
5709static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005710posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005711{
Victor Stinner97b89882010-05-06 00:25:39 +00005712 WAIT_TYPE status;
5713 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005714
Victor Stinner97b89882010-05-06 00:25:39 +00005715 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
5716 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005717
Victor Stinner97b89882010-05-06 00:25:39 +00005718 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005719}
5720#endif /* WTERMSIG */
5721
5722#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005723PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005724"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005725Return the signal that stopped the process that provided\n\
5726the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005727
5728static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005729posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005730{
Victor Stinner97b89882010-05-06 00:25:39 +00005731 WAIT_TYPE status;
5732 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005733
Victor Stinner97b89882010-05-06 00:25:39 +00005734 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
5735 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005736
Victor Stinner97b89882010-05-06 00:25:39 +00005737 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005738}
5739#endif /* WSTOPSIG */
5740
5741#endif /* HAVE_SYS_WAIT_H */
5742
5743
Thomas Wouters477c8d52006-05-27 19:21:47 +00005744#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005745#ifdef _SCO_DS
5746/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5747 needed definitions in sys/statvfs.h */
5748#define _SVID3
5749#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005750#include <sys/statvfs.h>
5751
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005752static PyObject*
5753_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner97b89882010-05-06 00:25:39 +00005754 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5755 if (v == NULL)
5756 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005757
5758#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner97b89882010-05-06 00:25:39 +00005759 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5760 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5761 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
5762 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
5763 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
5764 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
5765 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
5766 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
5767 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5768 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005769#else
Victor Stinner97b89882010-05-06 00:25:39 +00005770 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5771 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5772 PyStructSequence_SET_ITEM(v, 2,
5773 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
5774 PyStructSequence_SET_ITEM(v, 3,
5775 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
5776 PyStructSequence_SET_ITEM(v, 4,
5777 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
5778 PyStructSequence_SET_ITEM(v, 5,
5779 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
5780 PyStructSequence_SET_ITEM(v, 6,
5781 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
5782 PyStructSequence_SET_ITEM(v, 7,
5783 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
5784 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5785 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005786#endif
5787
Victor Stinner97b89882010-05-06 00:25:39 +00005788 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005789}
5790
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005791PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005792"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005793Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005794
5795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005796posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005797{
Victor Stinner97b89882010-05-06 00:25:39 +00005798 int fd, res;
5799 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005800
Victor Stinner97b89882010-05-06 00:25:39 +00005801 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
5802 return NULL;
5803 Py_BEGIN_ALLOW_THREADS
5804 res = fstatvfs(fd, &st);
5805 Py_END_ALLOW_THREADS
5806 if (res != 0)
5807 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005808
Victor Stinner97b89882010-05-06 00:25:39 +00005809 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005810}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005811#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005812
5813
Thomas Wouters477c8d52006-05-27 19:21:47 +00005814#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005815#include <sys/statvfs.h>
5816
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005817PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005818"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005819Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005820
5821static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005822posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005823{
Victor Stinner97b89882010-05-06 00:25:39 +00005824 char *path;
5825 int res;
5826 struct statvfs st;
5827 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
5828 return NULL;
5829 Py_BEGIN_ALLOW_THREADS
5830 res = statvfs(path, &st);
5831 Py_END_ALLOW_THREADS
5832 if (res != 0)
5833 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005834
Victor Stinner97b89882010-05-06 00:25:39 +00005835 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005836}
5837#endif /* HAVE_STATVFS */
5838
Fred Drakec9680921999-12-13 16:37:25 +00005839/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5840 * It maps strings representing configuration variable names to
5841 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005842 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005843 * rarely-used constants. There are three separate tables that use
5844 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005845 *
5846 * This code is always included, even if none of the interfaces that
5847 * need it are included. The #if hackery needed to avoid it would be
5848 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005849 */
5850struct constdef {
5851 char *name;
5852 long value;
5853};
5854
Fred Drake12c6e2d1999-12-14 21:25:03 +00005855static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005856conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005857 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005858{
Christian Heimes217cfd12007-12-02 14:31:20 +00005859 if (PyLong_Check(arg)) {
Stefan Krah67733312010-11-26 17:04:40 +00005860 *valuep = PyLong_AS_LONG(arg);
5861 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005862 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005863 else {
Stefan Krah67733312010-11-26 17:04:40 +00005864 /* look up the value in the table using a binary search */
5865 size_t lo = 0;
5866 size_t mid;
5867 size_t hi = tablesize;
5868 int cmp;
5869 const char *confname;
5870 if (!PyUnicode_Check(arg)) {
5871 PyErr_SetString(PyExc_TypeError,
5872 "configuration names must be strings or integers");
5873 return 0;
Victor Stinner97b89882010-05-06 00:25:39 +00005874 }
Stefan Krah67733312010-11-26 17:04:40 +00005875 confname = _PyUnicode_AsString(arg);
5876 if (confname == NULL)
5877 return 0;
5878 while (lo < hi) {
5879 mid = (lo + hi) / 2;
5880 cmp = strcmp(confname, table[mid].name);
5881 if (cmp < 0)
5882 hi = mid;
5883 else if (cmp > 0)
5884 lo = mid + 1;
5885 else {
5886 *valuep = table[mid].value;
5887 return 1;
5888 }
5889 }
5890 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5891 return 0;
Victor Stinner97b89882010-05-06 00:25:39 +00005892 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005893}
5894
5895
5896#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5897static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005898#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00005899 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00005900#endif
5901#ifdef _PC_ABI_ASYNC_IO
Victor Stinner97b89882010-05-06 00:25:39 +00005902 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00005903#endif
Fred Drakec9680921999-12-13 16:37:25 +00005904#ifdef _PC_ASYNC_IO
Victor Stinner97b89882010-05-06 00:25:39 +00005905 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00005906#endif
5907#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner97b89882010-05-06 00:25:39 +00005908 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00005909#endif
5910#ifdef _PC_FILESIZEBITS
Victor Stinner97b89882010-05-06 00:25:39 +00005911 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00005912#endif
5913#ifdef _PC_LAST
Victor Stinner97b89882010-05-06 00:25:39 +00005914 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00005915#endif
5916#ifdef _PC_LINK_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00005917 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00005918#endif
5919#ifdef _PC_MAX_CANON
Victor Stinner97b89882010-05-06 00:25:39 +00005920 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00005921#endif
5922#ifdef _PC_MAX_INPUT
Victor Stinner97b89882010-05-06 00:25:39 +00005923 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00005924#endif
5925#ifdef _PC_NAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00005926 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00005927#endif
5928#ifdef _PC_NO_TRUNC
Victor Stinner97b89882010-05-06 00:25:39 +00005929 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00005930#endif
5931#ifdef _PC_PATH_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00005932 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00005933#endif
5934#ifdef _PC_PIPE_BUF
Victor Stinner97b89882010-05-06 00:25:39 +00005935 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00005936#endif
5937#ifdef _PC_PRIO_IO
Victor Stinner97b89882010-05-06 00:25:39 +00005938 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00005939#endif
5940#ifdef _PC_SOCK_MAXBUF
Victor Stinner97b89882010-05-06 00:25:39 +00005941 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00005942#endif
5943#ifdef _PC_SYNC_IO
Victor Stinner97b89882010-05-06 00:25:39 +00005944 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00005945#endif
5946#ifdef _PC_VDISABLE
Victor Stinner97b89882010-05-06 00:25:39 +00005947 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00005948#endif
5949};
5950
Fred Drakec9680921999-12-13 16:37:25 +00005951static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005952conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005953{
5954 return conv_confname(arg, valuep, posix_constants_pathconf,
5955 sizeof(posix_constants_pathconf)
5956 / sizeof(struct constdef));
5957}
5958#endif
5959
5960#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005961PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005962"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005963Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005964If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005965
5966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005967posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005968{
5969 PyObject *result = NULL;
5970 int name, fd;
5971
Fred Drake12c6e2d1999-12-14 21:25:03 +00005972 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5973 conv_path_confname, &name)) {
Stefan Krah67733312010-11-26 17:04:40 +00005974 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00005975
Stefan Krah67733312010-11-26 17:04:40 +00005976 errno = 0;
5977 limit = fpathconf(fd, name);
5978 if (limit == -1 && errno != 0)
5979 posix_error();
5980 else
5981 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005982 }
5983 return result;
5984}
5985#endif
5986
5987
5988#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005989PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005990"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005991Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005992If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005993
5994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005995posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005996{
5997 PyObject *result = NULL;
5998 int name;
5999 char *path;
6000
6001 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6002 conv_path_confname, &name)) {
Victor Stinner97b89882010-05-06 00:25:39 +00006003 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006004
Victor Stinner97b89882010-05-06 00:25:39 +00006005 errno = 0;
6006 limit = pathconf(path, name);
6007 if (limit == -1 && errno != 0) {
6008 if (errno == EINVAL)
Stefan Krah40b61232010-11-26 15:08:59 +00006009 /* could be a path or name problem */
6010 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006011 else
Stefan Krah40b61232010-11-26 15:08:59 +00006012 posix_error_with_filename(path);
Victor Stinner97b89882010-05-06 00:25:39 +00006013 }
6014 else
6015 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006016 }
6017 return result;
6018}
6019#endif
6020
6021#ifdef HAVE_CONFSTR
6022static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006023#ifdef _CS_ARCHITECTURE
Victor Stinner97b89882010-05-06 00:25:39 +00006024 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006025#endif
Mark Dickinson466e9262010-04-16 16:32:49 +00006026#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006027 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson466e9262010-04-16 16:32:49 +00006028#endif
6029#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006030 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson466e9262010-04-16 16:32:49 +00006031#endif
Fred Draked86ed291999-12-15 15:34:33 +00006032#ifdef _CS_HOSTNAME
Victor Stinner97b89882010-05-06 00:25:39 +00006033 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006034#endif
6035#ifdef _CS_HW_PROVIDER
Victor Stinner97b89882010-05-06 00:25:39 +00006036 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006037#endif
6038#ifdef _CS_HW_SERIAL
Victor Stinner97b89882010-05-06 00:25:39 +00006039 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006040#endif
6041#ifdef _CS_INITTAB_NAME
Victor Stinner97b89882010-05-06 00:25:39 +00006042 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006043#endif
Fred Drakec9680921999-12-13 16:37:25 +00006044#ifdef _CS_LFS64_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006045 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006046#endif
6047#ifdef _CS_LFS64_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006048 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006049#endif
6050#ifdef _CS_LFS64_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006051 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006052#endif
6053#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006054 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006055#endif
6056#ifdef _CS_LFS_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006057 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006058#endif
6059#ifdef _CS_LFS_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006060 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006061#endif
6062#ifdef _CS_LFS_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006063 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006064#endif
6065#ifdef _CS_LFS_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006066 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006067#endif
Fred Draked86ed291999-12-15 15:34:33 +00006068#ifdef _CS_MACHINE
Victor Stinner97b89882010-05-06 00:25:39 +00006069 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006070#endif
Fred Drakec9680921999-12-13 16:37:25 +00006071#ifdef _CS_PATH
Victor Stinner97b89882010-05-06 00:25:39 +00006072 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006073#endif
Fred Draked86ed291999-12-15 15:34:33 +00006074#ifdef _CS_RELEASE
Victor Stinner97b89882010-05-06 00:25:39 +00006075 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006076#endif
6077#ifdef _CS_SRPC_DOMAIN
Victor Stinner97b89882010-05-06 00:25:39 +00006078 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006079#endif
6080#ifdef _CS_SYSNAME
Victor Stinner97b89882010-05-06 00:25:39 +00006081 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006082#endif
6083#ifdef _CS_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006084 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006085#endif
Fred Drakec9680921999-12-13 16:37:25 +00006086#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006087 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006088#endif
6089#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006090 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006091#endif
6092#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006093 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006094#endif
6095#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006096 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006097#endif
6098#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006099 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006100#endif
6101#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006102 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006103#endif
6104#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006105 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006106#endif
6107#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006108 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006109#endif
6110#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006111 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006112#endif
6113#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006114 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006115#endif
6116#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006117 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006118#endif
6119#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006120 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006121#endif
6122#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006123 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006124#endif
6125#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006126 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006127#endif
6128#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006129 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006130#endif
6131#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006132 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006133#endif
Fred Draked86ed291999-12-15 15:34:33 +00006134#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner97b89882010-05-06 00:25:39 +00006135 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006136#endif
6137#ifdef _MIPS_CS_BASE
Victor Stinner97b89882010-05-06 00:25:39 +00006138 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006139#endif
6140#ifdef _MIPS_CS_HOSTID
Victor Stinner97b89882010-05-06 00:25:39 +00006141 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006142#endif
6143#ifdef _MIPS_CS_HW_NAME
Victor Stinner97b89882010-05-06 00:25:39 +00006144 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006145#endif
6146#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner97b89882010-05-06 00:25:39 +00006147 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006148#endif
6149#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner97b89882010-05-06 00:25:39 +00006150 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006151#endif
6152#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006153 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006154#endif
6155#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner97b89882010-05-06 00:25:39 +00006156 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006157#endif
6158#ifdef _MIPS_CS_OS_NAME
Victor Stinner97b89882010-05-06 00:25:39 +00006159 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006160#endif
6161#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner97b89882010-05-06 00:25:39 +00006162 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006163#endif
6164#ifdef _MIPS_CS_PROCESSORS
Victor Stinner97b89882010-05-06 00:25:39 +00006165 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006166#endif
6167#ifdef _MIPS_CS_SERIAL
Victor Stinner97b89882010-05-06 00:25:39 +00006168 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006169#endif
6170#ifdef _MIPS_CS_VENDOR
Victor Stinner97b89882010-05-06 00:25:39 +00006171 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006172#endif
Fred Drakec9680921999-12-13 16:37:25 +00006173};
6174
6175static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006176conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006177{
6178 return conv_confname(arg, valuep, posix_constants_confstr,
6179 sizeof(posix_constants_confstr)
6180 / sizeof(struct constdef));
6181}
6182
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006183PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006184"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006185Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006186
6187static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006188posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006189{
6190 PyObject *result = NULL;
6191 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006192 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00006193
6194 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Stefan Krah40b61232010-11-26 15:08:59 +00006195 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006196
Fred Drakec9680921999-12-13 16:37:25 +00006197 errno = 0;
Victor Stinner97b89882010-05-06 00:25:39 +00006198 len = confstr(name, buffer, sizeof(buffer));
6199 if (len == 0) {
6200 if (errno) {
6201 posix_error();
6202 }
6203 else {
6204 result = Py_None;
6205 Py_INCREF(Py_None);
6206 }
Fred Drakec9680921999-12-13 16:37:25 +00006207 }
6208 else {
Victor Stinner97b89882010-05-06 00:25:39 +00006209 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00006210 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006211 if (result != NULL)
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00006212 confstr(name, _PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00006213 }
6214 else
Neal Norwitz93c56822007-08-26 07:10:06 +00006215 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006216 }
6217 }
6218 return result;
6219}
6220#endif
6221
6222
6223#ifdef HAVE_SYSCONF
6224static struct constdef posix_constants_sysconf[] = {
6225#ifdef _SC_2_CHAR_TERM
Victor Stinner97b89882010-05-06 00:25:39 +00006226 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006227#endif
6228#ifdef _SC_2_C_BIND
Victor Stinner97b89882010-05-06 00:25:39 +00006229 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006230#endif
6231#ifdef _SC_2_C_DEV
Victor Stinner97b89882010-05-06 00:25:39 +00006232 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006233#endif
6234#ifdef _SC_2_C_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006235 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006236#endif
6237#ifdef _SC_2_FORT_DEV
Victor Stinner97b89882010-05-06 00:25:39 +00006238 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006239#endif
6240#ifdef _SC_2_FORT_RUN
Victor Stinner97b89882010-05-06 00:25:39 +00006241 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006242#endif
6243#ifdef _SC_2_LOCALEDEF
Victor Stinner97b89882010-05-06 00:25:39 +00006244 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006245#endif
6246#ifdef _SC_2_SW_DEV
Victor Stinner97b89882010-05-06 00:25:39 +00006247 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006248#endif
6249#ifdef _SC_2_UPE
Victor Stinner97b89882010-05-06 00:25:39 +00006250 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006251#endif
6252#ifdef _SC_2_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006253 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006254#endif
Fred Draked86ed291999-12-15 15:34:33 +00006255#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner97b89882010-05-06 00:25:39 +00006256 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006257#endif
6258#ifdef _SC_ACL
Victor Stinner97b89882010-05-06 00:25:39 +00006259 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006260#endif
Fred Drakec9680921999-12-13 16:37:25 +00006261#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006262 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006263#endif
Fred Drakec9680921999-12-13 16:37:25 +00006264#ifdef _SC_AIO_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006265 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006266#endif
6267#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006268 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006269#endif
6270#ifdef _SC_ARG_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006271 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006272#endif
6273#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner97b89882010-05-06 00:25:39 +00006274 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006275#endif
6276#ifdef _SC_ATEXIT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006277 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006278#endif
Fred Draked86ed291999-12-15 15:34:33 +00006279#ifdef _SC_AUDIT
Victor Stinner97b89882010-05-06 00:25:39 +00006280 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006281#endif
Fred Drakec9680921999-12-13 16:37:25 +00006282#ifdef _SC_AVPHYS_PAGES
Victor Stinner97b89882010-05-06 00:25:39 +00006283 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006284#endif
6285#ifdef _SC_BC_BASE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006286 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006287#endif
6288#ifdef _SC_BC_DIM_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006289 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006290#endif
6291#ifdef _SC_BC_SCALE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006292 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006293#endif
6294#ifdef _SC_BC_STRING_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006295 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006296#endif
Fred Draked86ed291999-12-15 15:34:33 +00006297#ifdef _SC_CAP
Victor Stinner97b89882010-05-06 00:25:39 +00006298 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006299#endif
Fred Drakec9680921999-12-13 16:37:25 +00006300#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006301 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006302#endif
6303#ifdef _SC_CHAR_BIT
Victor Stinner97b89882010-05-06 00:25:39 +00006304 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006305#endif
6306#ifdef _SC_CHAR_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006307 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006308#endif
6309#ifdef _SC_CHAR_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006310 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006311#endif
6312#ifdef _SC_CHILD_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006313 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006314#endif
6315#ifdef _SC_CLK_TCK
Victor Stinner97b89882010-05-06 00:25:39 +00006316 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006317#endif
6318#ifdef _SC_COHER_BLKSZ
Victor Stinner97b89882010-05-06 00:25:39 +00006319 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006320#endif
6321#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006322 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006323#endif
6324#ifdef _SC_DCACHE_ASSOC
Victor Stinner97b89882010-05-06 00:25:39 +00006325 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006326#endif
6327#ifdef _SC_DCACHE_BLKSZ
Victor Stinner97b89882010-05-06 00:25:39 +00006328 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006329#endif
6330#ifdef _SC_DCACHE_LINESZ
Victor Stinner97b89882010-05-06 00:25:39 +00006331 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006332#endif
6333#ifdef _SC_DCACHE_SZ
Victor Stinner97b89882010-05-06 00:25:39 +00006334 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006335#endif
6336#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner97b89882010-05-06 00:25:39 +00006337 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006338#endif
6339#ifdef _SC_DELAYTIMER_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006340 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006341#endif
6342#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006343 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006344#endif
6345#ifdef _SC_EXPR_NEST_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006346 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006347#endif
6348#ifdef _SC_FSYNC
Victor Stinner97b89882010-05-06 00:25:39 +00006349 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006350#endif
6351#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006352 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006353#endif
6354#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006355 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006356#endif
6357#ifdef _SC_ICACHE_ASSOC
Victor Stinner97b89882010-05-06 00:25:39 +00006358 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006359#endif
6360#ifdef _SC_ICACHE_BLKSZ
Victor Stinner97b89882010-05-06 00:25:39 +00006361 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006362#endif
6363#ifdef _SC_ICACHE_LINESZ
Victor Stinner97b89882010-05-06 00:25:39 +00006364 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006365#endif
6366#ifdef _SC_ICACHE_SZ
Victor Stinner97b89882010-05-06 00:25:39 +00006367 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006368#endif
Fred Draked86ed291999-12-15 15:34:33 +00006369#ifdef _SC_INF
Victor Stinner97b89882010-05-06 00:25:39 +00006370 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006371#endif
Fred Drakec9680921999-12-13 16:37:25 +00006372#ifdef _SC_INT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006373 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006374#endif
6375#ifdef _SC_INT_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006376 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006377#endif
6378#ifdef _SC_IOV_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006379 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006380#endif
Fred Draked86ed291999-12-15 15:34:33 +00006381#ifdef _SC_IP_SECOPTS
Victor Stinner97b89882010-05-06 00:25:39 +00006382 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006383#endif
Fred Drakec9680921999-12-13 16:37:25 +00006384#ifdef _SC_JOB_CONTROL
Victor Stinner97b89882010-05-06 00:25:39 +00006385 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006386#endif
Fred Draked86ed291999-12-15 15:34:33 +00006387#ifdef _SC_KERN_POINTERS
Victor Stinner97b89882010-05-06 00:25:39 +00006388 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006389#endif
6390#ifdef _SC_KERN_SIM
Victor Stinner97b89882010-05-06 00:25:39 +00006391 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006392#endif
Fred Drakec9680921999-12-13 16:37:25 +00006393#ifdef _SC_LINE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006394 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006395#endif
6396#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006397 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006398#endif
6399#ifdef _SC_LOGNAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006400 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006401#endif
6402#ifdef _SC_LONG_BIT
Victor Stinner97b89882010-05-06 00:25:39 +00006403 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006404#endif
Fred Draked86ed291999-12-15 15:34:33 +00006405#ifdef _SC_MAC
Victor Stinner97b89882010-05-06 00:25:39 +00006406 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006407#endif
Fred Drakec9680921999-12-13 16:37:25 +00006408#ifdef _SC_MAPPED_FILES
Victor Stinner97b89882010-05-06 00:25:39 +00006409 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006410#endif
6411#ifdef _SC_MAXPID
Victor Stinner97b89882010-05-06 00:25:39 +00006412 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006413#endif
6414#ifdef _SC_MB_LEN_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006415 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006416#endif
6417#ifdef _SC_MEMLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00006418 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006419#endif
6420#ifdef _SC_MEMLOCK_RANGE
Victor Stinner97b89882010-05-06 00:25:39 +00006421 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006422#endif
6423#ifdef _SC_MEMORY_PROTECTION
Victor Stinner97b89882010-05-06 00:25:39 +00006424 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006425#endif
6426#ifdef _SC_MESSAGE_PASSING
Victor Stinner97b89882010-05-06 00:25:39 +00006427 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006428#endif
Fred Draked86ed291999-12-15 15:34:33 +00006429#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner97b89882010-05-06 00:25:39 +00006430 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006431#endif
Fred Drakec9680921999-12-13 16:37:25 +00006432#ifdef _SC_MQ_OPEN_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006433 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006434#endif
6435#ifdef _SC_MQ_PRIO_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006436 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006437#endif
Fred Draked86ed291999-12-15 15:34:33 +00006438#ifdef _SC_NACLS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006439 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006440#endif
Fred Drakec9680921999-12-13 16:37:25 +00006441#ifdef _SC_NGROUPS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006442 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006443#endif
6444#ifdef _SC_NL_ARGMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006445 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006446#endif
6447#ifdef _SC_NL_LANGMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006448 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006449#endif
6450#ifdef _SC_NL_MSGMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006451 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006452#endif
6453#ifdef _SC_NL_NMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006454 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006455#endif
6456#ifdef _SC_NL_SETMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006457 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006458#endif
6459#ifdef _SC_NL_TEXTMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006460 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006461#endif
6462#ifdef _SC_NPROCESSORS_CONF
Victor Stinner97b89882010-05-06 00:25:39 +00006463 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00006464#endif
6465#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner97b89882010-05-06 00:25:39 +00006466 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00006467#endif
Fred Draked86ed291999-12-15 15:34:33 +00006468#ifdef _SC_NPROC_CONF
Victor Stinner97b89882010-05-06 00:25:39 +00006469 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00006470#endif
6471#ifdef _SC_NPROC_ONLN
Victor Stinner97b89882010-05-06 00:25:39 +00006472 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00006473#endif
Fred Drakec9680921999-12-13 16:37:25 +00006474#ifdef _SC_NZERO
Victor Stinner97b89882010-05-06 00:25:39 +00006475 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00006476#endif
6477#ifdef _SC_OPEN_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006478 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006479#endif
6480#ifdef _SC_PAGESIZE
Victor Stinner97b89882010-05-06 00:25:39 +00006481 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006482#endif
6483#ifdef _SC_PAGE_SIZE
Victor Stinner97b89882010-05-06 00:25:39 +00006484 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006485#endif
6486#ifdef _SC_PASS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006487 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006488#endif
6489#ifdef _SC_PHYS_PAGES
Victor Stinner97b89882010-05-06 00:25:39 +00006490 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006491#endif
6492#ifdef _SC_PII
Victor Stinner97b89882010-05-06 00:25:39 +00006493 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00006494#endif
6495#ifdef _SC_PII_INTERNET
Victor Stinner97b89882010-05-06 00:25:39 +00006496 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00006497#endif
6498#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner97b89882010-05-06 00:25:39 +00006499 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00006500#endif
6501#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner97b89882010-05-06 00:25:39 +00006502 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00006503#endif
6504#ifdef _SC_PII_OSI
Victor Stinner97b89882010-05-06 00:25:39 +00006505 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00006506#endif
6507#ifdef _SC_PII_OSI_CLTS
Victor Stinner97b89882010-05-06 00:25:39 +00006508 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00006509#endif
6510#ifdef _SC_PII_OSI_COTS
Victor Stinner97b89882010-05-06 00:25:39 +00006511 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00006512#endif
6513#ifdef _SC_PII_OSI_M
Victor Stinner97b89882010-05-06 00:25:39 +00006514 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00006515#endif
6516#ifdef _SC_PII_SOCKET
Victor Stinner97b89882010-05-06 00:25:39 +00006517 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00006518#endif
6519#ifdef _SC_PII_XTI
Victor Stinner97b89882010-05-06 00:25:39 +00006520 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00006521#endif
6522#ifdef _SC_POLL
Victor Stinner97b89882010-05-06 00:25:39 +00006523 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00006524#endif
6525#ifdef _SC_PRIORITIZED_IO
Victor Stinner97b89882010-05-06 00:25:39 +00006526 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006527#endif
6528#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner97b89882010-05-06 00:25:39 +00006529 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00006530#endif
6531#ifdef _SC_REALTIME_SIGNALS
Victor Stinner97b89882010-05-06 00:25:39 +00006532 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00006533#endif
6534#ifdef _SC_RE_DUP_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006535 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006536#endif
6537#ifdef _SC_RTSIG_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006538 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006539#endif
6540#ifdef _SC_SAVED_IDS
Victor Stinner97b89882010-05-06 00:25:39 +00006541 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00006542#endif
6543#ifdef _SC_SCHAR_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006544 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006545#endif
6546#ifdef _SC_SCHAR_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006547 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006548#endif
6549#ifdef _SC_SELECT
Victor Stinner97b89882010-05-06 00:25:39 +00006550 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00006551#endif
6552#ifdef _SC_SEMAPHORES
Victor Stinner97b89882010-05-06 00:25:39 +00006553 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00006554#endif
6555#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006556 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006557#endif
6558#ifdef _SC_SEM_VALUE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006559 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006560#endif
6561#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner97b89882010-05-06 00:25:39 +00006562 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00006563#endif
6564#ifdef _SC_SHRT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006565 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006566#endif
6567#ifdef _SC_SHRT_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006568 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006569#endif
6570#ifdef _SC_SIGQUEUE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006571 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006572#endif
6573#ifdef _SC_SIGRT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006574 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006575#endif
6576#ifdef _SC_SIGRT_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006577 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006578#endif
Fred Draked86ed291999-12-15 15:34:33 +00006579#ifdef _SC_SOFTPOWER
Victor Stinner97b89882010-05-06 00:25:39 +00006580 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00006581#endif
Fred Drakec9680921999-12-13 16:37:25 +00006582#ifdef _SC_SPLIT_CACHE
Victor Stinner97b89882010-05-06 00:25:39 +00006583 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00006584#endif
6585#ifdef _SC_SSIZE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006586 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006587#endif
6588#ifdef _SC_STACK_PROT
Victor Stinner97b89882010-05-06 00:25:39 +00006589 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00006590#endif
6591#ifdef _SC_STREAM_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006592 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006593#endif
6594#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner97b89882010-05-06 00:25:39 +00006595 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006596#endif
6597#ifdef _SC_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00006598 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00006599#endif
6600#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner97b89882010-05-06 00:25:39 +00006601 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00006602#endif
6603#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner97b89882010-05-06 00:25:39 +00006604 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006605#endif
6606#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner97b89882010-05-06 00:25:39 +00006607 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00006608#endif
6609#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006610 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006611#endif
6612#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner97b89882010-05-06 00:25:39 +00006613 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00006614#endif
6615#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner97b89882010-05-06 00:25:39 +00006616 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00006617#endif
6618#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner97b89882010-05-06 00:25:39 +00006619 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00006620#endif
6621#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner97b89882010-05-06 00:25:39 +00006622 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00006623#endif
6624#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner97b89882010-05-06 00:25:39 +00006625 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00006626#endif
6627#ifdef _SC_THREAD_STACK_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006628 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006629#endif
6630#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006631 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006632#endif
6633#ifdef _SC_TIMERS
Victor Stinner97b89882010-05-06 00:25:39 +00006634 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00006635#endif
6636#ifdef _SC_TIMER_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006637 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006638#endif
6639#ifdef _SC_TTY_NAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006640 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006641#endif
6642#ifdef _SC_TZNAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006643 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006644#endif
6645#ifdef _SC_T_IOV_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006646 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006647#endif
6648#ifdef _SC_UCHAR_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006649 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006650#endif
6651#ifdef _SC_UINT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006652 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006653#endif
6654#ifdef _SC_UIO_MAXIOV
Victor Stinner97b89882010-05-06 00:25:39 +00006655 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00006656#endif
6657#ifdef _SC_ULONG_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006658 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006659#endif
6660#ifdef _SC_USHRT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006661 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006662#endif
6663#ifdef _SC_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006664 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006665#endif
6666#ifdef _SC_WORD_BIT
Victor Stinner97b89882010-05-06 00:25:39 +00006667 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006668#endif
6669#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner97b89882010-05-06 00:25:39 +00006670 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00006671#endif
6672#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner97b89882010-05-06 00:25:39 +00006673 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00006674#endif
6675#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner97b89882010-05-06 00:25:39 +00006676 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00006677#endif
6678#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner97b89882010-05-06 00:25:39 +00006679 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00006680#endif
6681#ifdef _SC_XOPEN_CRYPT
Victor Stinner97b89882010-05-06 00:25:39 +00006682 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00006683#endif
6684#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner97b89882010-05-06 00:25:39 +00006685 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00006686#endif
6687#ifdef _SC_XOPEN_LEGACY
Victor Stinner97b89882010-05-06 00:25:39 +00006688 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00006689#endif
6690#ifdef _SC_XOPEN_REALTIME
Victor Stinner97b89882010-05-06 00:25:39 +00006691 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00006692#endif
6693#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00006694 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00006695#endif
6696#ifdef _SC_XOPEN_SHM
Victor Stinner97b89882010-05-06 00:25:39 +00006697 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00006698#endif
6699#ifdef _SC_XOPEN_UNIX
Victor Stinner97b89882010-05-06 00:25:39 +00006700 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00006701#endif
6702#ifdef _SC_XOPEN_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006703 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006704#endif
6705#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006706 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006707#endif
6708#ifdef _SC_XOPEN_XPG2
Victor Stinner97b89882010-05-06 00:25:39 +00006709 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00006710#endif
6711#ifdef _SC_XOPEN_XPG3
Victor Stinner97b89882010-05-06 00:25:39 +00006712 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00006713#endif
6714#ifdef _SC_XOPEN_XPG4
Victor Stinner97b89882010-05-06 00:25:39 +00006715 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00006716#endif
6717};
6718
6719static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006720conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006721{
6722 return conv_confname(arg, valuep, posix_constants_sysconf,
6723 sizeof(posix_constants_sysconf)
6724 / sizeof(struct constdef));
6725}
6726
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006727PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006728"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006729Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006730
6731static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006732posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006733{
6734 PyObject *result = NULL;
6735 int name;
6736
6737 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6738 int value;
6739
6740 errno = 0;
6741 value = sysconf(name);
6742 if (value == -1 && errno != 0)
6743 posix_error();
6744 else
Christian Heimes217cfd12007-12-02 14:31:20 +00006745 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00006746 }
6747 return result;
6748}
6749#endif
6750
6751
Fred Drakebec628d1999-12-15 18:31:10 +00006752/* This code is used to ensure that the tables of configuration value names
6753 * are in sorted order as required by conv_confname(), and also to build the
6754 * the exported dictionaries that are used to publish information about the
6755 * names available on the host platform.
6756 *
6757 * Sorting the table at runtime ensures that the table is properly ordered
6758 * when used, even for platforms we're not able to test on. It also makes
6759 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006760 */
Fred Drakebec628d1999-12-15 18:31:10 +00006761
6762static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006763cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006764{
6765 const struct constdef *c1 =
Victor Stinner97b89882010-05-06 00:25:39 +00006766 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00006767 const struct constdef *c2 =
Victor Stinner97b89882010-05-06 00:25:39 +00006768 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00006769
6770 return strcmp(c1->name, c2->name);
6771}
6772
6773static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006774setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner97b89882010-05-06 00:25:39 +00006775 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006776{
Fred Drakebec628d1999-12-15 18:31:10 +00006777 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006778 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006779
6780 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6781 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006782 if (d == NULL)
Victor Stinner97b89882010-05-06 00:25:39 +00006783 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006784
Barry Warsaw3155db32000-04-13 15:20:40 +00006785 for (i=0; i < tablesize; ++i) {
Victor Stinner97b89882010-05-06 00:25:39 +00006786 PyObject *o = PyLong_FromLong(table[i].value);
6787 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6788 Py_XDECREF(o);
6789 Py_DECREF(d);
6790 return -1;
6791 }
6792 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006793 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006794 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006795}
6796
Fred Drakebec628d1999-12-15 18:31:10 +00006797/* Return -1 on failure, 0 on success. */
6798static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006799setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006800{
6801#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006802 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006803 sizeof(posix_constants_pathconf)
6804 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006805 "pathconf_names", module))
Stefan Krah67733312010-11-26 17:04:40 +00006806 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006807#endif
6808#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006809 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006810 sizeof(posix_constants_confstr)
6811 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006812 "confstr_names", module))
Stefan Krah67733312010-11-26 17:04:40 +00006813 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006814#endif
6815#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006816 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006817 sizeof(posix_constants_sysconf)
6818 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006819 "sysconf_names", module))
Stefan Krah67733312010-11-26 17:04:40 +00006820 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006821#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006822 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006823}
Fred Draked86ed291999-12-15 15:34:33 +00006824
6825
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006826PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006827"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006828Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006829in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006830
6831static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006832posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006833{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006834 abort();
6835 /*NOTREACHED*/
6836 Py_FatalError("abort() called from Python code didn't abort!");
6837 return NULL;
6838}
Fred Drakebec628d1999-12-15 18:31:10 +00006839
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006840#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006841PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006842"startfile(filepath [, operation]) - Start a file with its associated\n\
6843application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006844\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006845When \"operation\" is not specified or \"open\", this acts like\n\
6846double-clicking the file in Explorer, or giving the file name as an\n\
6847argument to the DOS \"start\" command: the file is opened with whatever\n\
6848application (if any) its extension is associated.\n\
6849When another \"operation\" is given, it specifies what should be done with\n\
6850the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006851\n\
6852startfile returns as soon as the associated application is launched.\n\
6853There is no option to wait for the application to close, and no way\n\
6854to retrieve the application's exit status.\n\
6855\n\
6856The filepath is relative to the current directory. If you want to use\n\
6857an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006858the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006859
6860static PyObject *
6861win32_startfile(PyObject *self, PyObject *args)
6862{
Victor Stinner97b89882010-05-06 00:25:39 +00006863 PyObject *ofilepath;
6864 char *filepath;
6865 char *operation = NULL;
6866 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00006867
Victor Stinner97b89882010-05-06 00:25:39 +00006868 if (unicode_file_names()) {
6869 PyObject *unipath, *woperation = NULL;
6870 if (!PyArg_ParseTuple(args, "U|s:startfile",
6871 &unipath, &operation)) {
6872 PyErr_Clear();
6873 goto normal;
6874 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006875
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006876
Victor Stinner97b89882010-05-06 00:25:39 +00006877 if (operation) {
6878 woperation = PyUnicode_DecodeASCII(operation,
6879 strlen(operation), NULL);
6880 if (!woperation) {
6881 PyErr_Clear();
6882 operation = NULL;
6883 goto normal;
6884 }
6885 }
6886
6887 Py_BEGIN_ALLOW_THREADS
6888 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6889 PyUnicode_AS_UNICODE(unipath),
6890 NULL, NULL, SW_SHOWNORMAL);
6891 Py_END_ALLOW_THREADS
6892
6893 Py_XDECREF(woperation);
6894 if (rc <= (HINSTANCE)32) {
6895 PyObject *errval = win32_error_unicode("startfile",
6896 PyUnicode_AS_UNICODE(unipath));
6897 return errval;
6898 }
6899 Py_INCREF(Py_None);
6900 return Py_None;
6901 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006902
6903normal:
Victor Stinner97b89882010-05-06 00:25:39 +00006904 if (!PyArg_ParseTuple(args, "O&|s:startfile",
6905 PyUnicode_FSConverter, &ofilepath,
6906 &operation))
6907 return NULL;
6908 filepath = bytes2str(ofilepath, 1);
6909 Py_BEGIN_ALLOW_THREADS
6910 rc = ShellExecute((HWND)0, operation, filepath,
6911 NULL, NULL, SW_SHOWNORMAL);
6912 Py_END_ALLOW_THREADS
6913 if (rc <= (HINSTANCE)32) {
6914 PyObject *errval = win32_error("startfile", filepath);
6915 release_bytes(ofilepath);
6916 return errval;
6917 }
6918 release_bytes(ofilepath);
6919 Py_INCREF(Py_None);
6920 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006921}
6922#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006923
Martin v. Löwis438b5342002-12-27 10:16:42 +00006924#ifdef HAVE_GETLOADAVG
6925PyDoc_STRVAR(posix_getloadavg__doc__,
6926"getloadavg() -> (float, float, float)\n\n\
6927Return the number of processes in the system run queue averaged over\n\
6928the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6929was unobtainable");
6930
6931static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006932posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006933{
6934 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006935 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah67733312010-11-26 17:04:40 +00006936 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6937 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00006938 } else
Stefan Krah67733312010-11-26 17:04:40 +00006939 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00006940}
6941#endif
6942
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006943#ifdef MS_WINDOWS
6944
6945PyDoc_STRVAR(win32_urandom__doc__,
6946"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006947Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006948
6949typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6950 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6951 DWORD dwFlags );
6952typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6953 BYTE *pbBuffer );
6954
6955static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00006956/* This handle is never explicitly released. Instead, the operating
6957 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006958static HCRYPTPROV hCryptProv = 0;
6959
Tim Peters4ad82172004-08-30 17:02:04 +00006960static PyObject*
6961win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006962{
Victor Stinner97b89882010-05-06 00:25:39 +00006963 int howMany;
6964 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006965
Victor Stinner97b89882010-05-06 00:25:39 +00006966 /* Read arguments */
6967 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
6968 return NULL;
6969 if (howMany < 0)
6970 return PyErr_Format(PyExc_ValueError,
6971 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006972
Victor Stinner97b89882010-05-06 00:25:39 +00006973 if (hCryptProv == 0) {
6974 HINSTANCE hAdvAPI32 = NULL;
6975 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006976
Victor Stinner97b89882010-05-06 00:25:39 +00006977 /* Obtain handle to the DLL containing CryptoAPI
6978 This should not fail */
6979 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6980 if(hAdvAPI32 == NULL)
6981 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006982
Victor Stinner97b89882010-05-06 00:25:39 +00006983 /* Obtain pointers to the CryptoAPI functions
6984 This will fail on some early versions of Win95 */
6985 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6986 hAdvAPI32,
6987 "CryptAcquireContextA");
6988 if (pCryptAcquireContext == NULL)
6989 return PyErr_Format(PyExc_NotImplementedError,
6990 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006991
Victor Stinner97b89882010-05-06 00:25:39 +00006992 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6993 hAdvAPI32, "CryptGenRandom");
6994 if (pCryptGenRandom == NULL)
6995 return PyErr_Format(PyExc_NotImplementedError,
6996 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006997
Victor Stinner97b89882010-05-06 00:25:39 +00006998 /* Acquire context */
6999 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7000 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7001 return win32_error("CryptAcquireContext", NULL);
7002 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007003
Victor Stinner97b89882010-05-06 00:25:39 +00007004 /* Allocate bytes */
7005 result = PyBytes_FromStringAndSize(NULL, howMany);
7006 if (result != NULL) {
7007 /* Get random data */
7008 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7009 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7010 PyBytes_AS_STRING(result))) {
7011 Py_DECREF(result);
7012 return win32_error("CryptGenRandom", NULL);
7013 }
7014 }
7015 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007016}
7017#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007018
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007019PyDoc_STRVAR(device_encoding__doc__,
7020"device_encoding(fd) -> str\n\n\
7021Return a string describing the encoding of the device\n\
7022if the output is a terminal; else return None.");
7023
7024static PyObject *
7025device_encoding(PyObject *self, PyObject *args)
7026{
Victor Stinner97b89882010-05-06 00:25:39 +00007027 int fd;
7028 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7029 return NULL;
7030 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7031 Py_INCREF(Py_None);
7032 return Py_None;
7033 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007034#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner97b89882010-05-06 00:25:39 +00007035 if (fd == 0) {
7036 char buf[100];
7037 sprintf(buf, "cp%d", GetConsoleCP());
7038 return PyUnicode_FromString(buf);
7039 }
7040 if (fd == 1 || fd == 2) {
7041 char buf[100];
7042 sprintf(buf, "cp%d", GetConsoleOutputCP());
7043 return PyUnicode_FromString(buf);
7044 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007045#elif defined(CODESET)
Victor Stinner97b89882010-05-06 00:25:39 +00007046 {
7047 char *codeset = nl_langinfo(CODESET);
7048 if (codeset != NULL && codeset[0] != 0)
7049 return PyUnicode_FromString(codeset);
7050 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007051#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007052 Py_INCREF(Py_None);
7053 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007054}
7055
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007056#ifdef __VMS
7057/* Use openssl random routine */
7058#include <openssl/rand.h>
7059PyDoc_STRVAR(vms_urandom__doc__,
7060"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007061Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007062
7063static PyObject*
7064vms_urandom(PyObject *self, PyObject *args)
7065{
Victor Stinner97b89882010-05-06 00:25:39 +00007066 int howMany;
7067 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007068
Victor Stinner97b89882010-05-06 00:25:39 +00007069 /* Read arguments */
7070 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7071 return NULL;
7072 if (howMany < 0)
7073 return PyErr_Format(PyExc_ValueError,
7074 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007075
Victor Stinner97b89882010-05-06 00:25:39 +00007076 /* Allocate bytes */
7077 result = PyBytes_FromStringAndSize(NULL, howMany);
7078 if (result != NULL) {
7079 /* Get random data */
7080 if (RAND_pseudo_bytes((unsigned char*)
7081 PyBytes_AS_STRING(result),
7082 howMany) < 0) {
7083 Py_DECREF(result);
7084 return PyErr_Format(PyExc_ValueError,
7085 "RAND_pseudo_bytes");
7086 }
7087 }
7088 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007089}
7090#endif
7091
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007092static PyMethodDef posix_methods[] = {
Victor Stinner97b89882010-05-06 00:25:39 +00007093 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007094#ifdef HAVE_TTYNAME
Victor Stinner97b89882010-05-06 00:25:39 +00007095 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007096#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007097 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007098#ifdef HAVE_CHFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00007099 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007100#endif /* HAVE_CHFLAGS */
Victor Stinner97b89882010-05-06 00:25:39 +00007101 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007102#ifdef HAVE_FCHMOD
Victor Stinner97b89882010-05-06 00:25:39 +00007103 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007104#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007105#ifdef HAVE_CHOWN
Victor Stinner97b89882010-05-06 00:25:39 +00007106 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007107#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007108#ifdef HAVE_LCHMOD
Victor Stinner97b89882010-05-06 00:25:39 +00007109 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007110#endif /* HAVE_LCHMOD */
7111#ifdef HAVE_FCHOWN
Victor Stinner97b89882010-05-06 00:25:39 +00007112 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007113#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007114#ifdef HAVE_LCHFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00007115 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007116#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007117#ifdef HAVE_LCHOWN
Victor Stinner97b89882010-05-06 00:25:39 +00007118 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007119#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007120#ifdef HAVE_CHROOT
Victor Stinner97b89882010-05-06 00:25:39 +00007121 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007122#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007123#ifdef HAVE_CTERMID
Victor Stinner97b89882010-05-06 00:25:39 +00007124 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007125#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007126#ifdef HAVE_GETCWD
Victor Stinner97b89882010-05-06 00:25:39 +00007127 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7128 METH_NOARGS, posix_getcwd__doc__},
7129 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7130 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007131#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007132#ifdef HAVE_LINK
Victor Stinner97b89882010-05-06 00:25:39 +00007133 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007134#endif /* HAVE_LINK */
Victor Stinner97b89882010-05-06 00:25:39 +00007135 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7136 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7137 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007138#ifdef HAVE_NICE
Victor Stinner97b89882010-05-06 00:25:39 +00007139 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007140#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007141#ifdef HAVE_READLINK
Victor Stinner97b89882010-05-06 00:25:39 +00007142 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007143#endif /* HAVE_READLINK */
Victor Stinner97b89882010-05-06 00:25:39 +00007144 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7145 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7146 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
7147 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007148#ifdef HAVE_SYMLINK
Victor Stinner97b89882010-05-06 00:25:39 +00007149 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007150#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007151#ifdef HAVE_SYSTEM
Victor Stinner97b89882010-05-06 00:25:39 +00007152 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007153#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007154 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007155#ifdef HAVE_UNAME
Victor Stinner97b89882010-05-06 00:25:39 +00007156 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007157#endif /* HAVE_UNAME */
Victor Stinner97b89882010-05-06 00:25:39 +00007158 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7159 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7160 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007161#ifdef HAVE_TIMES
Victor Stinner97b89882010-05-06 00:25:39 +00007162 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007163#endif /* HAVE_TIMES */
Victor Stinner97b89882010-05-06 00:25:39 +00007164 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007165#ifdef HAVE_EXECV
Victor Stinner97b89882010-05-06 00:25:39 +00007166 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7167 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007168#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007169#ifdef HAVE_SPAWNV
Victor Stinner97b89882010-05-06 00:25:39 +00007170 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7171 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007172#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +00007173 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7174 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007175#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007176#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007177#ifdef HAVE_FORK1
Victor Stinner97b89882010-05-06 00:25:39 +00007178 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007179#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007180#ifdef HAVE_FORK
Victor Stinner97b89882010-05-06 00:25:39 +00007181 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007182#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007183#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner97b89882010-05-06 00:25:39 +00007184 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007185#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007186#ifdef HAVE_FORKPTY
Victor Stinner97b89882010-05-06 00:25:39 +00007187 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007188#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007189#ifdef HAVE_GETEGID
Victor Stinner97b89882010-05-06 00:25:39 +00007190 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007191#endif /* HAVE_GETEGID */
7192#ifdef HAVE_GETEUID
Victor Stinner97b89882010-05-06 00:25:39 +00007193 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007194#endif /* HAVE_GETEUID */
7195#ifdef HAVE_GETGID
Victor Stinner97b89882010-05-06 00:25:39 +00007196 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007197#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007198#ifdef HAVE_GETGROUPS
Victor Stinner97b89882010-05-06 00:25:39 +00007199 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007200#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007201 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007202#ifdef HAVE_GETPGRP
Victor Stinner97b89882010-05-06 00:25:39 +00007203 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007204#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007205#ifdef HAVE_GETPPID
Victor Stinner97b89882010-05-06 00:25:39 +00007206 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007207#endif /* HAVE_GETPPID */
7208#ifdef HAVE_GETUID
Victor Stinner97b89882010-05-06 00:25:39 +00007209 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007210#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007211#ifdef HAVE_GETLOGIN
Victor Stinner97b89882010-05-06 00:25:39 +00007212 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007213#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007214#ifdef HAVE_KILL
Victor Stinner97b89882010-05-06 00:25:39 +00007215 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007216#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007217#ifdef HAVE_KILLPG
Victor Stinner97b89882010-05-06 00:25:39 +00007218 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007219#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007220#ifdef HAVE_PLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00007221 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007222#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007223#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00007224 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007225#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007226#ifdef HAVE_SETUID
Victor Stinner97b89882010-05-06 00:25:39 +00007227 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007228#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007229#ifdef HAVE_SETEUID
Victor Stinner97b89882010-05-06 00:25:39 +00007230 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007231#endif /* HAVE_SETEUID */
7232#ifdef HAVE_SETEGID
Victor Stinner97b89882010-05-06 00:25:39 +00007233 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007234#endif /* HAVE_SETEGID */
7235#ifdef HAVE_SETREUID
Victor Stinner97b89882010-05-06 00:25:39 +00007236 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007237#endif /* HAVE_SETREUID */
7238#ifdef HAVE_SETREGID
Victor Stinner97b89882010-05-06 00:25:39 +00007239 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007240#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007241#ifdef HAVE_SETGID
Victor Stinner97b89882010-05-06 00:25:39 +00007242 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007243#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007244#ifdef HAVE_SETGROUPS
Victor Stinner97b89882010-05-06 00:25:39 +00007245 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007246#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007247#ifdef HAVE_GETPGID
Victor Stinner97b89882010-05-06 00:25:39 +00007248 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007249#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007250#ifdef HAVE_SETPGRP
Victor Stinner97b89882010-05-06 00:25:39 +00007251 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007252#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007253#ifdef HAVE_WAIT
Victor Stinner97b89882010-05-06 00:25:39 +00007254 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007255#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007256#ifdef HAVE_WAIT3
Victor Stinner97b89882010-05-06 00:25:39 +00007257 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007258#endif /* HAVE_WAIT3 */
7259#ifdef HAVE_WAIT4
Victor Stinner97b89882010-05-06 00:25:39 +00007260 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007261#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007262#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner97b89882010-05-06 00:25:39 +00007263 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007264#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007265#ifdef HAVE_GETSID
Victor Stinner97b89882010-05-06 00:25:39 +00007266 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007267#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007268#ifdef HAVE_SETSID
Victor Stinner97b89882010-05-06 00:25:39 +00007269 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007270#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007271#ifdef HAVE_SETPGID
Victor Stinner97b89882010-05-06 00:25:39 +00007272 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007273#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007274#ifdef HAVE_TCGETPGRP
Victor Stinner97b89882010-05-06 00:25:39 +00007275 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007276#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007277#ifdef HAVE_TCSETPGRP
Victor Stinner97b89882010-05-06 00:25:39 +00007278 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007279#endif /* HAVE_TCSETPGRP */
Victor Stinner97b89882010-05-06 00:25:39 +00007280 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7281 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7282 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7283 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7284 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7285 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7286 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7287 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7288 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7289 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7290 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007291#ifdef HAVE_PIPE
Victor Stinner97b89882010-05-06 00:25:39 +00007292 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007293#endif
7294#ifdef HAVE_MKFIFO
Victor Stinner97b89882010-05-06 00:25:39 +00007295 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007296#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007297#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner97b89882010-05-06 00:25:39 +00007298 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007299#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007300#ifdef HAVE_DEVICE_MACROS
Victor Stinner97b89882010-05-06 00:25:39 +00007301 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7302 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7303 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007304#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007305#ifdef HAVE_FTRUNCATE
Victor Stinner97b89882010-05-06 00:25:39 +00007306 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007307#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007308#ifdef HAVE_PUTENV
Victor Stinner97b89882010-05-06 00:25:39 +00007309 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007310#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007311#ifdef HAVE_UNSETENV
Victor Stinner97b89882010-05-06 00:25:39 +00007312 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007313#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007314 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007315#ifdef HAVE_FCHDIR
Victor Stinner97b89882010-05-06 00:25:39 +00007316 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007317#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007318#ifdef HAVE_FSYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007319 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007320#endif
7321#ifdef HAVE_FDATASYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007322 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007323#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007324#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007325#ifdef WCOREDUMP
Victor Stinner97b89882010-05-06 00:25:39 +00007326 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007327#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007328#ifdef WIFCONTINUED
Victor Stinner97b89882010-05-06 00:25:39 +00007329 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007330#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007331#ifdef WIFSTOPPED
Victor Stinner97b89882010-05-06 00:25:39 +00007332 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007333#endif /* WIFSTOPPED */
7334#ifdef WIFSIGNALED
Victor Stinner97b89882010-05-06 00:25:39 +00007335 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007336#endif /* WIFSIGNALED */
7337#ifdef WIFEXITED
Victor Stinner97b89882010-05-06 00:25:39 +00007338 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007339#endif /* WIFEXITED */
7340#ifdef WEXITSTATUS
Victor Stinner97b89882010-05-06 00:25:39 +00007341 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007342#endif /* WEXITSTATUS */
7343#ifdef WTERMSIG
Victor Stinner97b89882010-05-06 00:25:39 +00007344 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007345#endif /* WTERMSIG */
7346#ifdef WSTOPSIG
Victor Stinner97b89882010-05-06 00:25:39 +00007347 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007348#endif /* WSTOPSIG */
7349#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007350#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner97b89882010-05-06 00:25:39 +00007351 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007352#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007353#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner97b89882010-05-06 00:25:39 +00007354 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007355#endif
Fred Drakec9680921999-12-13 16:37:25 +00007356#ifdef HAVE_CONFSTR
Victor Stinner97b89882010-05-06 00:25:39 +00007357 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007358#endif
7359#ifdef HAVE_SYSCONF
Victor Stinner97b89882010-05-06 00:25:39 +00007360 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007361#endif
7362#ifdef HAVE_FPATHCONF
Victor Stinner97b89882010-05-06 00:25:39 +00007363 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007364#endif
7365#ifdef HAVE_PATHCONF
Victor Stinner97b89882010-05-06 00:25:39 +00007366 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007367#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007368 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007369#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00007370 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00007371#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007372#ifdef HAVE_GETLOADAVG
Victor Stinner97b89882010-05-06 00:25:39 +00007373 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007374#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007375 #ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00007376 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007377 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007378 #ifdef __VMS
Victor Stinner97b89882010-05-06 00:25:39 +00007379 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007380 #endif
Victor Stinner97b89882010-05-06 00:25:39 +00007381 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007382};
7383
7384
Barry Warsaw4a342091996-12-19 23:50:02 +00007385static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007386ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007387{
Victor Stinner97b89882010-05-06 00:25:39 +00007388 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007389}
7390
Guido van Rossumd48f2521997-12-05 22:19:34 +00007391#if defined(PYOS_OS2)
7392/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007393static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007394{
7395 APIRET rc;
7396 ULONG values[QSV_MAX+1];
7397 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007398 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007399
7400 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007401 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007402 Py_END_ALLOW_THREADS
7403
7404 if (rc != NO_ERROR) {
7405 os2_error(rc);
7406 return -1;
7407 }
7408
Fred Drake4d1e64b2002-04-15 19:40:07 +00007409 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7410 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7411 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7412 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7413 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7414 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7415 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007416
7417 switch (values[QSV_VERSION_MINOR]) {
7418 case 0: ver = "2.00"; break;
7419 case 10: ver = "2.10"; break;
7420 case 11: ver = "2.11"; break;
7421 case 30: ver = "3.00"; break;
7422 case 40: ver = "4.00"; break;
7423 case 50: ver = "5.00"; break;
7424 default:
Tim Peters885d4572001-11-28 20:27:42 +00007425 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner97b89882010-05-06 00:25:39 +00007426 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00007427 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007428 ver = &tmp[0];
7429 }
7430
7431 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007432 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007433 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007434
7435 /* Add Indicator of Which Drive was Used to Boot the System */
7436 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7437 tmp[1] = ':';
7438 tmp[2] = '\0';
7439
Fred Drake4d1e64b2002-04-15 19:40:07 +00007440 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007441}
7442#endif
7443
Barry Warsaw4a342091996-12-19 23:50:02 +00007444static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007445all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007446{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007447#ifdef F_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007448 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007449#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007450#ifdef R_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007451 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007452#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007453#ifdef W_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007454 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007455#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007456#ifdef X_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007457 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007458#endif
Fred Drakec9680921999-12-13 16:37:25 +00007459#ifdef NGROUPS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00007460 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00007461#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007462#ifdef TMP_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00007463 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007464#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007465#ifdef WCONTINUED
Victor Stinner97b89882010-05-06 00:25:39 +00007466 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00007467#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007468#ifdef WNOHANG
Victor Stinner97b89882010-05-06 00:25:39 +00007469 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007470#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007471#ifdef WUNTRACED
Victor Stinner97b89882010-05-06 00:25:39 +00007472 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00007473#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007474#ifdef O_RDONLY
Victor Stinner97b89882010-05-06 00:25:39 +00007475 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007476#endif
7477#ifdef O_WRONLY
Victor Stinner97b89882010-05-06 00:25:39 +00007478 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007479#endif
7480#ifdef O_RDWR
Victor Stinner97b89882010-05-06 00:25:39 +00007481 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007482#endif
7483#ifdef O_NDELAY
Victor Stinner97b89882010-05-06 00:25:39 +00007484 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007485#endif
7486#ifdef O_NONBLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00007487 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007488#endif
7489#ifdef O_APPEND
Victor Stinner97b89882010-05-06 00:25:39 +00007490 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007491#endif
7492#ifdef O_DSYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007493 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007494#endif
7495#ifdef O_RSYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007496 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007497#endif
7498#ifdef O_SYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007499 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007500#endif
7501#ifdef O_NOCTTY
Victor Stinner97b89882010-05-06 00:25:39 +00007502 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007503#endif
7504#ifdef O_CREAT
Victor Stinner97b89882010-05-06 00:25:39 +00007505 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007506#endif
7507#ifdef O_EXCL
Victor Stinner97b89882010-05-06 00:25:39 +00007508 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007509#endif
7510#ifdef O_TRUNC
Victor Stinner97b89882010-05-06 00:25:39 +00007511 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007512#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007513#ifdef O_BINARY
Victor Stinner97b89882010-05-06 00:25:39 +00007514 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00007515#endif
7516#ifdef O_TEXT
Victor Stinner97b89882010-05-06 00:25:39 +00007517 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00007518#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007519#ifdef O_LARGEFILE
Victor Stinner97b89882010-05-06 00:25:39 +00007520 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007521#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007522#ifdef O_SHLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00007523 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00007524#endif
7525#ifdef O_EXLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00007526 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00007527#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007528
Tim Peters5aa91602002-01-30 05:46:57 +00007529/* MS Windows */
7530#ifdef O_NOINHERIT
Victor Stinner97b89882010-05-06 00:25:39 +00007531 /* Don't inherit in child processes. */
7532 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007533#endif
7534#ifdef _O_SHORT_LIVED
Victor Stinner97b89882010-05-06 00:25:39 +00007535 /* Optimize for short life (keep in memory). */
7536 /* MS forgot to define this one with a non-underscore form too. */
7537 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007538#endif
7539#ifdef O_TEMPORARY
Victor Stinner97b89882010-05-06 00:25:39 +00007540 /* Automatically delete when last handle is closed. */
7541 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007542#endif
7543#ifdef O_RANDOM
Victor Stinner97b89882010-05-06 00:25:39 +00007544 /* Optimize for random access. */
7545 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007546#endif
7547#ifdef O_SEQUENTIAL
Victor Stinner97b89882010-05-06 00:25:39 +00007548 /* Optimize for sequential access. */
7549 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007550#endif
7551
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007552/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00007553#ifdef O_ASYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007554 /* Send a SIGIO signal whenever input or output
7555 becomes available on file descriptor */
7556 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00007557#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007558#ifdef O_DIRECT
Victor Stinner97b89882010-05-06 00:25:39 +00007559 /* Direct disk access. */
7560 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007561#endif
7562#ifdef O_DIRECTORY
Victor Stinner97b89882010-05-06 00:25:39 +00007563 /* Must be a directory. */
7564 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007565#endif
7566#ifdef O_NOFOLLOW
Victor Stinner97b89882010-05-06 00:25:39 +00007567 /* Do not follow links. */
7568 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007569#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007570#ifdef O_NOATIME
Victor Stinner97b89882010-05-06 00:25:39 +00007571 /* Do not update the access time. */
7572 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007573#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007574
Victor Stinner97b89882010-05-06 00:25:39 +00007575 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007576#ifdef EX_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007577 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007578#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007579#ifdef EX_USAGE
Victor Stinner97b89882010-05-06 00:25:39 +00007580 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007581#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007582#ifdef EX_DATAERR
Victor Stinner97b89882010-05-06 00:25:39 +00007583 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007584#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007585#ifdef EX_NOINPUT
Victor Stinner97b89882010-05-06 00:25:39 +00007586 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007587#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007588#ifdef EX_NOUSER
Victor Stinner97b89882010-05-06 00:25:39 +00007589 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007590#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007591#ifdef EX_NOHOST
Victor Stinner97b89882010-05-06 00:25:39 +00007592 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007593#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007594#ifdef EX_UNAVAILABLE
Victor Stinner97b89882010-05-06 00:25:39 +00007595 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007596#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007597#ifdef EX_SOFTWARE
Victor Stinner97b89882010-05-06 00:25:39 +00007598 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007599#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007600#ifdef EX_OSERR
Victor Stinner97b89882010-05-06 00:25:39 +00007601 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007602#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007603#ifdef EX_OSFILE
Victor Stinner97b89882010-05-06 00:25:39 +00007604 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007605#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007606#ifdef EX_CANTCREAT
Victor Stinner97b89882010-05-06 00:25:39 +00007607 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007608#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007609#ifdef EX_IOERR
Victor Stinner97b89882010-05-06 00:25:39 +00007610 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007611#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007612#ifdef EX_TEMPFAIL
Victor Stinner97b89882010-05-06 00:25:39 +00007613 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007614#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007615#ifdef EX_PROTOCOL
Victor Stinner97b89882010-05-06 00:25:39 +00007616 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007617#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007618#ifdef EX_NOPERM
Victor Stinner97b89882010-05-06 00:25:39 +00007619 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007620#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007621#ifdef EX_CONFIG
Victor Stinner97b89882010-05-06 00:25:39 +00007622 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007623#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007624#ifdef EX_NOTFOUND
Victor Stinner97b89882010-05-06 00:25:39 +00007625 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007626#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007627
Guido van Rossum246bc171999-02-01 23:54:31 +00007628#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007629#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00007630 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7631 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7632 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7633 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7634 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7635 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7636 if (ins(d, "P_PM", (long)P_PM)) return -1;
7637 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7638 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7639 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7640 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7641 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7642 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7643 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7644 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7645 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7646 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7647 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7648 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7649 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007650#else
Victor Stinner97b89882010-05-06 00:25:39 +00007651 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7652 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7653 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7654 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7655 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007656#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007657#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007658
Guido van Rossumd48f2521997-12-05 22:19:34 +00007659#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +00007660 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007661#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007662 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00007663}
7664
7665
Tim Peters5aa91602002-01-30 05:46:57 +00007666#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007667#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007668#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007669
7670#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007671#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007672#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007673
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007674#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00007675#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007676#define MODNAME "posix"
7677#endif
7678
Martin v. Löwis1a214512008-06-11 05:26:20 +00007679static struct PyModuleDef posixmodule = {
Victor Stinner97b89882010-05-06 00:25:39 +00007680 PyModuleDef_HEAD_INIT,
7681 MODNAME,
7682 posix__doc__,
7683 -1,
7684 posix_methods,
7685 NULL,
7686 NULL,
7687 NULL,
7688 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00007689};
7690
7691
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007692PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007693INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007694{
Victor Stinner97b89882010-05-06 00:25:39 +00007695 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007696
Victor Stinner97b89882010-05-06 00:25:39 +00007697 m = PyModule_Create(&posixmodule);
7698 if (m == NULL)
7699 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007700
Victor Stinner97b89882010-05-06 00:25:39 +00007701 /* Initialize environ dictionary */
7702 v = convertenviron();
7703 Py_XINCREF(v);
7704 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
7705 return NULL;
7706 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007707
Victor Stinner97b89882010-05-06 00:25:39 +00007708 if (all_ins(m))
7709 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00007710
Victor Stinner97b89882010-05-06 00:25:39 +00007711 if (setup_confname_tables(m))
7712 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00007713
Victor Stinner97b89882010-05-06 00:25:39 +00007714 Py_INCREF(PyExc_OSError);
7715 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007716
Guido van Rossumb3d39562000-01-31 18:41:26 +00007717#ifdef HAVE_PUTENV
Victor Stinner97b89882010-05-06 00:25:39 +00007718 if (posix_putenv_garbage == NULL)
7719 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007720#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007721
Victor Stinner97b89882010-05-06 00:25:39 +00007722 if (!initialized) {
7723 stat_result_desc.name = MODNAME ".stat_result";
7724 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7725 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7726 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7727 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7728 structseq_new = StatResultType.tp_new;
7729 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007730
Victor Stinner97b89882010-05-06 00:25:39 +00007731 statvfs_result_desc.name = MODNAME ".statvfs_result";
7732 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007733#ifdef NEED_TICKS_PER_SECOND
7734# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner97b89882010-05-06 00:25:39 +00007735 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007736# elif defined(HZ)
Victor Stinner97b89882010-05-06 00:25:39 +00007737 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007738# else
Victor Stinner97b89882010-05-06 00:25:39 +00007739 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007740# endif
7741#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007742 }
7743 Py_INCREF((PyObject*) &StatResultType);
7744 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
7745 Py_INCREF((PyObject*) &StatVFSResultType);
7746 PyModule_AddObject(m, "statvfs_result",
7747 (PyObject*) &StatVFSResultType);
7748 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007749
7750#ifdef __APPLE__
Victor Stinner97b89882010-05-06 00:25:39 +00007751 /*
7752 * Step 2 of weak-linking support on Mac OS X.
7753 *
7754 * The code below removes functions that are not available on the
7755 * currently active platform.
7756 *
7757 * This block allow one to use a python binary that was build on
7758 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7759 * OSX 10.4.
7760 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007761#ifdef HAVE_FSTATVFS
Victor Stinner97b89882010-05-06 00:25:39 +00007762 if (fstatvfs == NULL) {
7763 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
7764 return NULL;
7765 }
7766 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00007767#endif /* HAVE_FSTATVFS */
7768
7769#ifdef HAVE_STATVFS
Victor Stinner97b89882010-05-06 00:25:39 +00007770 if (statvfs == NULL) {
7771 if (PyObject_DelAttrString(m, "statvfs") == -1) {
7772 return NULL;
7773 }
7774 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00007775#endif /* HAVE_STATVFS */
7776
7777# ifdef HAVE_LCHOWN
Victor Stinner97b89882010-05-06 00:25:39 +00007778 if (lchown == NULL) {
7779 if (PyObject_DelAttrString(m, "lchown") == -1) {
7780 return NULL;
7781 }
7782 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00007783#endif /* HAVE_LCHOWN */
7784
7785
7786#endif /* __APPLE__ */
Victor Stinner97b89882010-05-06 00:25:39 +00007787 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007788
Guido van Rossumb6775db1994-08-01 11:34:53 +00007789}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007790
7791#ifdef __cplusplus
7792}
7793#endif