blob: cba8a9dcafcdbb33d24945ea106569d619ce2965 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Thomas Wouters477c8d52006-05-27 19:21:47 +000016#ifdef __APPLE__
17 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000018 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000019 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#if defined(PYOS_OS2)
49#define INCL_DOS
50#define INCL_DOSERRORS
51#define INCL_DOSPROCESS
52#define INCL_NOPMAPI
53#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000054#if defined(PYCC_GCC)
55#include <ctype.h>
56#include <io.h>
57#include <stdio.h>
58#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000059#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000060#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#endif
62
Thomas Wouters0e3f5912006-08-11 14:57:12 +000063#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065#endif /* HAVE_SYS_TYPES_H */
66
67#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070
Guido van Rossum36bc6801995-06-14 22:54:23 +000071#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000072#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000073#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000076#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000078
Guido van Rossumb6775db1994-08-01 11:34:53 +000079#ifdef HAVE_FCNTL_H
80#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000081#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000082
Guido van Rossuma6535fd2001-10-18 19:44:10 +000083#ifdef HAVE_GRP_H
84#include <grp.h>
85#endif
86
Barry Warsaw5676bd12003-01-07 20:57:09 +000087#ifdef HAVE_SYSEXITS_H
88#include <sysexits.h>
89#endif /* HAVE_SYSEXITS_H */
90
Anthony Baxter8a560de2004-10-13 15:30:56 +000091#ifdef HAVE_SYS_LOADAVG_H
92#include <sys/loadavg.h>
93#endif
94
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000095#ifdef HAVE_LANGINFO_H
96#include <langinfo.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000107#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000114#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000119#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#define HAVE_WAIT 1
121#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000122#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000123#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000124#define HAVE_GETPPID 1
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000125#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000126#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000127#define HAVE_EXECV 1
128#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000129#define HAVE_SYSTEM 1
130#define HAVE_CWAIT 1
131#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000132#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000133#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000134#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
135/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000136#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137/* Unix functions that the configure script doesn't check for */
138#define HAVE_EXECV 1
139#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000140#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000141#define HAVE_FORK1 1
142#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_GETCWD 1
144#define HAVE_GETEGID 1
145#define HAVE_GETEUID 1
146#define HAVE_GETGID 1
147#define HAVE_GETPPID 1
148#define HAVE_GETUID 1
149#define HAVE_KILL 1
150#define HAVE_OPENDIR 1
151#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000154#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000155#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156#endif /* _MSC_VER */
157#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000158#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000159#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000160
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000161#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000162
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000163#if defined(__sgi)&&_COMPILER_VERSION>=700
164/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
165 (default) */
166extern char *ctermid_r(char *);
167#endif
168
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000169#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000170#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000171extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000172#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000173#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000176extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000178#endif
179#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000180extern int chdir(char *);
181extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000182#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000183extern int chdir(const char *);
184extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000185#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000186#ifdef __BORLANDC__
187extern int chmod(const char *, int);
188#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000189extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000190#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000191/*#ifdef HAVE_FCHMOD
192extern int fchmod(int, mode_t);
193#endif*/
194/*#ifdef HAVE_LCHMOD
195extern int lchmod(const char *, mode_t);
196#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000197extern int chown(const char *, uid_t, gid_t);
198extern char *getcwd(char *, int);
199extern char *strerror(int);
200extern int link(const char *, const char *);
201extern int rename(const char *, const char *);
202extern int stat(const char *, struct stat *);
203extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000205extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000206#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000209#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000210#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000211
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000212#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#ifdef HAVE_UTIME_H
215#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000216#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000218#ifdef HAVE_SYS_UTIME_H
219#include <sys/utime.h>
220#define HAVE_UTIME_H /* pretend we do for the rest of this file */
221#endif /* HAVE_SYS_UTIME_H */
222
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223#ifdef HAVE_SYS_TIMES_H
224#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000225#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
227#ifdef HAVE_SYS_PARAM_H
228#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230
231#ifdef HAVE_SYS_UTSNAME_H
232#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000233#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000237#define NAMLEN(dirent) strlen((dirent)->d_name)
238#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000239#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#include <direct.h>
241#define NAMLEN(dirent) strlen((dirent)->d_name)
242#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000245#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000248#endif
249#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000251#endif
252#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000254#endif
255#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000257#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000258#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000260#endif
261#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000263#endif
264#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000266#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000267#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000268#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000269#endif
270#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000271#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000272#endif
273#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000274#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000275#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000276#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000277#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000279#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000280#include <lmcons.h> /* for UNLEN */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000281#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282
Guido van Rossumd48f2521997-12-05 22:19:34 +0000283#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000285#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286
Tim Petersbc2e10e2002-03-03 23:17:02 +0000287#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000288#if defined(PATH_MAX) && PATH_MAX > 1024
289#define MAXPATHLEN PATH_MAX
290#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000291#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000292#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000293#endif /* MAXPATHLEN */
294
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000295#ifdef UNION_WAIT
296/* Emulate some macros on systems that have a union instead of macros */
297
298#ifndef WIFEXITED
299#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
300#endif
301
302#ifndef WEXITSTATUS
303#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
304#endif
305
306#ifndef WTERMSIG
307#define WTERMSIG(u_wait) ((u_wait).w_termsig)
308#endif
309
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000310#define WAIT_TYPE union wait
311#define WAIT_STATUS_INT(s) (s.w_status)
312
313#else /* !UNION_WAIT */
314#define WAIT_TYPE int
315#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000316#endif /* UNION_WAIT */
317
Greg Wardb48bc172000-03-01 21:51:56 +0000318/* Don't use the "_r" form if we don't need it (also, won't have a
319 prototype for it, at least on Solaris -- maybe others as well?). */
320#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
321#define USE_CTERMID_R
322#endif
323
Fred Drake699f3522000-06-29 21:12:41 +0000324/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000325#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000326#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000327# define STAT win32_stat
328# define FSTAT win32_fstat
329# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000330#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000331# define STAT stat
332# define FSTAT fstat
333# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000334#endif
335
Tim Peters11b23062003-04-23 02:39:17 +0000336#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000337#include <sys/mkdev.h>
338#else
339#if defined(MAJOR_IN_SYSMACROS)
340#include <sys/sysmacros.h>
341#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000342#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
343#include <sys/mkdev.h>
344#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000345#endif
Fred Drake699f3522000-06-29 21:12:41 +0000346
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000347#if defined _MSC_VER && _MSC_VER >= 1400
348/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
349 * valid and throw an assertion if it isn't.
350 * Normally, an invalid fd is likely to be a C program error and therefore
351 * an assertion can be useful, but it does contradict the POSIX standard
352 * which for write(2) states:
353 * "Otherwise, -1 shall be returned and errno set to indicate the error."
354 * "[EBADF] The fildes argument is not a valid file descriptor open for
355 * writing."
356 * Furthermore, python allows the user to enter any old integer
357 * as a fd and should merely raise a python exception on error.
358 * The Microsoft CRT doesn't provide an official way to check for the
359 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000360 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000361 * internal structures involved.
362 * The structures below must be updated for each version of visual studio
363 * according to the file internal.h in the CRT source, until MS comes
364 * up with a less hacky way to do this.
365 * (all of this is to avoid globally modifying the CRT behaviour using
366 * _set_invalid_parameter_handler() and _CrtSetReportMode())
367 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000368/* The actual size of the structure is determined at runtime.
369 * Only the first items must be present.
370 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000371typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000372 intptr_t osfhnd;
373 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000374} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000375
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000376extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000377#define IOINFO_L2E 5
378#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
379#define IOINFO_ARRAYS 64
380#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
381#define FOPEN 0x01
382#define _NO_CONSOLE_FILENO (intptr_t)-2
383
384/* This function emulates what the windows CRT does to validate file handles */
385int
386_PyVerify_fd(int fd)
387{
Victor Stinner8c62be82010-05-06 00:08:46 +0000388 const int i1 = fd >> IOINFO_L2E;
389 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000390
Antoine Pitrou22e41552010-08-15 18:07:50 +0000391 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000392
Victor Stinner8c62be82010-05-06 00:08:46 +0000393 /* Determine the actual size of the ioinfo structure,
394 * as used by the CRT loaded in memory
395 */
396 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
397 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
398 }
399 if (sizeof_ioinfo == 0) {
400 /* This should not happen... */
401 goto fail;
402 }
403
404 /* See that it isn't a special CLEAR fileno */
405 if (fd != _NO_CONSOLE_FILENO) {
406 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
407 * we check pointer validity and other info
408 */
409 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
410 /* finally, check that the file is open */
411 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
412 if (info->osfile & FOPEN) {
413 return 1;
414 }
415 }
416 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000417 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000418 errno = EBADF;
419 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000420}
421
422/* the special case of checking dup2. The target fd must be in a sensible range */
423static int
424_PyVerify_fd_dup2(int fd1, int fd2)
425{
Victor Stinner8c62be82010-05-06 00:08:46 +0000426 if (!_PyVerify_fd(fd1))
427 return 0;
428 if (fd2 == _NO_CONSOLE_FILENO)
429 return 0;
430 if ((unsigned)fd2 < _NHANDLE_)
431 return 1;
432 else
433 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000434}
435#else
436/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
437#define _PyVerify_fd_dup2(A, B) (1)
438#endif
439
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000440#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000441/* The following structure was copied from
442 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
443 include doesn't seem to be present in the Windows SDK (at least as included
444 with Visual Studio Express). */
445typedef struct _REPARSE_DATA_BUFFER {
446 ULONG ReparseTag;
447 USHORT ReparseDataLength;
448 USHORT Reserved;
449 union {
450 struct {
451 USHORT SubstituteNameOffset;
452 USHORT SubstituteNameLength;
453 USHORT PrintNameOffset;
454 USHORT PrintNameLength;
455 ULONG Flags;
456 WCHAR PathBuffer[1];
457 } SymbolicLinkReparseBuffer;
458
459 struct {
460 USHORT SubstituteNameOffset;
461 USHORT SubstituteNameLength;
462 USHORT PrintNameOffset;
463 USHORT PrintNameLength;
464 WCHAR PathBuffer[1];
465 } MountPointReparseBuffer;
466
467 struct {
468 UCHAR DataBuffer[1];
469 } GenericReparseBuffer;
470 };
471} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
472
473#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
474 GenericReparseBuffer)
475#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
476
477static int
478_Py_ReadLink(HANDLE reparse_point_handle, ULONG *reparse_tag, wchar_t **target_path)
479{
480 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
481 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
482 DWORD n_bytes_returned;
483 const wchar_t *ptr;
484 wchar_t *buf;
485 size_t len;
486
487 if (0 == DeviceIoControl(
488 reparse_point_handle,
489 FSCTL_GET_REPARSE_POINT,
490 NULL, 0, /* in buffer */
491 target_buffer, sizeof(target_buffer),
492 &n_bytes_returned,
493 NULL)) /* we're not using OVERLAPPED_IO */
494 return 0;
495
496 if (reparse_tag)
497 *reparse_tag = rdb->ReparseTag;
498
499 if (target_path) {
500 switch (rdb->ReparseTag) {
501 case IO_REPARSE_TAG_SYMLINK:
502 /* XXX: Maybe should use SubstituteName? */
503 ptr = rdb->SymbolicLinkReparseBuffer.PathBuffer +
504 rdb->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR);
505 len = rdb->SymbolicLinkReparseBuffer.PrintNameLength/sizeof(WCHAR);
506 break;
507 case IO_REPARSE_TAG_MOUNT_POINT:
508 ptr = rdb->MountPointReparseBuffer.PathBuffer +
509 rdb->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
510 len = rdb->MountPointReparseBuffer.SubstituteNameLength/sizeof(WCHAR);
511 break;
512 default:
513 SetLastError(ERROR_REPARSE_TAG_MISMATCH); /* XXX: Proper error code? */
514 return 0;
515 }
516 buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1));
517 if (!buf) {
518 SetLastError(ERROR_OUTOFMEMORY);
519 return 0;
520 }
521 wcsncpy(buf, ptr, len);
522 buf[len] = L'\0';
523 if (wcsncmp(buf, L"\\??\\", 4) == 0)
524 buf[1] = L'\\';
525 *target_path = buf;
526 }
527
528 return 1;
529}
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000530#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000531
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000532/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000533#ifdef WITH_NEXT_FRAMEWORK
534/* On Darwin/MacOSX a shared library or framework has no access to
535** environ directly, we must obtain it with _NSGetEnviron().
536*/
537#include <crt_externs.h>
538static char **environ;
539#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000540extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000541#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000542
Barry Warsaw53699e91996-12-10 23:23:01 +0000543static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000544convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000545{
Victor Stinner8c62be82010-05-06 00:08:46 +0000546 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000547#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000548 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000549#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000550 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000551#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000552#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000553 APIRET rc;
554 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
555#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000556
Victor Stinner8c62be82010-05-06 00:08:46 +0000557 d = PyDict_New();
558 if (d == NULL)
559 return NULL;
560#ifdef WITH_NEXT_FRAMEWORK
561 if (environ == NULL)
562 environ = *_NSGetEnviron();
563#endif
564#ifdef MS_WINDOWS
565 /* _wenviron must be initialized in this way if the program is started
566 through main() instead of wmain(). */
567 _wgetenv(L"");
568 if (_wenviron == NULL)
569 return d;
570 /* This part ignores errors */
571 for (e = _wenviron; *e != NULL; e++) {
572 PyObject *k;
573 PyObject *v;
574 wchar_t *p = wcschr(*e, L'=');
575 if (p == NULL)
576 continue;
577 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
578 if (k == NULL) {
579 PyErr_Clear();
580 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000581 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000582 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
583 if (v == NULL) {
584 PyErr_Clear();
585 Py_DECREF(k);
586 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000587 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000588 if (PyDict_GetItem(d, k) == NULL) {
589 if (PyDict_SetItem(d, k, v) != 0)
590 PyErr_Clear();
591 }
592 Py_DECREF(k);
593 Py_DECREF(v);
594 }
595#else
596 if (environ == NULL)
597 return d;
598 /* This part ignores errors */
599 for (e = environ; *e != NULL; e++) {
600 PyObject *k;
601 PyObject *v;
602 char *p = strchr(*e, '=');
603 if (p == NULL)
604 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000605 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000606 if (k == NULL) {
607 PyErr_Clear();
608 continue;
609 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000610 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000611 if (v == NULL) {
612 PyErr_Clear();
613 Py_DECREF(k);
614 continue;
615 }
616 if (PyDict_GetItem(d, k) == NULL) {
617 if (PyDict_SetItem(d, k, v) != 0)
618 PyErr_Clear();
619 }
620 Py_DECREF(k);
621 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000622 }
623#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000624#if defined(PYOS_OS2)
625 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
626 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
627 PyObject *v = PyBytes_FromString(buffer);
628 PyDict_SetItemString(d, "BEGINLIBPATH", v);
629 Py_DECREF(v);
630 }
631 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
632 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
633 PyObject *v = PyBytes_FromString(buffer);
634 PyDict_SetItemString(d, "ENDLIBPATH", v);
635 Py_DECREF(v);
636 }
637#endif
638 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000639}
640
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000641/* Set a POSIX-specific error from errno, and return NULL */
642
Barry Warsawd58d7641998-07-23 16:14:40 +0000643static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000644posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000645{
Victor Stinner8c62be82010-05-06 00:08:46 +0000646 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000647}
Barry Warsawd58d7641998-07-23 16:14:40 +0000648static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000649posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000650{
Victor Stinner8c62be82010-05-06 00:08:46 +0000651 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000652}
653
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000654
Mark Hammondef8b6542001-05-13 08:04:26 +0000655static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000656posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000657{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000658 PyObject *name_str, *rc;
659 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
660 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000661 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000662 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
663 name_str);
664 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000665 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000666}
667
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000668#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000669static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000670win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000671{
Victor Stinner8c62be82010-05-06 00:08:46 +0000672 /* XXX We should pass the function name along in the future.
673 (winreg.c also wants to pass the function name.)
674 This would however require an additional param to the
675 Windows error object, which is non-trivial.
676 */
677 errno = GetLastError();
678 if (filename)
679 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
680 else
681 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000682}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000683
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000684static PyObject *
685win32_error_unicode(char* function, Py_UNICODE* filename)
686{
Victor Stinner8c62be82010-05-06 00:08:46 +0000687 /* XXX - see win32_error for comments on 'function' */
688 errno = GetLastError();
689 if (filename)
690 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
691 else
692 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000693}
694
Thomas Wouters477c8d52006-05-27 19:21:47 +0000695static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000696convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000697{
Victor Stinner8c62be82010-05-06 00:08:46 +0000698 if (PyUnicode_CheckExact(*param))
699 Py_INCREF(*param);
700 else if (PyUnicode_Check(*param))
701 /* For a Unicode subtype that's not a Unicode object,
702 return a true Unicode object with the same data. */
703 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
704 PyUnicode_GET_SIZE(*param));
705 else
706 *param = PyUnicode_FromEncodedObject(*param,
707 Py_FileSystemDefaultEncoding,
708 "strict");
709 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000710}
711
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000712#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000713
Guido van Rossumd48f2521997-12-05 22:19:34 +0000714#if defined(PYOS_OS2)
715/**********************************************************************
716 * Helper Function to Trim and Format OS/2 Messages
717 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000718static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000719os2_formatmsg(char *msgbuf, int msglen, char *reason)
720{
721 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
722
723 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
724 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
725
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000726 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000727 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
728 }
729
730 /* Add Optional Reason Text */
731 if (reason) {
732 strcat(msgbuf, " : ");
733 strcat(msgbuf, reason);
734 }
735}
736
737/**********************************************************************
738 * Decode an OS/2 Operating System Error Code
739 *
740 * A convenience function to lookup an OS/2 error code and return a
741 * text message we can use to raise a Python exception.
742 *
743 * Notes:
744 * The messages for errors returned from the OS/2 kernel reside in
745 * the file OSO001.MSG in the \OS2 directory hierarchy.
746 *
747 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000748static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000749os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
750{
751 APIRET rc;
752 ULONG msglen;
753
754 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
755 Py_BEGIN_ALLOW_THREADS
756 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
757 errorcode, "oso001.msg", &msglen);
758 Py_END_ALLOW_THREADS
759
760 if (rc == NO_ERROR)
761 os2_formatmsg(msgbuf, msglen, reason);
762 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000763 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000764 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000765
766 return msgbuf;
767}
768
769/* Set an OS/2-specific error and return NULL. OS/2 kernel
770 errors are not in a global variable e.g. 'errno' nor are
771 they congruent with posix error numbers. */
772
Victor Stinner8c62be82010-05-06 00:08:46 +0000773static PyObject *
774os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000775{
776 char text[1024];
777 PyObject *v;
778
779 os2_strerror(text, sizeof(text), code, "");
780
781 v = Py_BuildValue("(is)", code, text);
782 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000783 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000784 Py_DECREF(v);
785 }
786 return NULL; /* Signal to Python that an Exception is Pending */
787}
788
789#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000790
791/* POSIX generic methods */
792
Barry Warsaw53699e91996-12-10 23:23:01 +0000793static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000794posix_fildes(PyObject *fdobj, int (*func)(int))
795{
Victor Stinner8c62be82010-05-06 00:08:46 +0000796 int fd;
797 int res;
798 fd = PyObject_AsFileDescriptor(fdobj);
799 if (fd < 0)
800 return NULL;
801 if (!_PyVerify_fd(fd))
802 return posix_error();
803 Py_BEGIN_ALLOW_THREADS
804 res = (*func)(fd);
805 Py_END_ALLOW_THREADS
806 if (res < 0)
807 return posix_error();
808 Py_INCREF(Py_None);
809 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000810}
Guido van Rossum21142a01999-01-08 21:05:37 +0000811
812static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000813posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000814{
Victor Stinner8c62be82010-05-06 00:08:46 +0000815 PyObject *opath1 = NULL;
816 char *path1;
817 int res;
818 if (!PyArg_ParseTuple(args, format,
819 PyUnicode_FSConverter, &opath1))
820 return NULL;
821 path1 = PyBytes_AsString(opath1);
822 Py_BEGIN_ALLOW_THREADS
823 res = (*func)(path1);
824 Py_END_ALLOW_THREADS
825 if (res < 0)
826 return posix_error_with_allocated_filename(opath1);
827 Py_DECREF(opath1);
828 Py_INCREF(Py_None);
829 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000830}
831
Barry Warsaw53699e91996-12-10 23:23:01 +0000832static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000833posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000834 char *format,
835 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000836{
Victor Stinner8c62be82010-05-06 00:08:46 +0000837 PyObject *opath1 = NULL, *opath2 = NULL;
838 char *path1, *path2;
839 int res;
840 if (!PyArg_ParseTuple(args, format,
841 PyUnicode_FSConverter, &opath1,
842 PyUnicode_FSConverter, &opath2)) {
843 return NULL;
844 }
845 path1 = PyBytes_AsString(opath1);
846 path2 = PyBytes_AsString(opath2);
847 Py_BEGIN_ALLOW_THREADS
848 res = (*func)(path1, path2);
849 Py_END_ALLOW_THREADS
850 Py_DECREF(opath1);
851 Py_DECREF(opath2);
852 if (res != 0)
853 /* XXX how to report both path1 and path2??? */
854 return posix_error();
855 Py_INCREF(Py_None);
856 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000857}
858
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000859#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000860static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000861win32_1str(PyObject* args, char* func,
862 char* format, BOOL (__stdcall *funcA)(LPCSTR),
863 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000864{
Victor Stinner8c62be82010-05-06 00:08:46 +0000865 PyObject *uni;
866 char *ansi;
867 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000868
Victor Stinner8c62be82010-05-06 00:08:46 +0000869 if (!PyArg_ParseTuple(args, wformat, &uni))
870 PyErr_Clear();
871 else {
872 Py_BEGIN_ALLOW_THREADS
873 result = funcW(PyUnicode_AsUnicode(uni));
874 Py_END_ALLOW_THREADS
875 if (!result)
876 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
877 Py_INCREF(Py_None);
878 return Py_None;
879 }
880 if (!PyArg_ParseTuple(args, format, &ansi))
881 return NULL;
882 Py_BEGIN_ALLOW_THREADS
883 result = funcA(ansi);
884 Py_END_ALLOW_THREADS
885 if (!result)
886 return win32_error(func, ansi);
887 Py_INCREF(Py_None);
888 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000889
890}
891
892/* This is a reimplementation of the C library's chdir function,
893 but one that produces Win32 errors instead of DOS error codes.
894 chdir is essentially a wrapper around SetCurrentDirectory; however,
895 it also needs to set "magic" environment variables indicating
896 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000897static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000898win32_chdir(LPCSTR path)
899{
Victor Stinner8c62be82010-05-06 00:08:46 +0000900 char new_path[MAX_PATH+1];
901 int result;
902 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000903
Victor Stinner8c62be82010-05-06 00:08:46 +0000904 if(!SetCurrentDirectoryA(path))
905 return FALSE;
906 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
907 if (!result)
908 return FALSE;
909 /* In the ANSI API, there should not be any paths longer
910 than MAX_PATH. */
911 assert(result <= MAX_PATH+1);
912 if (strncmp(new_path, "\\\\", 2) == 0 ||
913 strncmp(new_path, "//", 2) == 0)
914 /* UNC path, nothing to do. */
915 return TRUE;
916 env[1] = new_path[0];
917 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000918}
919
920/* The Unicode version differs from the ANSI version
921 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000922static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000923win32_wchdir(LPCWSTR path)
924{
Victor Stinner8c62be82010-05-06 00:08:46 +0000925 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
926 int result;
927 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000928
Victor Stinner8c62be82010-05-06 00:08:46 +0000929 if(!SetCurrentDirectoryW(path))
930 return FALSE;
931 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
932 if (!result)
933 return FALSE;
934 if (result > MAX_PATH+1) {
935 new_path = malloc(result * sizeof(wchar_t));
936 if (!new_path) {
937 SetLastError(ERROR_OUTOFMEMORY);
938 return FALSE;
939 }
940 result = GetCurrentDirectoryW(result, new_path);
941 if (!result) {
942 free(new_path);
943 return FALSE;
944 }
945 }
946 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
947 wcsncmp(new_path, L"//", 2) == 0)
948 /* UNC path, nothing to do. */
949 return TRUE;
950 env[1] = new_path[0];
951 result = SetEnvironmentVariableW(env, new_path);
952 if (new_path != _new_path)
953 free(new_path);
954 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000955}
956#endif
957
Martin v. Löwis14694662006-02-03 12:54:16 +0000958#ifdef MS_WINDOWS
959/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
960 - time stamps are restricted to second resolution
961 - file modification times suffer from forth-and-back conversions between
962 UTC and local time
963 Therefore, we implement our own stat, based on the Win32 API directly.
964*/
Victor Stinner8c62be82010-05-06 00:08:46 +0000965#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000966
967struct win32_stat{
968 int st_dev;
969 __int64 st_ino;
970 unsigned short st_mode;
971 int st_nlink;
972 int st_uid;
973 int st_gid;
974 int st_rdev;
975 __int64 st_size;
976 int st_atime;
977 int st_atime_nsec;
978 int st_mtime;
979 int st_mtime_nsec;
980 int st_ctime;
981 int st_ctime_nsec;
982};
983
984static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
985
986static void
987FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
988{
Victor Stinner8c62be82010-05-06 00:08:46 +0000989 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
990 /* Cannot simply cast and dereference in_ptr,
991 since it might not be aligned properly */
992 __int64 in;
993 memcpy(&in, in_ptr, sizeof(in));
994 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
995 /* XXX Win32 supports time stamps past 2038; we currently don't */
996 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
Martin v. Löwis14694662006-02-03 12:54:16 +0000997}
998
Thomas Wouters477c8d52006-05-27 19:21:47 +0000999static void
1000time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
1001{
Victor Stinner8c62be82010-05-06 00:08:46 +00001002 /* XXX endianness */
1003 __int64 out;
1004 out = time_in + secs_between_epochs;
1005 out = out * 10000000 + nsec_in / 100;
1006 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001007}
1008
Martin v. Löwis14694662006-02-03 12:54:16 +00001009/* Below, we *know* that ugo+r is 0444 */
1010#if _S_IREAD != 0400
1011#error Unsupported C library
1012#endif
1013static int
1014attributes_to_mode(DWORD attr)
1015{
Victor Stinner8c62be82010-05-06 00:08:46 +00001016 int m = 0;
1017 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1018 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1019 else
1020 m |= _S_IFREG;
1021 if (attr & FILE_ATTRIBUTE_READONLY)
1022 m |= 0444;
1023 else
1024 m |= 0666;
1025 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001026}
1027
1028static int
Brian Curtinf5e76d02010-11-24 13:14:05 +00001029attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001030{
Victor Stinner8c62be82010-05-06 00:08:46 +00001031 memset(result, 0, sizeof(*result));
1032 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1033 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1034 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1035 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1036 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001037 result->st_nlink = info->nNumberOfLinks;
Martin v. Löwis14694662006-02-03 12:54:16 +00001038
Victor Stinner8c62be82010-05-06 00:08:46 +00001039 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001040}
1041
Guido van Rossumd8faa362007-04-27 19:54:29 +00001042static BOOL
Brian Curtinf5e76d02010-11-24 13:14:05 +00001043attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001044{
Victor Stinner8c62be82010-05-06 00:08:46 +00001045 HANDLE hFindFile;
1046 WIN32_FIND_DATAA FileData;
1047 hFindFile = FindFirstFileA(pszFile, &FileData);
1048 if (hFindFile == INVALID_HANDLE_VALUE)
1049 return FALSE;
1050 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001051 memset(info, 0, sizeof(*info));
1052 info->dwFileAttributes = FileData.dwFileAttributes;
1053 info->ftCreationTime = FileData.ftCreationTime;
1054 info->ftLastAccessTime = FileData.ftLastAccessTime;
1055 info->ftLastWriteTime = FileData.ftLastWriteTime;
1056 info->nFileSizeHigh = FileData.nFileSizeHigh;
1057 info->nFileSizeLow = FileData.nFileSizeLow;
1058/* info->nNumberOfLinks = 1; */
Victor Stinner8c62be82010-05-06 00:08:46 +00001059 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001060}
1061
1062static BOOL
Brian Curtinf5e76d02010-11-24 13:14:05 +00001063attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001064{
Victor Stinner8c62be82010-05-06 00:08:46 +00001065 HANDLE hFindFile;
1066 WIN32_FIND_DATAW FileData;
1067 hFindFile = FindFirstFileW(pszFile, &FileData);
1068 if (hFindFile == INVALID_HANDLE_VALUE)
1069 return FALSE;
1070 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001071 memset(info, 0, sizeof(*info));
1072 info->dwFileAttributes = FileData.dwFileAttributes;
1073 info->ftCreationTime = FileData.ftCreationTime;
1074 info->ftLastAccessTime = FileData.ftLastAccessTime;
1075 info->ftLastWriteTime = FileData.ftLastWriteTime;
1076 info->nFileSizeHigh = FileData.nFileSizeHigh;
1077 info->nFileSizeLow = FileData.nFileSizeLow;
1078/* info->nNumberOfLinks = 1; */
Victor Stinner8c62be82010-05-06 00:08:46 +00001079 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001080}
1081
Brian Curtinf5e76d02010-11-24 13:14:05 +00001082#ifndef SYMLOOP_MAX
1083#define SYMLOOP_MAX ( 88 )
1084#endif
1085
1086static int
1087win32_xstat_for_handle(HANDLE hFile, struct win32_stat *result, BOOL traverse, int depth);
1088
1089static int
1090win32_xstat(const char *path, struct win32_stat *result, BOOL traverse, int depth)
1091{
1092 int code;
1093 HANDLE hFile;
1094 BY_HANDLE_FILE_INFORMATION info;
1095 const char *dot;
1096
1097 hFile = CreateFileA(
1098 path,
1099 0, /* desired access */
1100 0, /* share mode */
1101 NULL, /* security attributes */
1102 OPEN_EXISTING,
1103 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1104 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT,
1105 NULL);
1106
1107 if(hFile == INVALID_HANDLE_VALUE) {
1108 /* Either the target doesn't exist, or we don't have access to
1109 get a handle to it. If the former, we need to return an error.
1110 If the latter, we can use attributes_from_dir. */
1111 if (GetLastError() != ERROR_SHARING_VIOLATION)
1112 goto err;
1113 else {
1114 /* Could not get attributes on open file. Fall back to
1115 reading the directory. */
1116 if (!attributes_from_dir(path, &info))
1117 /* Very strange. This should not fail now */
1118 goto err;
1119 if (traverse && (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
1120 /* Should traverse, but cannot open reparse point handle */
1121 SetLastError(ERROR_SHARING_VIOLATION);
1122 goto err;
1123 }
1124 attribute_data_to_stat(&info, result);
1125 }
1126 }
1127 else {
1128 code = win32_xstat_for_handle(hFile, result, traverse, depth);
1129 CloseHandle(hFile);
1130 if (code != 0)
1131 return code;
1132 }
1133
1134 /* Set S_IEXEC if it is an .exe, .bat, ... */
1135 dot = strrchr(path, '.');
1136 if (dot) {
1137 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1138 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1139 result->st_mode |= 0111;
1140 }
1141 return 0;
1142
1143err:
1144 /* Protocol violation: we explicitly clear errno, instead of
1145 setting it to a POSIX error. Callers should use GetLastError. */
1146 errno = 0;
1147 return -1;
1148}
1149
1150static int
1151win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth)
1152{
1153 int code;
1154 HANDLE hFile;
1155 BY_HANDLE_FILE_INFORMATION info;
1156 const wchar_t *dot;
1157
1158 hFile = CreateFileW(
1159 path,
1160 0, /* desired access */
1161 0, /* share mode */
1162 NULL, /* security attributes */
1163 OPEN_EXISTING,
1164 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1165 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT,
1166 NULL);
1167
1168 if(hFile == INVALID_HANDLE_VALUE) {
1169 /* Either the target doesn't exist, or we don't have access to
1170 get a handle to it. If the former, we need to return an error.
1171 If the latter, we can use attributes_from_dir. */
1172 if (GetLastError() != ERROR_SHARING_VIOLATION)
1173 goto err;
1174 else {
1175 /* Could not get attributes on open file. Fall back to
1176 reading the directory. */
1177 if (!attributes_from_dir_w(path, &info))
1178 /* Very strange. This should not fail now */
1179 goto err;
1180 if (traverse && (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
1181 /* Should traverse, but cannot open reparse point handle */
1182 SetLastError(ERROR_SHARING_VIOLATION);
1183 goto err;
1184 }
1185 attribute_data_to_stat(&info, result);
1186 }
1187 }
1188 else {
1189 code = win32_xstat_for_handle(hFile, result, traverse, depth);
1190 CloseHandle(hFile);
1191 if (code != 0)
1192 return code;
1193 }
1194
1195 /* Set S_IEXEC if it is an .exe, .bat, ... */
1196 dot = wcsrchr(path, '.');
1197 if (dot) {
1198 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1199 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1200 result->st_mode |= 0111;
1201 }
1202 return 0;
1203
1204err:
1205 /* Protocol violation: we explicitly clear errno, instead of
1206 setting it to a POSIX error. Callers should use GetLastError. */
1207 errno = 0;
1208 return -1;
1209}
1210
1211static int
1212win32_xstat_for_handle(HANDLE hFile, struct win32_stat *result, BOOL traverse, int depth)
1213{
1214 int code;
1215 BOOL reparse_tag;
1216 wchar_t *target_path;
1217 BY_HANDLE_FILE_INFORMATION info;
1218
1219 if (!GetFileInformationByHandle(hFile, &info))
1220 return -1;
1221
1222 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1223 if (traverse) {
1224 if (depth + 1 > SYMLOOP_MAX) {
1225 SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */
1226 return -1;
1227 }
1228 if (!_Py_ReadLink(hFile, NULL, &target_path))
1229 return -1;
1230 code = win32_xstat_w(target_path, result, traverse, depth + 1);
1231 free(target_path);
1232 return code;
1233 } else {
1234 if (!_Py_ReadLink(hFile, &reparse_tag, NULL))
1235 return -1;
1236 attribute_data_to_stat(&info, result);
1237 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1238 /* first clear the S_IFMT bits */
1239 result->st_mode ^= (result->st_mode & 0170000);
1240 /* now set the bits that make this a symlink */
1241 result->st_mode |= 0120000;
1242 }
1243 }
1244 } else {
1245 attribute_data_to_stat(&info, result);
1246 }
1247 return 0;
1248}
1249
Brian Curtind40e6f72010-07-08 21:39:08 +00001250/* About the following functions: win32_lstat, win32_lstat_w, win32_stat,
1251 win32_stat_w
1252
1253 In Posix, stat automatically traverses symlinks and returns the stat
1254 structure for the target. In Windows, the equivalent GetFileAttributes by
1255 default does not traverse symlinks and instead returns attributes for
1256 the symlink.
1257
1258 Therefore, win32_lstat will get the attributes traditionally, and
1259 win32_stat will first explicitly resolve the symlink target and then will
1260 call win32_lstat on that result.
1261
1262 The _w represent Unicode equivalents of the aformentioned ANSI functions. */
1263
1264static int
1265win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001266{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001267 return win32_xstat(path, result, FALSE, 0);
Martin v. Löwis14694662006-02-03 12:54:16 +00001268}
1269
Victor Stinner8c62be82010-05-06 00:08:46 +00001270static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001271win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001272{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001273 return win32_xstat_w(path, result, FALSE, 0);
Brian Curtind40e6f72010-07-08 21:39:08 +00001274}
1275
1276static int
1277win32_stat(const char* path, struct win32_stat *result)
1278{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001279 return win32_xstat(path, result, TRUE, 0);
Brian Curtind40e6f72010-07-08 21:39:08 +00001280}
1281
1282static int
1283win32_stat_w(const wchar_t* path, struct win32_stat *result)
1284{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001285 return win32_xstat_w(path, result, TRUE, 0);
Martin v. Löwis14694662006-02-03 12:54:16 +00001286}
1287
1288static int
1289win32_fstat(int file_number, struct win32_stat *result)
1290{
Victor Stinner8c62be82010-05-06 00:08:46 +00001291 BY_HANDLE_FILE_INFORMATION info;
1292 HANDLE h;
1293 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001294
Victor Stinner8c62be82010-05-06 00:08:46 +00001295 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001296
Victor Stinner8c62be82010-05-06 00:08:46 +00001297 /* Protocol violation: we explicitly clear errno, instead of
1298 setting it to a POSIX error. Callers should use GetLastError. */
1299 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001300
Victor Stinner8c62be82010-05-06 00:08:46 +00001301 if (h == INVALID_HANDLE_VALUE) {
1302 /* This is really a C library error (invalid file handle).
1303 We set the Win32 error to the closes one matching. */
1304 SetLastError(ERROR_INVALID_HANDLE);
1305 return -1;
1306 }
1307 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001308
Victor Stinner8c62be82010-05-06 00:08:46 +00001309 type = GetFileType(h);
1310 if (type == FILE_TYPE_UNKNOWN) {
1311 DWORD error = GetLastError();
1312 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001313 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001314 }
1315 /* else: valid but unknown file */
1316 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001317
Victor Stinner8c62be82010-05-06 00:08:46 +00001318 if (type != FILE_TYPE_DISK) {
1319 if (type == FILE_TYPE_CHAR)
1320 result->st_mode = _S_IFCHR;
1321 else if (type == FILE_TYPE_PIPE)
1322 result->st_mode = _S_IFIFO;
1323 return 0;
1324 }
1325
1326 if (!GetFileInformationByHandle(h, &info)) {
1327 return -1;
1328 }
1329
Brian Curtinf5e76d02010-11-24 13:14:05 +00001330 attribute_data_to_stat(&info, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001331 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001332 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1333 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001334}
1335
1336#endif /* MS_WINDOWS */
1337
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001338PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001339"stat_result: Result from stat or lstat.\n\n\
1340This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001341 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001342or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1343\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001344Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1345or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001346\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001347See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001348
1349static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001350 {"st_mode", "protection bits"},
1351 {"st_ino", "inode"},
1352 {"st_dev", "device"},
1353 {"st_nlink", "number of hard links"},
1354 {"st_uid", "user ID of owner"},
1355 {"st_gid", "group ID of owner"},
1356 {"st_size", "total size, in bytes"},
1357 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1358 {NULL, "integer time of last access"},
1359 {NULL, "integer time of last modification"},
1360 {NULL, "integer time of last change"},
1361 {"st_atime", "time of last access"},
1362 {"st_mtime", "time of last modification"},
1363 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001364#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001365 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001366#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001367#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001368 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001369#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001370#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001371 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001372#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001373#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001374 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001375#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001376#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001377 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001378#endif
1379#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001380 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001381#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001382 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001383};
1384
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001385#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001386#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001387#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001388#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001389#endif
1390
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001391#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001392#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1393#else
1394#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1395#endif
1396
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001397#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001398#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1399#else
1400#define ST_RDEV_IDX ST_BLOCKS_IDX
1401#endif
1402
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001403#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1404#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1405#else
1406#define ST_FLAGS_IDX ST_RDEV_IDX
1407#endif
1408
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001409#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001410#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001411#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001412#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001413#endif
1414
1415#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1416#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1417#else
1418#define ST_BIRTHTIME_IDX ST_GEN_IDX
1419#endif
1420
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001421static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001422 "stat_result", /* name */
1423 stat_result__doc__, /* doc */
1424 stat_result_fields,
1425 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001426};
1427
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001428PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001429"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1430This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001431 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001432or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001433\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001434See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001435
1436static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001437 {"f_bsize", },
1438 {"f_frsize", },
1439 {"f_blocks", },
1440 {"f_bfree", },
1441 {"f_bavail", },
1442 {"f_files", },
1443 {"f_ffree", },
1444 {"f_favail", },
1445 {"f_flag", },
1446 {"f_namemax",},
1447 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001448};
1449
1450static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001451 "statvfs_result", /* name */
1452 statvfs_result__doc__, /* doc */
1453 statvfs_result_fields,
1454 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001455};
1456
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001457static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001458static PyTypeObject StatResultType;
1459static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001460static newfunc structseq_new;
1461
1462static PyObject *
1463statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1464{
Victor Stinner8c62be82010-05-06 00:08:46 +00001465 PyStructSequence *result;
1466 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001467
Victor Stinner8c62be82010-05-06 00:08:46 +00001468 result = (PyStructSequence*)structseq_new(type, args, kwds);
1469 if (!result)
1470 return NULL;
1471 /* If we have been initialized from a tuple,
1472 st_?time might be set to None. Initialize it
1473 from the int slots. */
1474 for (i = 7; i <= 9; i++) {
1475 if (result->ob_item[i+3] == Py_None) {
1476 Py_DECREF(Py_None);
1477 Py_INCREF(result->ob_item[i]);
1478 result->ob_item[i+3] = result->ob_item[i];
1479 }
1480 }
1481 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001482}
1483
1484
1485
1486/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001487static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001488
1489PyDoc_STRVAR(stat_float_times__doc__,
1490"stat_float_times([newval]) -> oldval\n\n\
1491Determine whether os.[lf]stat represents time stamps as float objects.\n\
1492If newval is True, future calls to stat() return floats, if it is False,\n\
1493future calls return ints. \n\
1494If newval is omitted, return the current setting.\n");
1495
1496static PyObject*
1497stat_float_times(PyObject* self, PyObject *args)
1498{
Victor Stinner8c62be82010-05-06 00:08:46 +00001499 int newval = -1;
1500 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1501 return NULL;
1502 if (newval == -1)
1503 /* Return old value */
1504 return PyBool_FromLong(_stat_float_times);
1505 _stat_float_times = newval;
1506 Py_INCREF(Py_None);
1507 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001508}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001509
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001510static void
1511fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1512{
Victor Stinner8c62be82010-05-06 00:08:46 +00001513 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001514#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001515 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001516#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001517 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001518#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001519 if (!ival)
1520 return;
1521 if (_stat_float_times) {
1522 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1523 } else {
1524 fval = ival;
1525 Py_INCREF(fval);
1526 }
1527 PyStructSequence_SET_ITEM(v, index, ival);
1528 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001529}
1530
Tim Peters5aa91602002-01-30 05:46:57 +00001531/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001532 (used by posix_stat() and posix_fstat()) */
1533static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001534_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001535{
Victor Stinner8c62be82010-05-06 00:08:46 +00001536 unsigned long ansec, mnsec, cnsec;
1537 PyObject *v = PyStructSequence_New(&StatResultType);
1538 if (v == NULL)
1539 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001540
Victor Stinner8c62be82010-05-06 00:08:46 +00001541 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001542#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001543 PyStructSequence_SET_ITEM(v, 1,
1544 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001545#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001546 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001547#endif
1548#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001549 PyStructSequence_SET_ITEM(v, 2,
1550 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001551#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001552 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001553#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001554 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1555 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1556 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001557#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001558 PyStructSequence_SET_ITEM(v, 6,
1559 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001560#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001561 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001562#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001563
Martin v. Löwis14694662006-02-03 12:54:16 +00001564#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001565 ansec = st->st_atim.tv_nsec;
1566 mnsec = st->st_mtim.tv_nsec;
1567 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001568#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001569 ansec = st->st_atimespec.tv_nsec;
1570 mnsec = st->st_mtimespec.tv_nsec;
1571 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001572#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001573 ansec = st->st_atime_nsec;
1574 mnsec = st->st_mtime_nsec;
1575 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001576#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001577 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001578#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001579 fill_time(v, 7, st->st_atime, ansec);
1580 fill_time(v, 8, st->st_mtime, mnsec);
1581 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001582
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001583#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001584 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1585 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001586#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001587#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001588 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1589 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001590#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001591#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001592 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1593 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001594#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001595#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001596 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1597 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001598#endif
1599#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001600 {
1601 PyObject *val;
1602 unsigned long bsec,bnsec;
1603 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001604#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001605 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001606#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001607 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001608#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001609 if (_stat_float_times) {
1610 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1611 } else {
1612 val = PyLong_FromLong((long)bsec);
1613 }
1614 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1615 val);
1616 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001617#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001618#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001619 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1620 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001621#endif
Fred Drake699f3522000-06-29 21:12:41 +00001622
Victor Stinner8c62be82010-05-06 00:08:46 +00001623 if (PyErr_Occurred()) {
1624 Py_DECREF(v);
1625 return NULL;
1626 }
Fred Drake699f3522000-06-29 21:12:41 +00001627
Victor Stinner8c62be82010-05-06 00:08:46 +00001628 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001629}
1630
Barry Warsaw53699e91996-12-10 23:23:01 +00001631static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001632posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001633 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001634#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001635 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001636#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001637 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001638#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001639 char *wformat,
1640 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001641{
Victor Stinner8c62be82010-05-06 00:08:46 +00001642 STRUCT_STAT st;
1643 PyObject *opath;
1644 char *path;
1645 int res;
1646 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001647
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001648#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001649 PyUnicodeObject *po;
1650 if (PyArg_ParseTuple(args, wformat, &po)) {
1651 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001652
Victor Stinner8c62be82010-05-06 00:08:46 +00001653 Py_BEGIN_ALLOW_THREADS
1654 /* PyUnicode_AS_UNICODE result OK without
1655 thread lock as it is a simple dereference. */
1656 res = wstatfunc(wpath, &st);
1657 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001658
Victor Stinner8c62be82010-05-06 00:08:46 +00001659 if (res != 0)
1660 return win32_error_unicode("stat", wpath);
1661 return _pystat_fromstructstat(&st);
1662 }
1663 /* Drop the argument parsing error as narrow strings
1664 are also valid. */
1665 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001666#endif
1667
Victor Stinner8c62be82010-05-06 00:08:46 +00001668 if (!PyArg_ParseTuple(args, format,
1669 PyUnicode_FSConverter, &opath))
1670 return NULL;
1671 path = PyBytes_AsString(opath);
1672 Py_BEGIN_ALLOW_THREADS
1673 res = (*statfunc)(path, &st);
1674 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001675
Victor Stinner8c62be82010-05-06 00:08:46 +00001676 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001677#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001678 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001679#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001680 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001681#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001682 }
1683 else
1684 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001685
Victor Stinner8c62be82010-05-06 00:08:46 +00001686 Py_DECREF(opath);
1687 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001688}
1689
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001690/* POSIX methods */
1691
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001692PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001693"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001694Use the real uid/gid to test for access to a path. Note that most\n\
1695operations will use the effective uid/gid, therefore this routine can\n\
1696be used in a suid/sgid environment to test if the invoking user has the\n\
1697specified access to the path. The mode argument can be F_OK to test\n\
1698existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001699
1700static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001701posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001702{
Victor Stinner8c62be82010-05-06 00:08:46 +00001703 PyObject *opath;
1704 char *path;
1705 int mode;
1706
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001707#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001708 DWORD attr;
1709 PyUnicodeObject *po;
1710 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1711 Py_BEGIN_ALLOW_THREADS
1712 /* PyUnicode_AS_UNICODE OK without thread lock as
1713 it is a simple dereference. */
1714 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1715 Py_END_ALLOW_THREADS
1716 goto finish;
1717 }
1718 /* Drop the argument parsing error as narrow strings
1719 are also valid. */
1720 PyErr_Clear();
1721 if (!PyArg_ParseTuple(args, "O&i:access",
1722 PyUnicode_FSConverter, &opath, &mode))
1723 return NULL;
1724 path = PyBytes_AsString(opath);
1725 Py_BEGIN_ALLOW_THREADS
1726 attr = GetFileAttributesA(path);
1727 Py_END_ALLOW_THREADS
1728 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001729finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001730 if (attr == 0xFFFFFFFF)
1731 /* File does not exist, or cannot read attributes */
1732 return PyBool_FromLong(0);
1733 /* Access is possible if either write access wasn't requested, or
1734 the file isn't read-only, or if it's a directory, as there are
1735 no read-only directories on Windows. */
1736 return PyBool_FromLong(!(mode & 2)
1737 || !(attr & FILE_ATTRIBUTE_READONLY)
1738 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001739#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001740 int res;
1741 if (!PyArg_ParseTuple(args, "O&i:access",
1742 PyUnicode_FSConverter, &opath, &mode))
1743 return NULL;
1744 path = PyBytes_AsString(opath);
1745 Py_BEGIN_ALLOW_THREADS
1746 res = access(path, mode);
1747 Py_END_ALLOW_THREADS
1748 Py_DECREF(opath);
1749 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001750#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001751}
1752
Guido van Rossumd371ff11999-01-25 16:12:23 +00001753#ifndef F_OK
1754#define F_OK 0
1755#endif
1756#ifndef R_OK
1757#define R_OK 4
1758#endif
1759#ifndef W_OK
1760#define W_OK 2
1761#endif
1762#ifndef X_OK
1763#define X_OK 1
1764#endif
1765
1766#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001767PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001768"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001769Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001770
1771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001772posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001773{
Victor Stinner8c62be82010-05-06 00:08:46 +00001774 int id;
1775 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001776
Victor Stinner8c62be82010-05-06 00:08:46 +00001777 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1778 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001779
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001780#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001781 /* file descriptor 0 only, the default input device (stdin) */
1782 if (id == 0) {
1783 ret = ttyname();
1784 }
1785 else {
1786 ret = NULL;
1787 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001788#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001789 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001790#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001791 if (ret == NULL)
1792 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001793 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001794}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001795#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001796
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001797#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001798PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001799"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001800Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001801
1802static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001803posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001804{
Victor Stinner8c62be82010-05-06 00:08:46 +00001805 char *ret;
1806 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001807
Greg Wardb48bc172000-03-01 21:51:56 +00001808#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001809 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001810#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001811 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001812#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001813 if (ret == NULL)
1814 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001815 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001816}
1817#endif
1818
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001819PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001820"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001821Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001822
Barry Warsaw53699e91996-12-10 23:23:01 +00001823static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001824posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001825{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001826#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001827 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001828#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001829 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001830#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001831 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001832#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001833 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001834#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001835}
1836
Fred Drake4d1e64b2002-04-15 19:40:07 +00001837#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001838PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001839"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001840Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001841opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001842
1843static PyObject *
1844posix_fchdir(PyObject *self, PyObject *fdobj)
1845{
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001847}
1848#endif /* HAVE_FCHDIR */
1849
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001850
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001851PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001852"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001853Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001854
Barry Warsaw53699e91996-12-10 23:23:01 +00001855static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001856posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001857{
Victor Stinner8c62be82010-05-06 00:08:46 +00001858 PyObject *opath = NULL;
1859 char *path = NULL;
1860 int i;
1861 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001862#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001863 DWORD attr;
1864 PyUnicodeObject *po;
1865 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1866 Py_BEGIN_ALLOW_THREADS
1867 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1868 if (attr != 0xFFFFFFFF) {
1869 if (i & _S_IWRITE)
1870 attr &= ~FILE_ATTRIBUTE_READONLY;
1871 else
1872 attr |= FILE_ATTRIBUTE_READONLY;
1873 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1874 }
1875 else
1876 res = 0;
1877 Py_END_ALLOW_THREADS
1878 if (!res)
1879 return win32_error_unicode("chmod",
1880 PyUnicode_AS_UNICODE(po));
1881 Py_INCREF(Py_None);
1882 return Py_None;
1883 }
1884 /* Drop the argument parsing error as narrow strings
1885 are also valid. */
1886 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001887
Victor Stinner8c62be82010-05-06 00:08:46 +00001888 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1889 &opath, &i))
1890 return NULL;
1891 path = PyBytes_AsString(opath);
1892 Py_BEGIN_ALLOW_THREADS
1893 attr = GetFileAttributesA(path);
1894 if (attr != 0xFFFFFFFF) {
1895 if (i & _S_IWRITE)
1896 attr &= ~FILE_ATTRIBUTE_READONLY;
1897 else
1898 attr |= FILE_ATTRIBUTE_READONLY;
1899 res = SetFileAttributesA(path, attr);
1900 }
1901 else
1902 res = 0;
1903 Py_END_ALLOW_THREADS
1904 if (!res) {
1905 win32_error("chmod", path);
1906 Py_DECREF(opath);
1907 return NULL;
1908 }
1909 Py_DECREF(opath);
1910 Py_INCREF(Py_None);
1911 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001912#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00001913 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1914 &opath, &i))
1915 return NULL;
1916 path = PyBytes_AsString(opath);
1917 Py_BEGIN_ALLOW_THREADS
1918 res = chmod(path, i);
1919 Py_END_ALLOW_THREADS
1920 if (res < 0)
1921 return posix_error_with_allocated_filename(opath);
1922 Py_DECREF(opath);
1923 Py_INCREF(Py_None);
1924 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001925#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001926}
1927
Christian Heimes4e30a842007-11-30 22:12:06 +00001928#ifdef HAVE_FCHMOD
1929PyDoc_STRVAR(posix_fchmod__doc__,
1930"fchmod(fd, mode)\n\n\
1931Change the access permissions of the file given by file\n\
1932descriptor fd.");
1933
1934static PyObject *
1935posix_fchmod(PyObject *self, PyObject *args)
1936{
Victor Stinner8c62be82010-05-06 00:08:46 +00001937 int fd, mode, res;
1938 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1939 return NULL;
1940 Py_BEGIN_ALLOW_THREADS
1941 res = fchmod(fd, mode);
1942 Py_END_ALLOW_THREADS
1943 if (res < 0)
1944 return posix_error();
1945 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001946}
1947#endif /* HAVE_FCHMOD */
1948
1949#ifdef HAVE_LCHMOD
1950PyDoc_STRVAR(posix_lchmod__doc__,
1951"lchmod(path, mode)\n\n\
1952Change the access permissions of a file. If path is a symlink, this\n\
1953affects the link itself rather than the target.");
1954
1955static PyObject *
1956posix_lchmod(PyObject *self, PyObject *args)
1957{
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 PyObject *opath;
1959 char *path;
1960 int i;
1961 int res;
1962 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1963 &opath, &i))
1964 return NULL;
1965 path = PyBytes_AsString(opath);
1966 Py_BEGIN_ALLOW_THREADS
1967 res = lchmod(path, i);
1968 Py_END_ALLOW_THREADS
1969 if (res < 0)
1970 return posix_error_with_allocated_filename(opath);
1971 Py_DECREF(opath);
1972 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001973}
1974#endif /* HAVE_LCHMOD */
1975
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001976
Thomas Wouterscf297e42007-02-23 15:07:44 +00001977#ifdef HAVE_CHFLAGS
1978PyDoc_STRVAR(posix_chflags__doc__,
1979"chflags(path, flags)\n\n\
1980Set file flags.");
1981
1982static PyObject *
1983posix_chflags(PyObject *self, PyObject *args)
1984{
Victor Stinner8c62be82010-05-06 00:08:46 +00001985 PyObject *opath;
1986 char *path;
1987 unsigned long flags;
1988 int res;
1989 if (!PyArg_ParseTuple(args, "O&k:chflags",
1990 PyUnicode_FSConverter, &opath, &flags))
1991 return NULL;
1992 path = PyBytes_AsString(opath);
1993 Py_BEGIN_ALLOW_THREADS
1994 res = chflags(path, flags);
1995 Py_END_ALLOW_THREADS
1996 if (res < 0)
1997 return posix_error_with_allocated_filename(opath);
1998 Py_DECREF(opath);
1999 Py_INCREF(Py_None);
2000 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002001}
2002#endif /* HAVE_CHFLAGS */
2003
2004#ifdef HAVE_LCHFLAGS
2005PyDoc_STRVAR(posix_lchflags__doc__,
2006"lchflags(path, flags)\n\n\
2007Set file flags.\n\
2008This function will not follow symbolic links.");
2009
2010static PyObject *
2011posix_lchflags(PyObject *self, PyObject *args)
2012{
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 PyObject *opath;
2014 char *path;
2015 unsigned long flags;
2016 int res;
2017 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2018 PyUnicode_FSConverter, &opath, &flags))
2019 return NULL;
2020 path = PyBytes_AsString(opath);
2021 Py_BEGIN_ALLOW_THREADS
2022 res = lchflags(path, flags);
2023 Py_END_ALLOW_THREADS
2024 if (res < 0)
2025 return posix_error_with_allocated_filename(opath);
2026 Py_DECREF(opath);
2027 Py_INCREF(Py_None);
2028 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002029}
2030#endif /* HAVE_LCHFLAGS */
2031
Martin v. Löwis244edc82001-10-04 22:44:26 +00002032#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002033PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002034"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002035Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002036
2037static PyObject *
2038posix_chroot(PyObject *self, PyObject *args)
2039{
Victor Stinner8c62be82010-05-06 00:08:46 +00002040 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002041}
2042#endif
2043
Guido van Rossum21142a01999-01-08 21:05:37 +00002044#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002045PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002046"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002047force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002048
2049static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002050posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002051{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002052 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002053}
2054#endif /* HAVE_FSYNC */
2055
2056#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002057
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002058#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002059extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2060#endif
2061
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002062PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002063"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002064force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002065 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002066
2067static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002068posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002069{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002070 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002071}
2072#endif /* HAVE_FDATASYNC */
2073
2074
Fredrik Lundh10723342000-07-10 16:38:09 +00002075#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002076PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002077"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002078Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002079
Barry Warsaw53699e91996-12-10 23:23:01 +00002080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002081posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002082{
Victor Stinner8c62be82010-05-06 00:08:46 +00002083 PyObject *opath;
2084 char *path;
2085 long uid, gid;
2086 int res;
2087 if (!PyArg_ParseTuple(args, "O&ll:chown",
2088 PyUnicode_FSConverter, &opath,
2089 &uid, &gid))
2090 return NULL;
2091 path = PyBytes_AsString(opath);
2092 Py_BEGIN_ALLOW_THREADS
2093 res = chown(path, (uid_t) uid, (gid_t) gid);
2094 Py_END_ALLOW_THREADS
2095 if (res < 0)
2096 return posix_error_with_allocated_filename(opath);
2097 Py_DECREF(opath);
2098 Py_INCREF(Py_None);
2099 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002100}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002101#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002102
Christian Heimes4e30a842007-11-30 22:12:06 +00002103#ifdef HAVE_FCHOWN
2104PyDoc_STRVAR(posix_fchown__doc__,
2105"fchown(fd, uid, gid)\n\n\
2106Change the owner and group id of the file given by file descriptor\n\
2107fd to the numeric uid and gid.");
2108
2109static PyObject *
2110posix_fchown(PyObject *self, PyObject *args)
2111{
Victor Stinner8c62be82010-05-06 00:08:46 +00002112 int fd;
2113 long uid, gid;
2114 int res;
2115 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2116 return NULL;
2117 Py_BEGIN_ALLOW_THREADS
2118 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2119 Py_END_ALLOW_THREADS
2120 if (res < 0)
2121 return posix_error();
2122 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002123}
2124#endif /* HAVE_FCHOWN */
2125
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002126#ifdef HAVE_LCHOWN
2127PyDoc_STRVAR(posix_lchown__doc__,
2128"lchown(path, uid, gid)\n\n\
2129Change the owner and group id of path to the numeric uid and gid.\n\
2130This function will not follow symbolic links.");
2131
2132static PyObject *
2133posix_lchown(PyObject *self, PyObject *args)
2134{
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 PyObject *opath;
2136 char *path;
2137 long uid, gid;
2138 int res;
2139 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2140 PyUnicode_FSConverter, &opath,
2141 &uid, &gid))
2142 return NULL;
2143 path = PyBytes_AsString(opath);
2144 Py_BEGIN_ALLOW_THREADS
2145 res = lchown(path, (uid_t) uid, (gid_t) gid);
2146 Py_END_ALLOW_THREADS
2147 if (res < 0)
2148 return posix_error_with_allocated_filename(opath);
2149 Py_DECREF(opath);
2150 Py_INCREF(Py_None);
2151 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002152}
2153#endif /* HAVE_LCHOWN */
2154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002155
Guido van Rossum36bc6801995-06-14 22:54:23 +00002156#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002157static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002158posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002159{
Victor Stinner8c62be82010-05-06 00:08:46 +00002160 char buf[1026];
2161 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002162
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002163#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002164 if (!use_bytes) {
2165 wchar_t wbuf[1026];
2166 wchar_t *wbuf2 = wbuf;
2167 PyObject *resobj;
2168 DWORD len;
2169 Py_BEGIN_ALLOW_THREADS
2170 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2171 /* If the buffer is large enough, len does not include the
2172 terminating \0. If the buffer is too small, len includes
2173 the space needed for the terminator. */
2174 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2175 wbuf2 = malloc(len * sizeof(wchar_t));
2176 if (wbuf2)
2177 len = GetCurrentDirectoryW(len, wbuf2);
2178 }
2179 Py_END_ALLOW_THREADS
2180 if (!wbuf2) {
2181 PyErr_NoMemory();
2182 return NULL;
2183 }
2184 if (!len) {
2185 if (wbuf2 != wbuf) free(wbuf2);
2186 return win32_error("getcwdu", NULL);
2187 }
2188 resobj = PyUnicode_FromWideChar(wbuf2, len);
2189 if (wbuf2 != wbuf) free(wbuf2);
2190 return resobj;
2191 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002192#endif
2193
Victor Stinner8c62be82010-05-06 00:08:46 +00002194 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002195#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002196 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002197#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002198 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002199#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002200 Py_END_ALLOW_THREADS
2201 if (res == NULL)
2202 return posix_error();
2203 if (use_bytes)
2204 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002205 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002206}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002207
2208PyDoc_STRVAR(posix_getcwd__doc__,
2209"getcwd() -> path\n\n\
2210Return a unicode string representing the current working directory.");
2211
2212static PyObject *
2213posix_getcwd_unicode(PyObject *self)
2214{
2215 return posix_getcwd(0);
2216}
2217
2218PyDoc_STRVAR(posix_getcwdb__doc__,
2219"getcwdb() -> path\n\n\
2220Return a bytes string representing the current working directory.");
2221
2222static PyObject *
2223posix_getcwd_bytes(PyObject *self)
2224{
2225 return posix_getcwd(1);
2226}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002227#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002228
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002229
Guido van Rossumb6775db1994-08-01 11:34:53 +00002230#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002231PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002232"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002233Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002234
Barry Warsaw53699e91996-12-10 23:23:01 +00002235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002236posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002237{
Victor Stinner8c62be82010-05-06 00:08:46 +00002238 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002239}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002240#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002241
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002242
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002243PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002244"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002245Return a list containing the names of the entries in the directory.\n\
2246\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002247 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002248\n\
2249The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002250entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002251
Barry Warsaw53699e91996-12-10 23:23:01 +00002252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002253posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002254{
Victor Stinner8c62be82010-05-06 00:08:46 +00002255 /* XXX Should redo this putting the (now four) versions of opendir
2256 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002257#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002258
Victor Stinner8c62be82010-05-06 00:08:46 +00002259 PyObject *d, *v;
2260 HANDLE hFindFile;
2261 BOOL result;
2262 WIN32_FIND_DATA FileData;
2263 PyObject *opath;
2264 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2265 char *bufptr = namebuf;
2266 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002267
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002268 PyObject *po = NULL;
2269 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002270 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002271 Py_UNICODE *wnamebuf, *po_wchars;
2272
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002273 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002274 po_wchars = L".";
2275 len = 1;
2276 } else {
2277 po_wchars = PyUnicode_AS_UNICODE(po);
2278 len = PyUnicode_GET_SIZE(po);
2279 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002280 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002281 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2282 if (!wnamebuf) {
2283 PyErr_NoMemory();
2284 return NULL;
2285 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002286 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002287 if (len > 0) {
2288 Py_UNICODE wch = wnamebuf[len-1];
2289 if (wch != L'/' && wch != L'\\' && wch != L':')
2290 wnamebuf[len++] = L'\\';
2291 wcscpy(wnamebuf + len, L"*.*");
2292 }
2293 if ((d = PyList_New(0)) == NULL) {
2294 free(wnamebuf);
2295 return NULL;
2296 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002297 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002299 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002300 if (hFindFile == INVALID_HANDLE_VALUE) {
2301 int error = GetLastError();
2302 if (error == ERROR_FILE_NOT_FOUND) {
2303 free(wnamebuf);
2304 return d;
2305 }
2306 Py_DECREF(d);
2307 win32_error_unicode("FindFirstFileW", wnamebuf);
2308 free(wnamebuf);
2309 return NULL;
2310 }
2311 do {
2312 /* Skip over . and .. */
2313 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2314 wcscmp(wFileData.cFileName, L"..") != 0) {
2315 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2316 if (v == NULL) {
2317 Py_DECREF(d);
2318 d = NULL;
2319 break;
2320 }
2321 if (PyList_Append(d, v) != 0) {
2322 Py_DECREF(v);
2323 Py_DECREF(d);
2324 d = NULL;
2325 break;
2326 }
2327 Py_DECREF(v);
2328 }
2329 Py_BEGIN_ALLOW_THREADS
2330 result = FindNextFileW(hFindFile, &wFileData);
2331 Py_END_ALLOW_THREADS
2332 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2333 it got to the end of the directory. */
2334 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2335 Py_DECREF(d);
2336 win32_error_unicode("FindNextFileW", wnamebuf);
2337 FindClose(hFindFile);
2338 free(wnamebuf);
2339 return NULL;
2340 }
2341 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002342
Victor Stinner8c62be82010-05-06 00:08:46 +00002343 if (FindClose(hFindFile) == FALSE) {
2344 Py_DECREF(d);
2345 win32_error_unicode("FindClose", wnamebuf);
2346 free(wnamebuf);
2347 return NULL;
2348 }
2349 free(wnamebuf);
2350 return d;
2351 }
2352 /* Drop the argument parsing error as narrow strings
2353 are also valid. */
2354 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002355
Victor Stinner8c62be82010-05-06 00:08:46 +00002356 if (!PyArg_ParseTuple(args, "O&:listdir",
2357 PyUnicode_FSConverter, &opath))
2358 return NULL;
2359 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2360 PyErr_SetString(PyExc_ValueError, "path too long");
2361 Py_DECREF(opath);
2362 return NULL;
2363 }
2364 strcpy(namebuf, PyBytes_AsString(opath));
2365 len = PyObject_Size(opath);
2366 if (len > 0) {
2367 char ch = namebuf[len-1];
2368 if (ch != SEP && ch != ALTSEP && ch != ':')
2369 namebuf[len++] = '/';
2370 strcpy(namebuf + len, "*.*");
2371 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002372
Victor Stinner8c62be82010-05-06 00:08:46 +00002373 if ((d = PyList_New(0)) == NULL)
2374 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002375
Antoine Pitroub73caab2010-08-09 23:39:31 +00002376 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002377 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002378 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002379 if (hFindFile == INVALID_HANDLE_VALUE) {
2380 int error = GetLastError();
2381 if (error == ERROR_FILE_NOT_FOUND)
2382 return d;
2383 Py_DECREF(d);
2384 return win32_error("FindFirstFile", namebuf);
2385 }
2386 do {
2387 /* Skip over . and .. */
2388 if (strcmp(FileData.cFileName, ".") != 0 &&
2389 strcmp(FileData.cFileName, "..") != 0) {
2390 v = PyBytes_FromString(FileData.cFileName);
2391 if (v == NULL) {
2392 Py_DECREF(d);
2393 d = NULL;
2394 break;
2395 }
2396 if (PyList_Append(d, v) != 0) {
2397 Py_DECREF(v);
2398 Py_DECREF(d);
2399 d = NULL;
2400 break;
2401 }
2402 Py_DECREF(v);
2403 }
2404 Py_BEGIN_ALLOW_THREADS
2405 result = FindNextFile(hFindFile, &FileData);
2406 Py_END_ALLOW_THREADS
2407 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2408 it got to the end of the directory. */
2409 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2410 Py_DECREF(d);
2411 win32_error("FindNextFile", namebuf);
2412 FindClose(hFindFile);
2413 return NULL;
2414 }
2415 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002416
Victor Stinner8c62be82010-05-06 00:08:46 +00002417 if (FindClose(hFindFile) == FALSE) {
2418 Py_DECREF(d);
2419 return win32_error("FindClose", namebuf);
2420 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002421
Victor Stinner8c62be82010-05-06 00:08:46 +00002422 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002423
Tim Peters0bb44a42000-09-15 07:44:49 +00002424#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002425
2426#ifndef MAX_PATH
2427#define MAX_PATH CCHMAXPATH
2428#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002429 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002430 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002431 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002432 PyObject *d, *v;
2433 char namebuf[MAX_PATH+5];
2434 HDIR hdir = 1;
2435 ULONG srchcnt = 1;
2436 FILEFINDBUF3 ep;
2437 APIRET rc;
2438
Victor Stinner8c62be82010-05-06 00:08:46 +00002439 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002440 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002441 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002442 name = PyBytes_AsString(oname);
2443 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002444 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002445 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002446 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002447 return NULL;
2448 }
2449 strcpy(namebuf, name);
2450 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002451 if (*pt == ALTSEP)
2452 *pt = SEP;
2453 if (namebuf[len-1] != SEP)
2454 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002455 strcpy(namebuf + len, "*.*");
2456
Neal Norwitz6c913782007-10-14 03:23:09 +00002457 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002458 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002459 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002460 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002461
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002462 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2463 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002464 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002465 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2466 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2467 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002468
2469 if (rc != NO_ERROR) {
2470 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002471 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002472 }
2473
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002474 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002475 do {
2476 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002477 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002478 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002479
2480 strcpy(namebuf, ep.achName);
2481
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002482 /* Leave Case of Name Alone -- In Native Form */
2483 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002484
Christian Heimes72b710a2008-05-26 13:28:38 +00002485 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002486 if (v == NULL) {
2487 Py_DECREF(d);
2488 d = NULL;
2489 break;
2490 }
2491 if (PyList_Append(d, v) != 0) {
2492 Py_DECREF(v);
2493 Py_DECREF(d);
2494 d = NULL;
2495 break;
2496 }
2497 Py_DECREF(v);
2498 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2499 }
2500
Victor Stinnerdcb24032010-04-22 12:08:36 +00002501 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002502 return d;
2503#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002504 PyObject *oname;
2505 char *name;
2506 PyObject *d, *v;
2507 DIR *dirp;
2508 struct dirent *ep;
2509 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002510
Victor Stinner8c62be82010-05-06 00:08:46 +00002511 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002512 /* v is never read, so it does not need to be initialized yet. */
2513 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002514 arg_is_unicode = 0;
2515 PyErr_Clear();
2516 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002517 oname = NULL;
2518 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002519 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002520 if (oname == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002521 oname = PyBytes_FromString(".");
2522 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002523 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002524 Py_BEGIN_ALLOW_THREADS
2525 dirp = opendir(name);
2526 Py_END_ALLOW_THREADS
2527 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002528 return posix_error_with_allocated_filename(oname);
2529 }
2530 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002531 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002532 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002533 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002534 Py_DECREF(oname);
2535 return NULL;
2536 }
2537 for (;;) {
2538 errno = 0;
2539 Py_BEGIN_ALLOW_THREADS
2540 ep = readdir(dirp);
2541 Py_END_ALLOW_THREADS
2542 if (ep == NULL) {
2543 if (errno == 0) {
2544 break;
2545 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002546 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002547 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002548 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002549 Py_DECREF(d);
2550 return posix_error_with_allocated_filename(oname);
2551 }
2552 }
2553 if (ep->d_name[0] == '.' &&
2554 (NAMLEN(ep) == 1 ||
2555 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2556 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002557 if (arg_is_unicode)
2558 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2559 else
2560 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002561 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002562 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002563 break;
2564 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002565 if (PyList_Append(d, v) != 0) {
2566 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002567 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002568 break;
2569 }
2570 Py_DECREF(v);
2571 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002572 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002573 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002574 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002575 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002576
Victor Stinner8c62be82010-05-06 00:08:46 +00002577 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002578
Tim Peters0bb44a42000-09-15 07:44:49 +00002579#endif /* which OS */
2580} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002581
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002582#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002583/* A helper function for abspath on win32 */
2584static PyObject *
2585posix__getfullpathname(PyObject *self, PyObject *args)
2586{
Victor Stinner8c62be82010-05-06 00:08:46 +00002587 PyObject *opath;
2588 char *path;
2589 char outbuf[MAX_PATH*2];
2590 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002591#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002592 PyUnicodeObject *po;
2593 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2594 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2595 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2596 Py_UNICODE *wtemp;
2597 DWORD result;
2598 PyObject *v;
2599 result = GetFullPathNameW(wpath,
2600 sizeof(woutbuf)/sizeof(woutbuf[0]),
2601 woutbuf, &wtemp);
2602 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2603 woutbufp = malloc(result * sizeof(Py_UNICODE));
2604 if (!woutbufp)
2605 return PyErr_NoMemory();
2606 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2607 }
2608 if (result)
2609 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2610 else
2611 v = win32_error_unicode("GetFullPathNameW", wpath);
2612 if (woutbufp != woutbuf)
2613 free(woutbufp);
2614 return v;
2615 }
2616 /* Drop the argument parsing error as narrow strings
2617 are also valid. */
2618 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002619
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002620#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002621 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2622 PyUnicode_FSConverter, &opath))
2623 return NULL;
2624 path = PyBytes_AsString(opath);
2625 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2626 outbuf, &temp)) {
2627 win32_error("GetFullPathName", path);
2628 Py_DECREF(opath);
2629 return NULL;
2630 }
2631 Py_DECREF(opath);
2632 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2633 return PyUnicode_Decode(outbuf, strlen(outbuf),
2634 Py_FileSystemDefaultEncoding, NULL);
2635 }
2636 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002637} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002638
Brian Curtinf5e76d02010-11-24 13:14:05 +00002639/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
2640static int has_GetFinalPathNameByHandle = 0;
2641static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
2642 DWORD);
2643static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
2644 DWORD);
2645static int
2646check_GetFinalPathNameByHandle()
2647{
2648 HINSTANCE hKernel32;
2649 /* only recheck */
2650 if (!has_GetFinalPathNameByHandle)
2651 {
2652 hKernel32 = GetModuleHandle("KERNEL32");
2653 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
2654 "GetFinalPathNameByHandleA");
2655 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
2656 "GetFinalPathNameByHandleW");
2657 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
2658 Py_GetFinalPathNameByHandleW;
2659 }
2660 return has_GetFinalPathNameByHandle;
2661}
2662
Brian Curtind40e6f72010-07-08 21:39:08 +00002663/* A helper function for samepath on windows */
2664static PyObject *
2665posix__getfinalpathname(PyObject *self, PyObject *args)
2666{
2667 HANDLE hFile;
2668 int buf_size;
2669 wchar_t *target_path;
2670 int result_length;
2671 PyObject *result;
2672 wchar_t *path;
2673
Brian Curtin94622b02010-09-24 00:03:39 +00002674 if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) {
Brian Curtind40e6f72010-07-08 21:39:08 +00002675 return NULL;
2676 }
2677
2678 if(!check_GetFinalPathNameByHandle()) {
2679 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2680 NotImplementedError. */
2681 return PyErr_Format(PyExc_NotImplementedError,
2682 "GetFinalPathNameByHandle not available on this platform");
2683 }
2684
2685 hFile = CreateFileW(
2686 path,
2687 0, /* desired access */
2688 0, /* share mode */
2689 NULL, /* security attributes */
2690 OPEN_EXISTING,
2691 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2692 FILE_FLAG_BACKUP_SEMANTICS,
2693 NULL);
2694
2695 if(hFile == INVALID_HANDLE_VALUE) {
2696 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002697 return PyErr_Format(PyExc_RuntimeError,
2698 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002699 }
2700
2701 /* We have a good handle to the target, use it to determine the
2702 target path name. */
2703 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2704
2705 if(!buf_size)
2706 return win32_error_unicode("GetFinalPathNameByHandle", path);
2707
2708 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2709 if(!target_path)
2710 return PyErr_NoMemory();
2711
2712 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2713 buf_size, VOLUME_NAME_DOS);
2714 if(!result_length)
2715 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2716
2717 if(!CloseHandle(hFile))
2718 return win32_error_unicode("GetFinalPathNameByHandle", path);
2719
2720 target_path[result_length] = 0;
2721 result = PyUnicode_FromUnicode(target_path, result_length);
2722 free(target_path);
2723 return result;
2724
2725} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002726
2727static PyObject *
2728posix__getfileinformation(PyObject *self, PyObject *args)
2729{
2730 HANDLE hFile;
2731 BY_HANDLE_FILE_INFORMATION info;
2732 int fd;
2733
2734 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
2735 return NULL;
2736
2737 if (!_PyVerify_fd(fd)) {
2738 PyErr_SetString(PyExc_ValueError, "received invalid file descriptor");
2739 return NULL;
2740 }
2741
2742 hFile = (HANDLE)_get_osfhandle(fd);
2743 if (hFile == INVALID_HANDLE_VALUE)
2744 return win32_error("_getfileinformation", NULL);
2745
2746 if (!GetFileInformationByHandle(hFile, &info))
2747 return win32_error("_getfileinformation", NULL);
2748
2749 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
2750 info.nFileIndexHigh,
2751 info.nFileIndexLow);
2752}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002753#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002754
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002755PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002756"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002757Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002758
Barry Warsaw53699e91996-12-10 23:23:01 +00002759static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002760posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002761{
Victor Stinner8c62be82010-05-06 00:08:46 +00002762 int res;
2763 PyObject *opath;
2764 char *path;
2765 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002766
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002767#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002768 PyUnicodeObject *po;
2769 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2770 Py_BEGIN_ALLOW_THREADS
2771 /* PyUnicode_AS_UNICODE OK without thread lock as
2772 it is a simple dereference. */
2773 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2774 Py_END_ALLOW_THREADS
2775 if (!res)
2776 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2777 Py_INCREF(Py_None);
2778 return Py_None;
2779 }
2780 /* Drop the argument parsing error as narrow strings
2781 are also valid. */
2782 PyErr_Clear();
2783 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2784 PyUnicode_FSConverter, &opath, &mode))
2785 return NULL;
2786 path = PyBytes_AsString(opath);
2787 Py_BEGIN_ALLOW_THREADS
2788 /* PyUnicode_AS_UNICODE OK without thread lock as
2789 it is a simple dereference. */
2790 res = CreateDirectoryA(path, NULL);
2791 Py_END_ALLOW_THREADS
2792 if (!res) {
2793 win32_error("mkdir", path);
2794 Py_DECREF(opath);
2795 return NULL;
2796 }
2797 Py_DECREF(opath);
2798 Py_INCREF(Py_None);
2799 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002800#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002801
Victor Stinner8c62be82010-05-06 00:08:46 +00002802 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2803 PyUnicode_FSConverter, &opath, &mode))
2804 return NULL;
2805 path = PyBytes_AsString(opath);
2806 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002807#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002808 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002809#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002810 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002811#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002812 Py_END_ALLOW_THREADS
2813 if (res < 0)
2814 return posix_error_with_allocated_filename(opath);
2815 Py_DECREF(opath);
2816 Py_INCREF(Py_None);
2817 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002818#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002819}
2820
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002821
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002822/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2823#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002824#include <sys/resource.h>
2825#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002826
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002827
2828#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002829PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002830"nice(inc) -> new_priority\n\n\
2831Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002832
Barry Warsaw53699e91996-12-10 23:23:01 +00002833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002834posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002835{
Victor Stinner8c62be82010-05-06 00:08:46 +00002836 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002837
Victor Stinner8c62be82010-05-06 00:08:46 +00002838 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2839 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002840
Victor Stinner8c62be82010-05-06 00:08:46 +00002841 /* There are two flavours of 'nice': one that returns the new
2842 priority (as required by almost all standards out there) and the
2843 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2844 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002845
Victor Stinner8c62be82010-05-06 00:08:46 +00002846 If we are of the nice family that returns the new priority, we
2847 need to clear errno before the call, and check if errno is filled
2848 before calling posix_error() on a returnvalue of -1, because the
2849 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002850
Victor Stinner8c62be82010-05-06 00:08:46 +00002851 errno = 0;
2852 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002853#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00002854 if (value == 0)
2855 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002856#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002857 if (value == -1 && errno != 0)
2858 /* either nice() or getpriority() returned an error */
2859 return posix_error();
2860 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002861}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002862#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002863
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002864PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002865"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002866Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002867
Barry Warsaw53699e91996-12-10 23:23:01 +00002868static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002869posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002870{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002871#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002872 PyObject *o1, *o2;
2873 char *p1, *p2;
2874 BOOL result;
2875 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2876 goto error;
2877 if (!convert_to_unicode(&o1))
2878 goto error;
2879 if (!convert_to_unicode(&o2)) {
2880 Py_DECREF(o1);
2881 goto error;
2882 }
2883 Py_BEGIN_ALLOW_THREADS
2884 result = MoveFileW(PyUnicode_AsUnicode(o1),
2885 PyUnicode_AsUnicode(o2));
2886 Py_END_ALLOW_THREADS
2887 Py_DECREF(o1);
2888 Py_DECREF(o2);
2889 if (!result)
2890 return win32_error("rename", NULL);
2891 Py_INCREF(Py_None);
2892 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002893error:
Victor Stinner8c62be82010-05-06 00:08:46 +00002894 PyErr_Clear();
2895 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2896 return NULL;
2897 Py_BEGIN_ALLOW_THREADS
2898 result = MoveFileA(p1, p2);
2899 Py_END_ALLOW_THREADS
2900 if (!result)
2901 return win32_error("rename", NULL);
2902 Py_INCREF(Py_None);
2903 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002904#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002905 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002906#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002907}
2908
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002909
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002910PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002911"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002912Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002913
Barry Warsaw53699e91996-12-10 23:23:01 +00002914static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002915posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002916{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002917#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002919#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002920 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002921#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002922}
2923
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002924
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002925PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002926"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002927Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002928
Barry Warsaw53699e91996-12-10 23:23:01 +00002929static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002930posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002931{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002932#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00002933 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002934#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002935 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002936#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002937}
2938
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002939
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002940#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002941PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002942"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002943Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002944
Barry Warsaw53699e91996-12-10 23:23:01 +00002945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002946posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002947{
Victor Stinner8c62be82010-05-06 00:08:46 +00002948 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002949#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002950 wchar_t *command;
2951 if (!PyArg_ParseTuple(args, "u:system", &command))
2952 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002953
Victor Stinner8c62be82010-05-06 00:08:46 +00002954 Py_BEGIN_ALLOW_THREADS
2955 sts = _wsystem(command);
2956 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00002957#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002958 PyObject *command_obj;
2959 char *command;
2960 if (!PyArg_ParseTuple(args, "O&:system",
2961 PyUnicode_FSConverter, &command_obj))
2962 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002963
Victor Stinner8c62be82010-05-06 00:08:46 +00002964 command = PyBytes_AsString(command_obj);
2965 Py_BEGIN_ALLOW_THREADS
2966 sts = system(command);
2967 Py_END_ALLOW_THREADS
2968 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00002969#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002970 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002971}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002972#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002973
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002974
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002975PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002976"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002977Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002978
Barry Warsaw53699e91996-12-10 23:23:01 +00002979static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002980posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002981{
Victor Stinner8c62be82010-05-06 00:08:46 +00002982 int i;
2983 if (!PyArg_ParseTuple(args, "i:umask", &i))
2984 return NULL;
2985 i = (int)umask(i);
2986 if (i < 0)
2987 return posix_error();
2988 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002989}
2990
Brian Curtind40e6f72010-07-08 21:39:08 +00002991#ifdef MS_WINDOWS
2992
2993/* override the default DeleteFileW behavior so that directory
2994symlinks can be removed with this function, the same as with
2995Unix symlinks */
2996BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
2997{
2998 WIN32_FILE_ATTRIBUTE_DATA info;
2999 WIN32_FIND_DATAW find_data;
3000 HANDLE find_data_handle;
3001 int is_directory = 0;
3002 int is_link = 0;
3003
3004 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3005 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
3006
3007 /* Get WIN32_FIND_DATA structure for the path to determine if
3008 it is a symlink */
3009 if(is_directory &&
3010 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3011 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3012
3013 if(find_data_handle != INVALID_HANDLE_VALUE) {
3014 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3015 FindClose(find_data_handle);
3016 }
3017 }
3018 }
3019
3020 if (is_directory && is_link)
3021 return RemoveDirectoryW(lpFileName);
3022
3023 return DeleteFileW(lpFileName);
3024}
3025#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003026
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003027PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003028"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003029Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003030
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003031PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003032"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003033Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003034
Barry Warsaw53699e91996-12-10 23:23:01 +00003035static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003036posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003037{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003038#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003039 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3040 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003041#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003042 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003043#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003044}
3045
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003046
Guido van Rossumb6775db1994-08-01 11:34:53 +00003047#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003048PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003049"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003050Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003051
Barry Warsaw53699e91996-12-10 23:23:01 +00003052static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003053posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003054{
Victor Stinner8c62be82010-05-06 00:08:46 +00003055 struct utsname u;
3056 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003057
Victor Stinner8c62be82010-05-06 00:08:46 +00003058 Py_BEGIN_ALLOW_THREADS
3059 res = uname(&u);
3060 Py_END_ALLOW_THREADS
3061 if (res < 0)
3062 return posix_error();
3063 return Py_BuildValue("(sssss)",
3064 u.sysname,
3065 u.nodename,
3066 u.release,
3067 u.version,
3068 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003069}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003070#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003071
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003072static int
3073extract_time(PyObject *t, long* sec, long* usec)
3074{
Victor Stinner8c62be82010-05-06 00:08:46 +00003075 long intval;
3076 if (PyFloat_Check(t)) {
3077 double tval = PyFloat_AsDouble(t);
3078 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
3079 if (!intobj)
3080 return -1;
3081 intval = PyLong_AsLong(intobj);
3082 Py_DECREF(intobj);
3083 if (intval == -1 && PyErr_Occurred())
3084 return -1;
3085 *sec = intval;
3086 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3087 if (*usec < 0)
3088 /* If rounding gave us a negative number,
3089 truncate. */
3090 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003091 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003092 }
3093 intval = PyLong_AsLong(t);
3094 if (intval == -1 && PyErr_Occurred())
3095 return -1;
3096 *sec = intval;
3097 *usec = 0;
3098 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003099}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003100
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003101PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003102"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003103utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003104Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003105second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003106
Barry Warsaw53699e91996-12-10 23:23:01 +00003107static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003108posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003109{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003110#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003111 PyObject *arg;
3112 PyUnicodeObject *obwpath;
3113 wchar_t *wpath = NULL;
3114 PyObject *oapath;
3115 char *apath;
3116 HANDLE hFile;
3117 long atimesec, mtimesec, ausec, musec;
3118 FILETIME atime, mtime;
3119 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003120
Victor Stinner8c62be82010-05-06 00:08:46 +00003121 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3122 wpath = PyUnicode_AS_UNICODE(obwpath);
3123 Py_BEGIN_ALLOW_THREADS
3124 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3125 NULL, OPEN_EXISTING,
3126 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3127 Py_END_ALLOW_THREADS
3128 if (hFile == INVALID_HANDLE_VALUE)
3129 return win32_error_unicode("utime", wpath);
3130 } else
3131 /* Drop the argument parsing error as narrow strings
3132 are also valid. */
3133 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003134
Victor Stinner8c62be82010-05-06 00:08:46 +00003135 if (!wpath) {
3136 if (!PyArg_ParseTuple(args, "O&O:utime",
3137 PyUnicode_FSConverter, &oapath, &arg))
3138 return NULL;
3139 apath = PyBytes_AsString(oapath);
3140 Py_BEGIN_ALLOW_THREADS
3141 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3142 NULL, OPEN_EXISTING,
3143 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3144 Py_END_ALLOW_THREADS
3145 if (hFile == INVALID_HANDLE_VALUE) {
3146 win32_error("utime", apath);
3147 Py_DECREF(oapath);
3148 return NULL;
3149 }
3150 Py_DECREF(oapath);
3151 }
3152
3153 if (arg == Py_None) {
3154 SYSTEMTIME now;
3155 GetSystemTime(&now);
3156 if (!SystemTimeToFileTime(&now, &mtime) ||
3157 !SystemTimeToFileTime(&now, &atime)) {
3158 win32_error("utime", NULL);
3159 goto done;
3160 }
3161 }
3162 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3163 PyErr_SetString(PyExc_TypeError,
3164 "utime() arg 2 must be a tuple (atime, mtime)");
3165 goto done;
3166 }
3167 else {
3168 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3169 &atimesec, &ausec) == -1)
3170 goto done;
3171 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3172 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3173 &mtimesec, &musec) == -1)
3174 goto done;
3175 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3176 }
3177 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3178 /* Avoid putting the file name into the error here,
3179 as that may confuse the user into believing that
3180 something is wrong with the file, when it also
3181 could be the time stamp that gives a problem. */
3182 win32_error("utime", NULL);
3183 }
3184 Py_INCREF(Py_None);
3185 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003186done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003187 CloseHandle(hFile);
3188 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003189#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003190
Victor Stinner8c62be82010-05-06 00:08:46 +00003191 PyObject *opath;
3192 char *path;
3193 long atime, mtime, ausec, musec;
3194 int res;
3195 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003196
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003197#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003198 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003199#define ATIME buf[0].tv_sec
3200#define MTIME buf[1].tv_sec
3201#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003202/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003203 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003204#define ATIME buf.actime
3205#define MTIME buf.modtime
3206#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003207#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003208 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003209#define ATIME buf[0]
3210#define MTIME buf[1]
3211#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003212#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003213
Mark Hammond817c9292003-12-03 01:22:38 +00003214
Victor Stinner8c62be82010-05-06 00:08:46 +00003215 if (!PyArg_ParseTuple(args, "O&O:utime",
3216 PyUnicode_FSConverter, &opath, &arg))
3217 return NULL;
3218 path = PyBytes_AsString(opath);
3219 if (arg == Py_None) {
3220 /* optional time values not given */
3221 Py_BEGIN_ALLOW_THREADS
3222 res = utime(path, NULL);
3223 Py_END_ALLOW_THREADS
3224 }
3225 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3226 PyErr_SetString(PyExc_TypeError,
3227 "utime() arg 2 must be a tuple (atime, mtime)");
3228 Py_DECREF(opath);
3229 return NULL;
3230 }
3231 else {
3232 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3233 &atime, &ausec) == -1) {
3234 Py_DECREF(opath);
3235 return NULL;
3236 }
3237 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3238 &mtime, &musec) == -1) {
3239 Py_DECREF(opath);
3240 return NULL;
3241 }
3242 ATIME = atime;
3243 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003244#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003245 buf[0].tv_usec = ausec;
3246 buf[1].tv_usec = musec;
3247 Py_BEGIN_ALLOW_THREADS
3248 res = utimes(path, buf);
3249 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003250#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003251 Py_BEGIN_ALLOW_THREADS
3252 res = utime(path, UTIME_ARG);
3253 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003254#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003255 }
3256 if (res < 0) {
3257 return posix_error_with_allocated_filename(opath);
3258 }
3259 Py_DECREF(opath);
3260 Py_INCREF(Py_None);
3261 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003262#undef UTIME_ARG
3263#undef ATIME
3264#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003265#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003266}
3267
Guido van Rossum85e3b011991-06-03 12:42:10 +00003268
Guido van Rossum3b066191991-06-04 19:40:25 +00003269/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003270
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003271PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003272"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003273Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003274
Barry Warsaw53699e91996-12-10 23:23:01 +00003275static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003276posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003277{
Victor Stinner8c62be82010-05-06 00:08:46 +00003278 int sts;
3279 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3280 return NULL;
3281 _exit(sts);
3282 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003283}
3284
Martin v. Löwis114619e2002-10-07 06:44:21 +00003285#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3286static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003287free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003288{
Victor Stinner8c62be82010-05-06 00:08:46 +00003289 Py_ssize_t i;
3290 for (i = 0; i < count; i++)
3291 PyMem_Free(array[i]);
3292 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003293}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003294
Antoine Pitrou69f71142009-05-24 21:25:49 +00003295static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003296int fsconvert_strdup(PyObject *o, char**out)
3297{
Victor Stinner8c62be82010-05-06 00:08:46 +00003298 PyObject *bytes;
3299 Py_ssize_t size;
3300 if (!PyUnicode_FSConverter(o, &bytes))
3301 return 0;
3302 size = PyBytes_GET_SIZE(bytes);
3303 *out = PyMem_Malloc(size+1);
3304 if (!*out)
3305 return 0;
3306 memcpy(*out, PyBytes_AsString(bytes), size+1);
3307 Py_DECREF(bytes);
3308 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003309}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003310#endif
3311
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003312
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003313#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003314PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003315"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003316Execute an executable path with arguments, replacing current process.\n\
3317\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003318 path: path of executable file\n\
3319 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003320
Barry Warsaw53699e91996-12-10 23:23:01 +00003321static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003322posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003323{
Victor Stinner8c62be82010-05-06 00:08:46 +00003324 PyObject *opath;
3325 char *path;
3326 PyObject *argv;
3327 char **argvlist;
3328 Py_ssize_t i, argc;
3329 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003330
Victor Stinner8c62be82010-05-06 00:08:46 +00003331 /* execv has two arguments: (path, argv), where
3332 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003333
Victor Stinner8c62be82010-05-06 00:08:46 +00003334 if (!PyArg_ParseTuple(args, "O&O:execv",
3335 PyUnicode_FSConverter,
3336 &opath, &argv))
3337 return NULL;
3338 path = PyBytes_AsString(opath);
3339 if (PyList_Check(argv)) {
3340 argc = PyList_Size(argv);
3341 getitem = PyList_GetItem;
3342 }
3343 else if (PyTuple_Check(argv)) {
3344 argc = PyTuple_Size(argv);
3345 getitem = PyTuple_GetItem;
3346 }
3347 else {
3348 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3349 Py_DECREF(opath);
3350 return NULL;
3351 }
3352 if (argc < 1) {
3353 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3354 Py_DECREF(opath);
3355 return NULL;
3356 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003357
Victor Stinner8c62be82010-05-06 00:08:46 +00003358 argvlist = PyMem_NEW(char *, argc+1);
3359 if (argvlist == NULL) {
3360 Py_DECREF(opath);
3361 return PyErr_NoMemory();
3362 }
3363 for (i = 0; i < argc; i++) {
3364 if (!fsconvert_strdup((*getitem)(argv, i),
3365 &argvlist[i])) {
3366 free_string_array(argvlist, i);
3367 PyErr_SetString(PyExc_TypeError,
3368 "execv() arg 2 must contain only strings");
3369 Py_DECREF(opath);
3370 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003371
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 }
3373 }
3374 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003375
Victor Stinner8c62be82010-05-06 00:08:46 +00003376 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003377
Victor Stinner8c62be82010-05-06 00:08:46 +00003378 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003379
Victor Stinner8c62be82010-05-06 00:08:46 +00003380 free_string_array(argvlist, argc);
3381 Py_DECREF(opath);
3382 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003383}
3384
Victor Stinner13bb71c2010-04-23 21:41:56 +00003385static char**
3386parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3387{
Victor Stinner8c62be82010-05-06 00:08:46 +00003388 char **envlist;
3389 Py_ssize_t i, pos, envc;
3390 PyObject *keys=NULL, *vals=NULL;
3391 PyObject *key, *val, *key2, *val2;
3392 char *p, *k, *v;
3393 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003394
Victor Stinner8c62be82010-05-06 00:08:46 +00003395 i = PyMapping_Size(env);
3396 if (i < 0)
3397 return NULL;
3398 envlist = PyMem_NEW(char *, i + 1);
3399 if (envlist == NULL) {
3400 PyErr_NoMemory();
3401 return NULL;
3402 }
3403 envc = 0;
3404 keys = PyMapping_Keys(env);
3405 vals = PyMapping_Values(env);
3406 if (!keys || !vals)
3407 goto error;
3408 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3409 PyErr_Format(PyExc_TypeError,
3410 "env.keys() or env.values() is not a list");
3411 goto error;
3412 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003413
Victor Stinner8c62be82010-05-06 00:08:46 +00003414 for (pos = 0; pos < i; pos++) {
3415 key = PyList_GetItem(keys, pos);
3416 val = PyList_GetItem(vals, pos);
3417 if (!key || !val)
3418 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003419
Victor Stinner8c62be82010-05-06 00:08:46 +00003420 if (PyUnicode_FSConverter(key, &key2) == 0)
3421 goto error;
3422 if (PyUnicode_FSConverter(val, &val2) == 0) {
3423 Py_DECREF(key2);
3424 goto error;
3425 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003426
3427#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3429 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003430#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003431 k = PyBytes_AsString(key2);
3432 v = PyBytes_AsString(val2);
3433 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003434
Victor Stinner8c62be82010-05-06 00:08:46 +00003435 p = PyMem_NEW(char, len);
3436 if (p == NULL) {
3437 PyErr_NoMemory();
3438 Py_DECREF(key2);
3439 Py_DECREF(val2);
3440 goto error;
3441 }
3442 PyOS_snprintf(p, len, "%s=%s", k, v);
3443 envlist[envc++] = p;
3444 Py_DECREF(key2);
3445 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003446#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003447 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003448#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003449 }
3450 Py_DECREF(vals);
3451 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003452
Victor Stinner8c62be82010-05-06 00:08:46 +00003453 envlist[envc] = 0;
3454 *envc_ptr = envc;
3455 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003456
3457error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003458 Py_XDECREF(keys);
3459 Py_XDECREF(vals);
3460 while (--envc >= 0)
3461 PyMem_DEL(envlist[envc]);
3462 PyMem_DEL(envlist);
3463 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003464}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003465
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003466PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003467"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003468Execute a path with arguments and environment, replacing current process.\n\
3469\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003470 path: path of executable file\n\
3471 args: tuple or list of arguments\n\
3472 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003473
Barry Warsaw53699e91996-12-10 23:23:01 +00003474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003475posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003476{
Victor Stinner8c62be82010-05-06 00:08:46 +00003477 PyObject *opath;
3478 char *path;
3479 PyObject *argv, *env;
3480 char **argvlist;
3481 char **envlist;
3482 Py_ssize_t i, argc, envc;
3483 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3484 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003485
Victor Stinner8c62be82010-05-06 00:08:46 +00003486 /* execve has three arguments: (path, argv, env), where
3487 argv is a list or tuple of strings and env is a dictionary
3488 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003489
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 if (!PyArg_ParseTuple(args, "O&OO:execve",
3491 PyUnicode_FSConverter,
3492 &opath, &argv, &env))
3493 return NULL;
3494 path = PyBytes_AsString(opath);
3495 if (PyList_Check(argv)) {
3496 argc = PyList_Size(argv);
3497 getitem = PyList_GetItem;
3498 }
3499 else if (PyTuple_Check(argv)) {
3500 argc = PyTuple_Size(argv);
3501 getitem = PyTuple_GetItem;
3502 }
3503 else {
3504 PyErr_SetString(PyExc_TypeError,
3505 "execve() arg 2 must be a tuple or list");
3506 goto fail_0;
3507 }
3508 if (!PyMapping_Check(env)) {
3509 PyErr_SetString(PyExc_TypeError,
3510 "execve() arg 3 must be a mapping object");
3511 goto fail_0;
3512 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003513
Victor Stinner8c62be82010-05-06 00:08:46 +00003514 argvlist = PyMem_NEW(char *, argc+1);
3515 if (argvlist == NULL) {
3516 PyErr_NoMemory();
3517 goto fail_0;
3518 }
3519 for (i = 0; i < argc; i++) {
3520 if (!fsconvert_strdup((*getitem)(argv, i),
3521 &argvlist[i]))
3522 {
3523 lastarg = i;
3524 goto fail_1;
3525 }
3526 }
3527 lastarg = argc;
3528 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003529
Victor Stinner8c62be82010-05-06 00:08:46 +00003530 envlist = parse_envlist(env, &envc);
3531 if (envlist == NULL)
3532 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003533
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003535
Victor Stinner8c62be82010-05-06 00:08:46 +00003536 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003537
Victor Stinner8c62be82010-05-06 00:08:46 +00003538 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003539
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 while (--envc >= 0)
3541 PyMem_DEL(envlist[envc]);
3542 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003543 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003545 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 Py_DECREF(opath);
3547 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003548}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003549#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003550
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003551
Guido van Rossuma1065681999-01-25 23:20:23 +00003552#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003553PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003554"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003555Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003556\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 mode: mode of process creation\n\
3558 path: path of executable file\n\
3559 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003560
3561static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003562posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003563{
Victor Stinner8c62be82010-05-06 00:08:46 +00003564 PyObject *opath;
3565 char *path;
3566 PyObject *argv;
3567 char **argvlist;
3568 int mode, i;
3569 Py_ssize_t argc;
3570 Py_intptr_t spawnval;
3571 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003572
Victor Stinner8c62be82010-05-06 00:08:46 +00003573 /* spawnv has three arguments: (mode, path, argv), where
3574 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003575
Victor Stinner8c62be82010-05-06 00:08:46 +00003576 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3577 PyUnicode_FSConverter,
3578 &opath, &argv))
3579 return NULL;
3580 path = PyBytes_AsString(opath);
3581 if (PyList_Check(argv)) {
3582 argc = PyList_Size(argv);
3583 getitem = PyList_GetItem;
3584 }
3585 else if (PyTuple_Check(argv)) {
3586 argc = PyTuple_Size(argv);
3587 getitem = PyTuple_GetItem;
3588 }
3589 else {
3590 PyErr_SetString(PyExc_TypeError,
3591 "spawnv() arg 2 must be a tuple or list");
3592 Py_DECREF(opath);
3593 return NULL;
3594 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003595
Victor Stinner8c62be82010-05-06 00:08:46 +00003596 argvlist = PyMem_NEW(char *, argc+1);
3597 if (argvlist == NULL) {
3598 Py_DECREF(opath);
3599 return PyErr_NoMemory();
3600 }
3601 for (i = 0; i < argc; i++) {
3602 if (!fsconvert_strdup((*getitem)(argv, i),
3603 &argvlist[i])) {
3604 free_string_array(argvlist, i);
3605 PyErr_SetString(
3606 PyExc_TypeError,
3607 "spawnv() arg 2 must contain only strings");
3608 Py_DECREF(opath);
3609 return NULL;
3610 }
3611 }
3612 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003613
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003614#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003615 Py_BEGIN_ALLOW_THREADS
3616 spawnval = spawnv(mode, path, argvlist);
3617 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003618#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003619 if (mode == _OLD_P_OVERLAY)
3620 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003621
Victor Stinner8c62be82010-05-06 00:08:46 +00003622 Py_BEGIN_ALLOW_THREADS
3623 spawnval = _spawnv(mode, path, argvlist);
3624 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003625#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003626
Victor Stinner8c62be82010-05-06 00:08:46 +00003627 free_string_array(argvlist, argc);
3628 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003629
Victor Stinner8c62be82010-05-06 00:08:46 +00003630 if (spawnval == -1)
3631 return posix_error();
3632 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003633#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003634 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003635#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003636 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003637#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003638}
3639
3640
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003641PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003642"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003643Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003644\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 mode: mode of process creation\n\
3646 path: path of executable file\n\
3647 args: tuple or list of arguments\n\
3648 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003649
3650static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003651posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003652{
Victor Stinner8c62be82010-05-06 00:08:46 +00003653 PyObject *opath;
3654 char *path;
3655 PyObject *argv, *env;
3656 char **argvlist;
3657 char **envlist;
3658 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003659 int mode;
3660 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 Py_intptr_t spawnval;
3662 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3663 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003664
Victor Stinner8c62be82010-05-06 00:08:46 +00003665 /* spawnve has four arguments: (mode, path, argv, env), where
3666 argv is a list or tuple of strings and env is a dictionary
3667 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003668
Victor Stinner8c62be82010-05-06 00:08:46 +00003669 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3670 PyUnicode_FSConverter,
3671 &opath, &argv, &env))
3672 return NULL;
3673 path = PyBytes_AsString(opath);
3674 if (PyList_Check(argv)) {
3675 argc = PyList_Size(argv);
3676 getitem = PyList_GetItem;
3677 }
3678 else if (PyTuple_Check(argv)) {
3679 argc = PyTuple_Size(argv);
3680 getitem = PyTuple_GetItem;
3681 }
3682 else {
3683 PyErr_SetString(PyExc_TypeError,
3684 "spawnve() arg 2 must be a tuple or list");
3685 goto fail_0;
3686 }
3687 if (!PyMapping_Check(env)) {
3688 PyErr_SetString(PyExc_TypeError,
3689 "spawnve() arg 3 must be a mapping object");
3690 goto fail_0;
3691 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003692
Victor Stinner8c62be82010-05-06 00:08:46 +00003693 argvlist = PyMem_NEW(char *, argc+1);
3694 if (argvlist == NULL) {
3695 PyErr_NoMemory();
3696 goto fail_0;
3697 }
3698 for (i = 0; i < argc; i++) {
3699 if (!fsconvert_strdup((*getitem)(argv, i),
3700 &argvlist[i]))
3701 {
3702 lastarg = i;
3703 goto fail_1;
3704 }
3705 }
3706 lastarg = argc;
3707 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003708
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 envlist = parse_envlist(env, &envc);
3710 if (envlist == NULL)
3711 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003712
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003713#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003714 Py_BEGIN_ALLOW_THREADS
3715 spawnval = spawnve(mode, path, argvlist, envlist);
3716 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003717#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003718 if (mode == _OLD_P_OVERLAY)
3719 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003720
Victor Stinner8c62be82010-05-06 00:08:46 +00003721 Py_BEGIN_ALLOW_THREADS
3722 spawnval = _spawnve(mode, path, argvlist, envlist);
3723 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003724#endif
Tim Peters25059d32001-12-07 20:35:43 +00003725
Victor Stinner8c62be82010-05-06 00:08:46 +00003726 if (spawnval == -1)
3727 (void) posix_error();
3728 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003729#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003730 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003731#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003732 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003733#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003734
Victor Stinner8c62be82010-05-06 00:08:46 +00003735 while (--envc >= 0)
3736 PyMem_DEL(envlist[envc]);
3737 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003738 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003739 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003740 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003741 Py_DECREF(opath);
3742 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003743}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003744
3745/* OS/2 supports spawnvp & spawnvpe natively */
3746#if defined(PYOS_OS2)
3747PyDoc_STRVAR(posix_spawnvp__doc__,
3748"spawnvp(mode, file, args)\n\n\
3749Execute the program 'file' in a new process, using the environment\n\
3750search path to find the file.\n\
3751\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003752 mode: mode of process creation\n\
3753 file: executable file name\n\
3754 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003755
3756static PyObject *
3757posix_spawnvp(PyObject *self, PyObject *args)
3758{
Victor Stinner8c62be82010-05-06 00:08:46 +00003759 PyObject *opath;
3760 char *path;
3761 PyObject *argv;
3762 char **argvlist;
3763 int mode, i, argc;
3764 Py_intptr_t spawnval;
3765 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003766
Victor Stinner8c62be82010-05-06 00:08:46 +00003767 /* spawnvp has three arguments: (mode, path, argv), where
3768 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003769
Victor Stinner8c62be82010-05-06 00:08:46 +00003770 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3771 PyUnicode_FSConverter,
3772 &opath, &argv))
3773 return NULL;
3774 path = PyBytes_AsString(opath);
3775 if (PyList_Check(argv)) {
3776 argc = PyList_Size(argv);
3777 getitem = PyList_GetItem;
3778 }
3779 else if (PyTuple_Check(argv)) {
3780 argc = PyTuple_Size(argv);
3781 getitem = PyTuple_GetItem;
3782 }
3783 else {
3784 PyErr_SetString(PyExc_TypeError,
3785 "spawnvp() arg 2 must be a tuple or list");
3786 Py_DECREF(opath);
3787 return NULL;
3788 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003789
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 argvlist = PyMem_NEW(char *, argc+1);
3791 if (argvlist == NULL) {
3792 Py_DECREF(opath);
3793 return PyErr_NoMemory();
3794 }
3795 for (i = 0; i < argc; i++) {
3796 if (!fsconvert_strdup((*getitem)(argv, i),
3797 &argvlist[i])) {
3798 free_string_array(argvlist, i);
3799 PyErr_SetString(
3800 PyExc_TypeError,
3801 "spawnvp() arg 2 must contain only strings");
3802 Py_DECREF(opath);
3803 return NULL;
3804 }
3805 }
3806 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003807
Victor Stinner8c62be82010-05-06 00:08:46 +00003808 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003809#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003810 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003811#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003812 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003813#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003814 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003815
Victor Stinner8c62be82010-05-06 00:08:46 +00003816 free_string_array(argvlist, argc);
3817 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003818
Victor Stinner8c62be82010-05-06 00:08:46 +00003819 if (spawnval == -1)
3820 return posix_error();
3821 else
3822 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003823}
3824
3825
3826PyDoc_STRVAR(posix_spawnvpe__doc__,
3827"spawnvpe(mode, file, args, env)\n\n\
3828Execute the program 'file' in a new process, using the environment\n\
3829search path to find the file.\n\
3830\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003831 mode: mode of process creation\n\
3832 file: executable file name\n\
3833 args: tuple or list of arguments\n\
3834 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003835
3836static PyObject *
3837posix_spawnvpe(PyObject *self, PyObject *args)
3838{
Victor Stinner8c62be82010-05-06 00:08:46 +00003839 PyObject *opath
3840 char *path;
3841 PyObject *argv, *env;
3842 char **argvlist;
3843 char **envlist;
3844 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003845 int mode;
3846 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003847 Py_intptr_t spawnval;
3848 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3849 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003850
Victor Stinner8c62be82010-05-06 00:08:46 +00003851 /* spawnvpe has four arguments: (mode, path, argv, env), where
3852 argv is a list or tuple of strings and env is a dictionary
3853 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003854
Victor Stinner8c62be82010-05-06 00:08:46 +00003855 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3856 PyUnicode_FSConverter,
3857 &opath, &argv, &env))
3858 return NULL;
3859 path = PyBytes_AsString(opath);
3860 if (PyList_Check(argv)) {
3861 argc = PyList_Size(argv);
3862 getitem = PyList_GetItem;
3863 }
3864 else if (PyTuple_Check(argv)) {
3865 argc = PyTuple_Size(argv);
3866 getitem = PyTuple_GetItem;
3867 }
3868 else {
3869 PyErr_SetString(PyExc_TypeError,
3870 "spawnvpe() arg 2 must be a tuple or list");
3871 goto fail_0;
3872 }
3873 if (!PyMapping_Check(env)) {
3874 PyErr_SetString(PyExc_TypeError,
3875 "spawnvpe() arg 3 must be a mapping object");
3876 goto fail_0;
3877 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003878
Victor Stinner8c62be82010-05-06 00:08:46 +00003879 argvlist = PyMem_NEW(char *, argc+1);
3880 if (argvlist == NULL) {
3881 PyErr_NoMemory();
3882 goto fail_0;
3883 }
3884 for (i = 0; i < argc; i++) {
3885 if (!fsconvert_strdup((*getitem)(argv, i),
3886 &argvlist[i]))
3887 {
3888 lastarg = i;
3889 goto fail_1;
3890 }
3891 }
3892 lastarg = argc;
3893 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003894
Victor Stinner8c62be82010-05-06 00:08:46 +00003895 envlist = parse_envlist(env, &envc);
3896 if (envlist == NULL)
3897 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003898
Victor Stinner8c62be82010-05-06 00:08:46 +00003899 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003900#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003901 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003902#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003904#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003905 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003906
Victor Stinner8c62be82010-05-06 00:08:46 +00003907 if (spawnval == -1)
3908 (void) posix_error();
3909 else
3910 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003911
Victor Stinner8c62be82010-05-06 00:08:46 +00003912 while (--envc >= 0)
3913 PyMem_DEL(envlist[envc]);
3914 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003915 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003916 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003917 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003918 Py_DECREF(opath);
3919 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003920}
3921#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003922#endif /* HAVE_SPAWNV */
3923
3924
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003925#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003926PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003927"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003928Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3929\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003930Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003931
3932static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003933posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003934{
Victor Stinner8c62be82010-05-06 00:08:46 +00003935 pid_t pid;
3936 int result = 0;
3937 _PyImport_AcquireLock();
3938 pid = fork1();
3939 if (pid == 0) {
3940 /* child: this clobbers and resets the import lock. */
3941 PyOS_AfterFork();
3942 } else {
3943 /* parent: release the import lock. */
3944 result = _PyImport_ReleaseLock();
3945 }
3946 if (pid == -1)
3947 return posix_error();
3948 if (result < 0) {
3949 /* Don't clobber the OSError if the fork failed. */
3950 PyErr_SetString(PyExc_RuntimeError,
3951 "not holding the import lock");
3952 return NULL;
3953 }
3954 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003955}
3956#endif
3957
3958
Guido van Rossumad0ee831995-03-01 10:34:45 +00003959#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003960PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003961"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003962Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003963Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003964
Barry Warsaw53699e91996-12-10 23:23:01 +00003965static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003966posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003967{
Victor Stinner8c62be82010-05-06 00:08:46 +00003968 pid_t pid;
3969 int result = 0;
3970 _PyImport_AcquireLock();
3971 pid = fork();
3972 if (pid == 0) {
3973 /* child: this clobbers and resets the import lock. */
3974 PyOS_AfterFork();
3975 } else {
3976 /* parent: release the import lock. */
3977 result = _PyImport_ReleaseLock();
3978 }
3979 if (pid == -1)
3980 return posix_error();
3981 if (result < 0) {
3982 /* Don't clobber the OSError if the fork failed. */
3983 PyErr_SetString(PyExc_RuntimeError,
3984 "not holding the import lock");
3985 return NULL;
3986 }
3987 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003988}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003989#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003990
Neal Norwitzb59798b2003-03-21 01:43:31 +00003991/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003992/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3993#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003994#define DEV_PTY_FILE "/dev/ptc"
3995#define HAVE_DEV_PTMX
3996#else
3997#define DEV_PTY_FILE "/dev/ptmx"
3998#endif
3999
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004000#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004001#ifdef HAVE_PTY_H
4002#include <pty.h>
4003#else
4004#ifdef HAVE_LIBUTIL_H
4005#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00004006#else
4007#ifdef HAVE_UTIL_H
4008#include <util.h>
4009#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004010#endif /* HAVE_LIBUTIL_H */
4011#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00004012#ifdef HAVE_STROPTS_H
4013#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004014#endif
4015#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004016
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004017#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004018PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004019"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004020Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004021
4022static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004023posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004024{
Victor Stinner8c62be82010-05-06 00:08:46 +00004025 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004026#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004027 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004028#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004029#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004030 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004031#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004032 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004033#endif
4034#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004035
Thomas Wouters70c21a12000-07-14 14:28:33 +00004036#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004037 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4038 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004039#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004040 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4041 if (slave_name == NULL)
4042 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004043
Victor Stinner8c62be82010-05-06 00:08:46 +00004044 slave_fd = open(slave_name, O_RDWR);
4045 if (slave_fd < 0)
4046 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004047#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004048 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4049 if (master_fd < 0)
4050 return posix_error();
4051 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4052 /* change permission of slave */
4053 if (grantpt(master_fd) < 0) {
4054 PyOS_setsig(SIGCHLD, sig_saved);
4055 return posix_error();
4056 }
4057 /* unlock slave */
4058 if (unlockpt(master_fd) < 0) {
4059 PyOS_setsig(SIGCHLD, sig_saved);
4060 return posix_error();
4061 }
4062 PyOS_setsig(SIGCHLD, sig_saved);
4063 slave_name = ptsname(master_fd); /* get name of slave */
4064 if (slave_name == NULL)
4065 return posix_error();
4066 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4067 if (slave_fd < 0)
4068 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004069#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004070 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4071 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004072#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004073 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004074#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004075#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004076#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004077
Victor Stinner8c62be82010-05-06 00:08:46 +00004078 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004079
Fred Drake8cef4cf2000-06-28 16:40:38 +00004080}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004081#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004082
4083#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004084PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004085"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004086Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4087Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004088To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004089
4090static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004091posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004092{
Victor Stinner8c62be82010-05-06 00:08:46 +00004093 int master_fd = -1, result = 0;
4094 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004095
Victor Stinner8c62be82010-05-06 00:08:46 +00004096 _PyImport_AcquireLock();
4097 pid = forkpty(&master_fd, NULL, NULL, NULL);
4098 if (pid == 0) {
4099 /* child: this clobbers and resets the import lock. */
4100 PyOS_AfterFork();
4101 } else {
4102 /* parent: release the import lock. */
4103 result = _PyImport_ReleaseLock();
4104 }
4105 if (pid == -1)
4106 return posix_error();
4107 if (result < 0) {
4108 /* Don't clobber the OSError if the fork failed. */
4109 PyErr_SetString(PyExc_RuntimeError,
4110 "not holding the import lock");
4111 return NULL;
4112 }
4113 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004114}
4115#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004116
Guido van Rossumad0ee831995-03-01 10:34:45 +00004117#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004118PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004119"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004120Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004121
Barry Warsaw53699e91996-12-10 23:23:01 +00004122static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004123posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004124{
Victor Stinner8c62be82010-05-06 00:08:46 +00004125 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004126}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004127#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004128
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004129
Guido van Rossumad0ee831995-03-01 10:34:45 +00004130#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004131PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004132"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004133Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004134
Barry Warsaw53699e91996-12-10 23:23:01 +00004135static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004136posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004137{
Victor Stinner8c62be82010-05-06 00:08:46 +00004138 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004139}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004140#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004141
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004142
Guido van Rossumad0ee831995-03-01 10:34:45 +00004143#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004144PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004145"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004146Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004147
Barry Warsaw53699e91996-12-10 23:23:01 +00004148static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004149posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004150{
Victor Stinner8c62be82010-05-06 00:08:46 +00004151 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004152}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004153#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004155
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004156PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004157"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004158Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004159
Barry Warsaw53699e91996-12-10 23:23:01 +00004160static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004161posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004162{
Victor Stinner8c62be82010-05-06 00:08:46 +00004163 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004164}
4165
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004166
Fred Drakec9680921999-12-13 16:37:25 +00004167#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004168PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004169"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004170Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004171
4172static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004173posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004174{
4175 PyObject *result = NULL;
4176
Fred Drakec9680921999-12-13 16:37:25 +00004177#ifdef NGROUPS_MAX
4178#define MAX_GROUPS NGROUPS_MAX
4179#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004180 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004181#define MAX_GROUPS 64
4182#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004183 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004184
4185 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4186 * This is a helper variable to store the intermediate result when
4187 * that happens.
4188 *
4189 * To keep the code readable the OSX behaviour is unconditional,
4190 * according to the POSIX spec this should be safe on all unix-y
4191 * systems.
4192 */
4193 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00004194 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004195
Victor Stinner8c62be82010-05-06 00:08:46 +00004196 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004197 if (n < 0) {
4198 if (errno == EINVAL) {
4199 n = getgroups(0, NULL);
4200 if (n == -1) {
4201 return posix_error();
4202 }
4203 if (n == 0) {
4204 /* Avoid malloc(0) */
4205 alt_grouplist = grouplist;
4206 } else {
4207 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4208 if (alt_grouplist == NULL) {
4209 errno = EINVAL;
4210 return posix_error();
4211 }
4212 n = getgroups(n, alt_grouplist);
4213 if (n == -1) {
4214 PyMem_Free(alt_grouplist);
4215 return posix_error();
4216 }
4217 }
4218 } else {
4219 return posix_error();
4220 }
4221 }
4222 result = PyList_New(n);
4223 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004224 int i;
4225 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004226 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00004227 if (o == NULL) {
4228 Py_DECREF(result);
4229 result = NULL;
4230 break;
Fred Drakec9680921999-12-13 16:37:25 +00004231 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004232 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004233 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004234 }
4235
4236 if (alt_grouplist != grouplist) {
4237 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00004238 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004239
Fred Drakec9680921999-12-13 16:37:25 +00004240 return result;
4241}
4242#endif
4243
Antoine Pitroub7572f02009-12-02 20:46:48 +00004244#ifdef HAVE_INITGROUPS
4245PyDoc_STRVAR(posix_initgroups__doc__,
4246"initgroups(username, gid) -> None\n\n\
4247Call the system initgroups() to initialize the group access list with all of\n\
4248the groups of which the specified username is a member, plus the specified\n\
4249group id.");
4250
4251static PyObject *
4252posix_initgroups(PyObject *self, PyObject *args)
4253{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004254 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00004255 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004256 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004257 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004258
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004259 if (!PyArg_ParseTuple(args, "O&l:initgroups",
4260 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00004261 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004262 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004263
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004264 res = initgroups(username, (gid_t) gid);
4265 Py_DECREF(oname);
4266 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00004267 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004268
Victor Stinner8c62be82010-05-06 00:08:46 +00004269 Py_INCREF(Py_None);
4270 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004271}
4272#endif
4273
Martin v. Löwis606edc12002-06-13 21:09:11 +00004274#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004275PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004276"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004277Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004278
4279static PyObject *
4280posix_getpgid(PyObject *self, PyObject *args)
4281{
Victor Stinner8c62be82010-05-06 00:08:46 +00004282 pid_t pid, pgid;
4283 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4284 return NULL;
4285 pgid = getpgid(pid);
4286 if (pgid < 0)
4287 return posix_error();
4288 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004289}
4290#endif /* HAVE_GETPGID */
4291
4292
Guido van Rossumb6775db1994-08-01 11:34:53 +00004293#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004294PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004295"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004296Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004297
Barry Warsaw53699e91996-12-10 23:23:01 +00004298static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004299posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004300{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004301#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004302 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004303#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004304 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004305#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004306}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004307#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004308
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004309
Guido van Rossumb6775db1994-08-01 11:34:53 +00004310#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004311PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004312"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004313Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004314
Barry Warsaw53699e91996-12-10 23:23:01 +00004315static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004316posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004317{
Guido van Rossum64933891994-10-20 21:56:42 +00004318#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004319 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004320#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004321 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004322#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004323 return posix_error();
4324 Py_INCREF(Py_None);
4325 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004326}
4327
Guido van Rossumb6775db1994-08-01 11:34:53 +00004328#endif /* HAVE_SETPGRP */
4329
Guido van Rossumad0ee831995-03-01 10:34:45 +00004330#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004331
4332#ifdef MS_WINDOWS
4333#include <tlhelp32.h>
4334
4335static PyObject*
4336win32_getppid()
4337{
4338 HANDLE snapshot;
4339 pid_t mypid;
4340 PyObject* result = NULL;
4341 BOOL have_record;
4342 PROCESSENTRY32 pe;
4343
4344 mypid = getpid(); /* This function never fails */
4345
4346 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
4347 if (snapshot == INVALID_HANDLE_VALUE)
4348 return PyErr_SetFromWindowsErr(GetLastError());
4349
4350 pe.dwSize = sizeof(pe);
4351 have_record = Process32First(snapshot, &pe);
4352 while (have_record) {
4353 if (mypid == (pid_t)pe.th32ProcessID) {
4354 /* We could cache the ulong value in a static variable. */
4355 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
4356 break;
4357 }
4358
4359 have_record = Process32Next(snapshot, &pe);
4360 }
4361
4362 /* If our loop exits and our pid was not found (result will be NULL)
4363 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
4364 * error anyway, so let's raise it. */
4365 if (!result)
4366 result = PyErr_SetFromWindowsErr(GetLastError());
4367
4368 CloseHandle(snapshot);
4369
4370 return result;
4371}
4372#endif /*MS_WINDOWS*/
4373
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004374PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004375"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004376Return the parent's process id. If the parent process has already exited,\n\
4377Windows machines will still return its id; others systems will return the id\n\
4378of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004379
Barry Warsaw53699e91996-12-10 23:23:01 +00004380static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004381posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004382{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004383#ifdef MS_WINDOWS
4384 return win32_getppid();
4385#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004386 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00004387#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004388}
4389#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004391
Fred Drake12c6e2d1999-12-14 21:25:03 +00004392#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004393PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004394"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004395Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004396
4397static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004398posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004399{
Victor Stinner8c62be82010-05-06 00:08:46 +00004400 PyObject *result = NULL;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004401#ifdef MS_WINDOWS
4402 wchar_t user_name[UNLEN + 1];
4403 DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]);
4404
4405 if (GetUserNameW(user_name, &num_chars)) {
4406 /* num_chars is the number of unicode chars plus null terminator */
4407 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
4408 }
4409 else
4410 result = PyErr_SetFromWindowsErr(GetLastError());
4411#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004412 char *name;
4413 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004414
Victor Stinner8c62be82010-05-06 00:08:46 +00004415 errno = 0;
4416 name = getlogin();
4417 if (name == NULL) {
4418 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00004419 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004420 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004421 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00004422 }
4423 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004424 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00004425 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004426#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00004427 return result;
4428}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004429#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004430
Guido van Rossumad0ee831995-03-01 10:34:45 +00004431#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004432PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004433"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004434Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004435
Barry Warsaw53699e91996-12-10 23:23:01 +00004436static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004437posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004438{
Victor Stinner8c62be82010-05-06 00:08:46 +00004439 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004440}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004441#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004442
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004443
Guido van Rossumad0ee831995-03-01 10:34:45 +00004444#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004445PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004446"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004447Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004448
Barry Warsaw53699e91996-12-10 23:23:01 +00004449static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004450posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004451{
Victor Stinner8c62be82010-05-06 00:08:46 +00004452 pid_t pid;
4453 int sig;
4454 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4455 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004456#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004457 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4458 APIRET rc;
4459 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004460 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004461
4462 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4463 APIRET rc;
4464 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004465 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004466
4467 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004468 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004469#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004470 if (kill(pid, sig) == -1)
4471 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004472#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004473 Py_INCREF(Py_None);
4474 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004475}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004476#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004477
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004478#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004479PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004480"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004481Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004482
4483static PyObject *
4484posix_killpg(PyObject *self, PyObject *args)
4485{
Victor Stinner8c62be82010-05-06 00:08:46 +00004486 int sig;
4487 pid_t pgid;
4488 /* XXX some man pages make the `pgid` parameter an int, others
4489 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4490 take the same type. Moreover, pid_t is always at least as wide as
4491 int (else compilation of this module fails), which is safe. */
4492 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4493 return NULL;
4494 if (killpg(pgid, sig) == -1)
4495 return posix_error();
4496 Py_INCREF(Py_None);
4497 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004498}
4499#endif
4500
Brian Curtineb24d742010-04-12 17:16:38 +00004501#ifdef MS_WINDOWS
4502PyDoc_STRVAR(win32_kill__doc__,
4503"kill(pid, sig)\n\n\
4504Kill a process with a signal.");
4505
4506static PyObject *
4507win32_kill(PyObject *self, PyObject *args)
4508{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004509 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004510 DWORD pid, sig, err;
4511 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004512
Victor Stinner8c62be82010-05-06 00:08:46 +00004513 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4514 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004515
Victor Stinner8c62be82010-05-06 00:08:46 +00004516 /* Console processes which share a common console can be sent CTRL+C or
4517 CTRL+BREAK events, provided they handle said events. */
4518 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4519 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4520 err = GetLastError();
4521 PyErr_SetFromWindowsErr(err);
4522 }
4523 else
4524 Py_RETURN_NONE;
4525 }
Brian Curtineb24d742010-04-12 17:16:38 +00004526
Victor Stinner8c62be82010-05-06 00:08:46 +00004527 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4528 attempt to open and terminate the process. */
4529 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4530 if (handle == NULL) {
4531 err = GetLastError();
4532 return PyErr_SetFromWindowsErr(err);
4533 }
Brian Curtineb24d742010-04-12 17:16:38 +00004534
Victor Stinner8c62be82010-05-06 00:08:46 +00004535 if (TerminateProcess(handle, sig) == 0) {
4536 err = GetLastError();
4537 result = PyErr_SetFromWindowsErr(err);
4538 } else {
4539 Py_INCREF(Py_None);
4540 result = Py_None;
4541 }
Brian Curtineb24d742010-04-12 17:16:38 +00004542
Victor Stinner8c62be82010-05-06 00:08:46 +00004543 CloseHandle(handle);
4544 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004545}
4546#endif /* MS_WINDOWS */
4547
Guido van Rossumc0125471996-06-28 18:55:32 +00004548#ifdef HAVE_PLOCK
4549
4550#ifdef HAVE_SYS_LOCK_H
4551#include <sys/lock.h>
4552#endif
4553
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004554PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004555"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004556Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004557
Barry Warsaw53699e91996-12-10 23:23:01 +00004558static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004559posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004560{
Victor Stinner8c62be82010-05-06 00:08:46 +00004561 int op;
4562 if (!PyArg_ParseTuple(args, "i:plock", &op))
4563 return NULL;
4564 if (plock(op) == -1)
4565 return posix_error();
4566 Py_INCREF(Py_None);
4567 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004568}
4569#endif
4570
Guido van Rossumb6775db1994-08-01 11:34:53 +00004571#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004572PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004573"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004574Set the current process's user id.");
4575
Barry Warsaw53699e91996-12-10 23:23:01 +00004576static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004577posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004578{
Victor Stinner8c62be82010-05-06 00:08:46 +00004579 long uid_arg;
4580 uid_t uid;
4581 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4582 return NULL;
4583 uid = uid_arg;
4584 if (uid != uid_arg) {
4585 PyErr_SetString(PyExc_OverflowError, "user id too big");
4586 return NULL;
4587 }
4588 if (setuid(uid) < 0)
4589 return posix_error();
4590 Py_INCREF(Py_None);
4591 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004592}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004593#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004594
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004595
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004596#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004597PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004598"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004599Set the current process's effective user id.");
4600
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004601static PyObject *
4602posix_seteuid (PyObject *self, PyObject *args)
4603{
Victor Stinner8c62be82010-05-06 00:08:46 +00004604 long euid_arg;
4605 uid_t euid;
4606 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4607 return NULL;
4608 euid = euid_arg;
4609 if (euid != euid_arg) {
4610 PyErr_SetString(PyExc_OverflowError, "user id too big");
4611 return NULL;
4612 }
4613 if (seteuid(euid) < 0) {
4614 return posix_error();
4615 } else {
4616 Py_INCREF(Py_None);
4617 return Py_None;
4618 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004619}
4620#endif /* HAVE_SETEUID */
4621
4622#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004623PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004624"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004625Set the current process's effective group id.");
4626
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004627static PyObject *
4628posix_setegid (PyObject *self, PyObject *args)
4629{
Victor Stinner8c62be82010-05-06 00:08:46 +00004630 long egid_arg;
4631 gid_t egid;
4632 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4633 return NULL;
4634 egid = egid_arg;
4635 if (egid != egid_arg) {
4636 PyErr_SetString(PyExc_OverflowError, "group id too big");
4637 return NULL;
4638 }
4639 if (setegid(egid) < 0) {
4640 return posix_error();
4641 } else {
4642 Py_INCREF(Py_None);
4643 return Py_None;
4644 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004645}
4646#endif /* HAVE_SETEGID */
4647
4648#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004649PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004650"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004651Set the current process's real and effective user ids.");
4652
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004653static PyObject *
4654posix_setreuid (PyObject *self, PyObject *args)
4655{
Victor Stinner8c62be82010-05-06 00:08:46 +00004656 long ruid_arg, euid_arg;
4657 uid_t ruid, euid;
4658 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4659 return NULL;
4660 if (ruid_arg == -1)
4661 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4662 else
4663 ruid = ruid_arg; /* otherwise, assign from our long */
4664 if (euid_arg == -1)
4665 euid = (uid_t)-1;
4666 else
4667 euid = euid_arg;
4668 if ((euid_arg != -1 && euid != euid_arg) ||
4669 (ruid_arg != -1 && ruid != ruid_arg)) {
4670 PyErr_SetString(PyExc_OverflowError, "user id too big");
4671 return NULL;
4672 }
4673 if (setreuid(ruid, euid) < 0) {
4674 return posix_error();
4675 } else {
4676 Py_INCREF(Py_None);
4677 return Py_None;
4678 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004679}
4680#endif /* HAVE_SETREUID */
4681
4682#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004683PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004684"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004685Set the current process's real and effective group ids.");
4686
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004687static PyObject *
4688posix_setregid (PyObject *self, PyObject *args)
4689{
Victor Stinner8c62be82010-05-06 00:08:46 +00004690 long rgid_arg, egid_arg;
4691 gid_t rgid, egid;
4692 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4693 return NULL;
4694 if (rgid_arg == -1)
4695 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4696 else
4697 rgid = rgid_arg; /* otherwise, assign from our long */
4698 if (egid_arg == -1)
4699 egid = (gid_t)-1;
4700 else
4701 egid = egid_arg;
4702 if ((egid_arg != -1 && egid != egid_arg) ||
4703 (rgid_arg != -1 && rgid != rgid_arg)) {
4704 PyErr_SetString(PyExc_OverflowError, "group id too big");
4705 return NULL;
4706 }
4707 if (setregid(rgid, egid) < 0) {
4708 return posix_error();
4709 } else {
4710 Py_INCREF(Py_None);
4711 return Py_None;
4712 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004713}
4714#endif /* HAVE_SETREGID */
4715
Guido van Rossumb6775db1994-08-01 11:34:53 +00004716#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004717PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004718"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004719Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004720
Barry Warsaw53699e91996-12-10 23:23:01 +00004721static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004722posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004723{
Victor Stinner8c62be82010-05-06 00:08:46 +00004724 long gid_arg;
4725 gid_t gid;
4726 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4727 return NULL;
4728 gid = gid_arg;
4729 if (gid != gid_arg) {
4730 PyErr_SetString(PyExc_OverflowError, "group id too big");
4731 return NULL;
4732 }
4733 if (setgid(gid) < 0)
4734 return posix_error();
4735 Py_INCREF(Py_None);
4736 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004737}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004738#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004739
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004740#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004741PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004742"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004743Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004744
4745static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004746posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004747{
Victor Stinner8c62be82010-05-06 00:08:46 +00004748 int i, len;
4749 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004750
Victor Stinner8c62be82010-05-06 00:08:46 +00004751 if (!PySequence_Check(groups)) {
4752 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4753 return NULL;
4754 }
4755 len = PySequence_Size(groups);
4756 if (len > MAX_GROUPS) {
4757 PyErr_SetString(PyExc_ValueError, "too many groups");
4758 return NULL;
4759 }
4760 for(i = 0; i < len; i++) {
4761 PyObject *elem;
4762 elem = PySequence_GetItem(groups, i);
4763 if (!elem)
4764 return NULL;
4765 if (!PyLong_Check(elem)) {
4766 PyErr_SetString(PyExc_TypeError,
4767 "groups must be integers");
4768 Py_DECREF(elem);
4769 return NULL;
4770 } else {
4771 unsigned long x = PyLong_AsUnsignedLong(elem);
4772 if (PyErr_Occurred()) {
4773 PyErr_SetString(PyExc_TypeError,
4774 "group id too big");
4775 Py_DECREF(elem);
4776 return NULL;
4777 }
4778 grouplist[i] = x;
4779 /* read back the value to see if it fitted in gid_t */
4780 if (grouplist[i] != x) {
4781 PyErr_SetString(PyExc_TypeError,
4782 "group id too big");
4783 Py_DECREF(elem);
4784 return NULL;
4785 }
4786 }
4787 Py_DECREF(elem);
4788 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004789
Victor Stinner8c62be82010-05-06 00:08:46 +00004790 if (setgroups(len, grouplist) < 0)
4791 return posix_error();
4792 Py_INCREF(Py_None);
4793 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004794}
4795#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004796
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004797#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4798static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004799wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004800{
Victor Stinner8c62be82010-05-06 00:08:46 +00004801 PyObject *result;
4802 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004803
Victor Stinner8c62be82010-05-06 00:08:46 +00004804 if (pid == -1)
4805 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004806
Victor Stinner8c62be82010-05-06 00:08:46 +00004807 if (struct_rusage == NULL) {
4808 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4809 if (m == NULL)
4810 return NULL;
4811 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4812 Py_DECREF(m);
4813 if (struct_rusage == NULL)
4814 return NULL;
4815 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004816
Victor Stinner8c62be82010-05-06 00:08:46 +00004817 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4818 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4819 if (!result)
4820 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004821
4822#ifndef doubletime
4823#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4824#endif
4825
Victor Stinner8c62be82010-05-06 00:08:46 +00004826 PyStructSequence_SET_ITEM(result, 0,
4827 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4828 PyStructSequence_SET_ITEM(result, 1,
4829 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004830#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004831 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4832 SET_INT(result, 2, ru->ru_maxrss);
4833 SET_INT(result, 3, ru->ru_ixrss);
4834 SET_INT(result, 4, ru->ru_idrss);
4835 SET_INT(result, 5, ru->ru_isrss);
4836 SET_INT(result, 6, ru->ru_minflt);
4837 SET_INT(result, 7, ru->ru_majflt);
4838 SET_INT(result, 8, ru->ru_nswap);
4839 SET_INT(result, 9, ru->ru_inblock);
4840 SET_INT(result, 10, ru->ru_oublock);
4841 SET_INT(result, 11, ru->ru_msgsnd);
4842 SET_INT(result, 12, ru->ru_msgrcv);
4843 SET_INT(result, 13, ru->ru_nsignals);
4844 SET_INT(result, 14, ru->ru_nvcsw);
4845 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004846#undef SET_INT
4847
Victor Stinner8c62be82010-05-06 00:08:46 +00004848 if (PyErr_Occurred()) {
4849 Py_DECREF(result);
4850 return NULL;
4851 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004852
Victor Stinner8c62be82010-05-06 00:08:46 +00004853 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004854}
4855#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4856
4857#ifdef HAVE_WAIT3
4858PyDoc_STRVAR(posix_wait3__doc__,
4859"wait3(options) -> (pid, status, rusage)\n\n\
4860Wait for completion of a child process.");
4861
4862static PyObject *
4863posix_wait3(PyObject *self, PyObject *args)
4864{
Victor Stinner8c62be82010-05-06 00:08:46 +00004865 pid_t pid;
4866 int options;
4867 struct rusage ru;
4868 WAIT_TYPE status;
4869 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004870
Victor Stinner8c62be82010-05-06 00:08:46 +00004871 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4872 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004873
Victor Stinner8c62be82010-05-06 00:08:46 +00004874 Py_BEGIN_ALLOW_THREADS
4875 pid = wait3(&status, options, &ru);
4876 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004877
Victor Stinner8c62be82010-05-06 00:08:46 +00004878 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004879}
4880#endif /* HAVE_WAIT3 */
4881
4882#ifdef HAVE_WAIT4
4883PyDoc_STRVAR(posix_wait4__doc__,
4884"wait4(pid, options) -> (pid, status, rusage)\n\n\
4885Wait for completion of a given child process.");
4886
4887static PyObject *
4888posix_wait4(PyObject *self, PyObject *args)
4889{
Victor Stinner8c62be82010-05-06 00:08:46 +00004890 pid_t pid;
4891 int options;
4892 struct rusage ru;
4893 WAIT_TYPE status;
4894 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004895
Victor Stinner8c62be82010-05-06 00:08:46 +00004896 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
4897 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004898
Victor Stinner8c62be82010-05-06 00:08:46 +00004899 Py_BEGIN_ALLOW_THREADS
4900 pid = wait4(pid, &status, options, &ru);
4901 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004902
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004904}
4905#endif /* HAVE_WAIT4 */
4906
Guido van Rossumb6775db1994-08-01 11:34:53 +00004907#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004908PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004909"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004910Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004911
Barry Warsaw53699e91996-12-10 23:23:01 +00004912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004913posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004914{
Victor Stinner8c62be82010-05-06 00:08:46 +00004915 pid_t pid;
4916 int options;
4917 WAIT_TYPE status;
4918 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004919
Victor Stinner8c62be82010-05-06 00:08:46 +00004920 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4921 return NULL;
4922 Py_BEGIN_ALLOW_THREADS
4923 pid = waitpid(pid, &status, options);
4924 Py_END_ALLOW_THREADS
4925 if (pid == -1)
4926 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004927
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004929}
4930
Tim Petersab034fa2002-02-01 11:27:43 +00004931#elif defined(HAVE_CWAIT)
4932
4933/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004934PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004935"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004936"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004937
4938static PyObject *
4939posix_waitpid(PyObject *self, PyObject *args)
4940{
Victor Stinner8c62be82010-05-06 00:08:46 +00004941 Py_intptr_t pid;
4942 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004943
Victor Stinner8c62be82010-05-06 00:08:46 +00004944 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4945 return NULL;
4946 Py_BEGIN_ALLOW_THREADS
4947 pid = _cwait(&status, pid, options);
4948 Py_END_ALLOW_THREADS
4949 if (pid == -1)
4950 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004951
Victor Stinner8c62be82010-05-06 00:08:46 +00004952 /* shift the status left a byte so this is more like the POSIX waitpid */
4953 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004954}
4955#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004956
Guido van Rossumad0ee831995-03-01 10:34:45 +00004957#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004958PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004959"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004960Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004961
Barry Warsaw53699e91996-12-10 23:23:01 +00004962static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004963posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004964{
Victor Stinner8c62be82010-05-06 00:08:46 +00004965 pid_t pid;
4966 WAIT_TYPE status;
4967 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004968
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 Py_BEGIN_ALLOW_THREADS
4970 pid = wait(&status);
4971 Py_END_ALLOW_THREADS
4972 if (pid == -1)
4973 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004974
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004976}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004977#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004978
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004979
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004980PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004981"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004982Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004983
Barry Warsaw53699e91996-12-10 23:23:01 +00004984static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004985posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004986{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004987#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00004988 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004989#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004990#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00004991 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat",
4992 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004993#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004994 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004995#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004996#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004997}
4998
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004999
Guido van Rossumb6775db1994-08-01 11:34:53 +00005000#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005001PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005002"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005003Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005004
Barry Warsaw53699e91996-12-10 23:23:01 +00005005static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005006posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005007{
Victor Stinner8c62be82010-05-06 00:08:46 +00005008 PyObject* v;
5009 char buf[MAXPATHLEN];
5010 PyObject *opath;
5011 char *path;
5012 int n;
5013 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005014
Victor Stinner8c62be82010-05-06 00:08:46 +00005015 if (!PyArg_ParseTuple(args, "O&:readlink",
5016 PyUnicode_FSConverter, &opath))
5017 return NULL;
5018 path = PyBytes_AsString(opath);
5019 v = PySequence_GetItem(args, 0);
5020 if (v == NULL) {
5021 Py_DECREF(opath);
5022 return NULL;
5023 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00005024
Victor Stinner8c62be82010-05-06 00:08:46 +00005025 if (PyUnicode_Check(v)) {
5026 arg_is_unicode = 1;
5027 }
5028 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005029
Victor Stinner8c62be82010-05-06 00:08:46 +00005030 Py_BEGIN_ALLOW_THREADS
5031 n = readlink(path, buf, (int) sizeof buf);
5032 Py_END_ALLOW_THREADS
5033 if (n < 0)
5034 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005035
Victor Stinner8c62be82010-05-06 00:08:46 +00005036 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00005037 if (arg_is_unicode)
5038 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
5039 else
5040 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005041}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005042#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005044
Guido van Rossumb6775db1994-08-01 11:34:53 +00005045#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005046PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005047"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005048Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005049
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005050static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005051posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005052{
Victor Stinner8c62be82010-05-06 00:08:46 +00005053 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005054}
5055#endif /* HAVE_SYMLINK */
5056
Brian Curtind40e6f72010-07-08 21:39:08 +00005057#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
5058
5059PyDoc_STRVAR(win_readlink__doc__,
5060"readlink(path) -> path\n\n\
5061Return a string representing the path to which the symbolic link points.");
5062
Brian Curtind40e6f72010-07-08 21:39:08 +00005063/* Windows readlink implementation */
5064static PyObject *
5065win_readlink(PyObject *self, PyObject *args)
5066{
5067 wchar_t *path;
5068 DWORD n_bytes_returned;
5069 DWORD io_result;
5070 PyObject *result;
5071 HANDLE reparse_point_handle;
5072
5073 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
5074 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
5075 wchar_t *print_name;
5076
5077 if (!PyArg_ParseTuple(args,
5078 "u:readlink",
5079 &path))
5080 return NULL;
5081
5082 /* First get a handle to the reparse point */
5083 Py_BEGIN_ALLOW_THREADS
5084 reparse_point_handle = CreateFileW(
5085 path,
5086 0,
5087 0,
5088 0,
5089 OPEN_EXISTING,
5090 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5091 0);
5092 Py_END_ALLOW_THREADS
5093
5094 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5095 {
5096 return win32_error_unicode("readlink", path);
5097 }
5098
5099 Py_BEGIN_ALLOW_THREADS
5100 /* New call DeviceIoControl to read the reparse point */
5101 io_result = DeviceIoControl(
5102 reparse_point_handle,
5103 FSCTL_GET_REPARSE_POINT,
5104 0, 0, /* in buffer */
5105 target_buffer, sizeof(target_buffer),
5106 &n_bytes_returned,
5107 0 /* we're not using OVERLAPPED_IO */
5108 );
5109 CloseHandle(reparse_point_handle);
5110 Py_END_ALLOW_THREADS
5111
5112 if (io_result==0)
5113 {
5114 return win32_error_unicode("readlink", path);
5115 }
5116
5117 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5118 {
5119 PyErr_SetString(PyExc_ValueError,
5120 "not a symbolic link");
5121 return NULL;
5122 }
Brian Curtin74e45612010-07-09 15:58:59 +00005123 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5124 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5125
5126 result = PyUnicode_FromWideChar(print_name,
5127 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005128 return result;
5129}
5130
5131#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5132
5133#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
5134
5135/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5136static int has_CreateSymbolicLinkW = 0;
5137static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5138static int
5139check_CreateSymbolicLinkW()
5140{
5141 HINSTANCE hKernel32;
5142 /* only recheck */
5143 if (has_CreateSymbolicLinkW)
5144 return has_CreateSymbolicLinkW;
5145 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005146 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5147 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005148 if (Py_CreateSymbolicLinkW)
5149 has_CreateSymbolicLinkW = 1;
5150 return has_CreateSymbolicLinkW;
5151}
5152
5153PyDoc_STRVAR(win_symlink__doc__,
5154"symlink(src, dst, target_is_directory=False)\n\n\
5155Create a symbolic link pointing to src named dst.\n\
5156target_is_directory is required if the target is to be interpreted as\n\
5157a directory.\n\
5158This function requires Windows 6.0 or greater, and raises a\n\
5159NotImplementedError otherwise.");
5160
5161static PyObject *
5162win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5163{
5164 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5165 PyObject *src, *dest;
5166 int target_is_directory = 0;
5167 DWORD res;
5168 WIN32_FILE_ATTRIBUTE_DATA src_info;
5169
5170 if (!check_CreateSymbolicLinkW())
5171 {
5172 /* raise NotImplementedError */
5173 return PyErr_Format(PyExc_NotImplementedError,
5174 "CreateSymbolicLinkW not found");
5175 }
5176 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5177 kwlist, &src, &dest, &target_is_directory))
5178 return NULL;
5179 if (!convert_to_unicode(&src)) { return NULL; }
5180 if (!convert_to_unicode(&dest)) {
5181 Py_DECREF(src);
5182 return NULL;
5183 }
5184
5185 /* if src is a directory, ensure target_is_directory==1 */
5186 if(
5187 GetFileAttributesExW(
5188 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5189 ))
5190 {
5191 target_is_directory = target_is_directory ||
5192 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5193 }
5194
5195 Py_BEGIN_ALLOW_THREADS
5196 res = Py_CreateSymbolicLinkW(
5197 PyUnicode_AsUnicode(dest),
5198 PyUnicode_AsUnicode(src),
5199 target_is_directory);
5200 Py_END_ALLOW_THREADS
5201 Py_DECREF(src);
5202 Py_DECREF(dest);
5203 if (!res)
5204 {
5205 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5206 }
5207
5208 Py_INCREF(Py_None);
5209 return Py_None;
5210}
5211#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005212
5213#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005214#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5215static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005216system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005217{
5218 ULONG value = 0;
5219
5220 Py_BEGIN_ALLOW_THREADS
5221 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5222 Py_END_ALLOW_THREADS
5223
5224 return value;
5225}
5226
5227static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005228posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005229{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005230 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005231 return Py_BuildValue("ddddd",
5232 (double)0 /* t.tms_utime / HZ */,
5233 (double)0 /* t.tms_stime / HZ */,
5234 (double)0 /* t.tms_cutime / HZ */,
5235 (double)0 /* t.tms_cstime / HZ */,
5236 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005237}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005238#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005239#define NEED_TICKS_PER_SECOND
5240static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005241static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005242posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005243{
Victor Stinner8c62be82010-05-06 00:08:46 +00005244 struct tms t;
5245 clock_t c;
5246 errno = 0;
5247 c = times(&t);
5248 if (c == (clock_t) -1)
5249 return posix_error();
5250 return Py_BuildValue("ddddd",
5251 (double)t.tms_utime / ticks_per_second,
5252 (double)t.tms_stime / ticks_per_second,
5253 (double)t.tms_cutime / ticks_per_second,
5254 (double)t.tms_cstime / ticks_per_second,
5255 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005256}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005257#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005258#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005259
5260
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005261#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005262#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005263static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005264posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005265{
Victor Stinner8c62be82010-05-06 00:08:46 +00005266 FILETIME create, exit, kernel, user;
5267 HANDLE hProc;
5268 hProc = GetCurrentProcess();
5269 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5270 /* The fields of a FILETIME structure are the hi and lo part
5271 of a 64-bit value expressed in 100 nanosecond units.
5272 1e7 is one second in such units; 1e-7 the inverse.
5273 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5274 */
5275 return Py_BuildValue(
5276 "ddddd",
5277 (double)(user.dwHighDateTime*429.4967296 +
5278 user.dwLowDateTime*1e-7),
5279 (double)(kernel.dwHighDateTime*429.4967296 +
5280 kernel.dwLowDateTime*1e-7),
5281 (double)0,
5282 (double)0,
5283 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005284}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005285#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005286
5287#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005288PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005289"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005290Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005291#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005292
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005293
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005294#ifdef HAVE_GETSID
5295PyDoc_STRVAR(posix_getsid__doc__,
5296"getsid(pid) -> sid\n\n\
5297Call the system call getsid().");
5298
5299static PyObject *
5300posix_getsid(PyObject *self, PyObject *args)
5301{
Victor Stinner8c62be82010-05-06 00:08:46 +00005302 pid_t pid;
5303 int sid;
5304 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5305 return NULL;
5306 sid = getsid(pid);
5307 if (sid < 0)
5308 return posix_error();
5309 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005310}
5311#endif /* HAVE_GETSID */
5312
5313
Guido van Rossumb6775db1994-08-01 11:34:53 +00005314#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005315PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005316"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005317Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005318
Barry Warsaw53699e91996-12-10 23:23:01 +00005319static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005320posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005321{
Victor Stinner8c62be82010-05-06 00:08:46 +00005322 if (setsid() < 0)
5323 return posix_error();
5324 Py_INCREF(Py_None);
5325 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005326}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005327#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005328
Guido van Rossumb6775db1994-08-01 11:34:53 +00005329#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005330PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005331"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005332Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005333
Barry Warsaw53699e91996-12-10 23:23:01 +00005334static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005335posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005336{
Victor Stinner8c62be82010-05-06 00:08:46 +00005337 pid_t pid;
5338 int pgrp;
5339 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5340 return NULL;
5341 if (setpgid(pid, pgrp) < 0)
5342 return posix_error();
5343 Py_INCREF(Py_None);
5344 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005345}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005346#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005347
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005348
Guido van Rossumb6775db1994-08-01 11:34:53 +00005349#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005350PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005351"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005352Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005353
Barry Warsaw53699e91996-12-10 23:23:01 +00005354static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005355posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005356{
Victor Stinner8c62be82010-05-06 00:08:46 +00005357 int fd;
5358 pid_t pgid;
5359 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5360 return NULL;
5361 pgid = tcgetpgrp(fd);
5362 if (pgid < 0)
5363 return posix_error();
5364 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005365}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005366#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005367
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005368
Guido van Rossumb6775db1994-08-01 11:34:53 +00005369#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005370PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005371"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005372Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005373
Barry Warsaw53699e91996-12-10 23:23:01 +00005374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005375posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005376{
Victor Stinner8c62be82010-05-06 00:08:46 +00005377 int fd;
5378 pid_t pgid;
5379 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5380 return NULL;
5381 if (tcsetpgrp(fd, pgid) < 0)
5382 return posix_error();
5383 Py_INCREF(Py_None);
5384 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005385}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005386#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005387
Guido van Rossum687dd131993-05-17 08:34:16 +00005388/* Functions acting on file descriptors */
5389
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005390PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005391"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005392Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005393
Barry Warsaw53699e91996-12-10 23:23:01 +00005394static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005395posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005396{
Victor Stinner8c62be82010-05-06 00:08:46 +00005397 PyObject *ofile;
5398 char *file;
5399 int flag;
5400 int mode = 0777;
5401 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005402
5403#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005404 PyUnicodeObject *po;
5405 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5406 Py_BEGIN_ALLOW_THREADS
5407 /* PyUnicode_AS_UNICODE OK without thread
5408 lock as it is a simple dereference. */
5409 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5410 Py_END_ALLOW_THREADS
5411 if (fd < 0)
5412 return posix_error();
5413 return PyLong_FromLong((long)fd);
5414 }
5415 /* Drop the argument parsing error as narrow strings
5416 are also valid. */
5417 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005418#endif
5419
Victor Stinner8c62be82010-05-06 00:08:46 +00005420 if (!PyArg_ParseTuple(args, "O&i|i",
5421 PyUnicode_FSConverter, &ofile,
5422 &flag, &mode))
5423 return NULL;
5424 file = PyBytes_AsString(ofile);
5425 Py_BEGIN_ALLOW_THREADS
5426 fd = open(file, flag, mode);
5427 Py_END_ALLOW_THREADS
5428 if (fd < 0)
5429 return posix_error_with_allocated_filename(ofile);
5430 Py_DECREF(ofile);
5431 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005432}
5433
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005434
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005435PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005436"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005437Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005438
Barry Warsaw53699e91996-12-10 23:23:01 +00005439static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005440posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005441{
Victor Stinner8c62be82010-05-06 00:08:46 +00005442 int fd, res;
5443 if (!PyArg_ParseTuple(args, "i:close", &fd))
5444 return NULL;
5445 if (!_PyVerify_fd(fd))
5446 return posix_error();
5447 Py_BEGIN_ALLOW_THREADS
5448 res = close(fd);
5449 Py_END_ALLOW_THREADS
5450 if (res < 0)
5451 return posix_error();
5452 Py_INCREF(Py_None);
5453 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005454}
5455
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005456
Victor Stinner8c62be82010-05-06 00:08:46 +00005457PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005458"closerange(fd_low, fd_high)\n\n\
5459Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5460
5461static PyObject *
5462posix_closerange(PyObject *self, PyObject *args)
5463{
Victor Stinner8c62be82010-05-06 00:08:46 +00005464 int fd_from, fd_to, i;
5465 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5466 return NULL;
5467 Py_BEGIN_ALLOW_THREADS
5468 for (i = fd_from; i < fd_to; i++)
5469 if (_PyVerify_fd(i))
5470 close(i);
5471 Py_END_ALLOW_THREADS
5472 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005473}
5474
5475
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005476PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005477"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005478Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005479
Barry Warsaw53699e91996-12-10 23:23:01 +00005480static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005481posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005482{
Victor Stinner8c62be82010-05-06 00:08:46 +00005483 int fd;
5484 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5485 return NULL;
5486 if (!_PyVerify_fd(fd))
5487 return posix_error();
5488 Py_BEGIN_ALLOW_THREADS
5489 fd = dup(fd);
5490 Py_END_ALLOW_THREADS
5491 if (fd < 0)
5492 return posix_error();
5493 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005494}
5495
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005496
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005497PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005498"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005499Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005500
Barry Warsaw53699e91996-12-10 23:23:01 +00005501static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005502posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005503{
Victor Stinner8c62be82010-05-06 00:08:46 +00005504 int fd, fd2, res;
5505 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5506 return NULL;
5507 if (!_PyVerify_fd_dup2(fd, fd2))
5508 return posix_error();
5509 Py_BEGIN_ALLOW_THREADS
5510 res = dup2(fd, fd2);
5511 Py_END_ALLOW_THREADS
5512 if (res < 0)
5513 return posix_error();
5514 Py_INCREF(Py_None);
5515 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005516}
5517
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005518
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005519PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005520"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005521Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005522
Barry Warsaw53699e91996-12-10 23:23:01 +00005523static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005524posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005525{
Victor Stinner8c62be82010-05-06 00:08:46 +00005526 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005527#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005528 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005529#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005530 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005531#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005532 PyObject *posobj;
5533 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5534 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005535#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005536 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5537 switch (how) {
5538 case 0: how = SEEK_SET; break;
5539 case 1: how = SEEK_CUR; break;
5540 case 2: how = SEEK_END; break;
5541 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005542#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005543
5544#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005545 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005546#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005547 pos = PyLong_Check(posobj) ?
5548 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005549#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005550 if (PyErr_Occurred())
5551 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005552
Victor Stinner8c62be82010-05-06 00:08:46 +00005553 if (!_PyVerify_fd(fd))
5554 return posix_error();
5555 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005556#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005557 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005558#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005559 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005560#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005561 Py_END_ALLOW_THREADS
5562 if (res < 0)
5563 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005564
5565#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005566 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005567#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005568 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005569#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005570}
5571
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005572
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005573PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005574"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005575Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005576
Barry Warsaw53699e91996-12-10 23:23:01 +00005577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005578posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005579{
Victor Stinner8c62be82010-05-06 00:08:46 +00005580 int fd, size;
5581 Py_ssize_t n;
5582 PyObject *buffer;
5583 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5584 return NULL;
5585 if (size < 0) {
5586 errno = EINVAL;
5587 return posix_error();
5588 }
5589 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5590 if (buffer == NULL)
5591 return NULL;
5592 if (!_PyVerify_fd(fd))
5593 return posix_error();
5594 Py_BEGIN_ALLOW_THREADS
5595 n = read(fd, PyBytes_AS_STRING(buffer), size);
5596 Py_END_ALLOW_THREADS
5597 if (n < 0) {
5598 Py_DECREF(buffer);
5599 return posix_error();
5600 }
5601 if (n != size)
5602 _PyBytes_Resize(&buffer, n);
5603 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005604}
5605
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005606
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005607PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005608"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005609Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005610
Barry Warsaw53699e91996-12-10 23:23:01 +00005611static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005612posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005613{
Victor Stinner8c62be82010-05-06 00:08:46 +00005614 Py_buffer pbuf;
5615 int fd;
5616 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005617
Victor Stinner8c62be82010-05-06 00:08:46 +00005618 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5619 return NULL;
5620 if (!_PyVerify_fd(fd))
5621 return posix_error();
5622 Py_BEGIN_ALLOW_THREADS
5623 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5624 Py_END_ALLOW_THREADS
5625 PyBuffer_Release(&pbuf);
5626 if (size < 0)
5627 return posix_error();
5628 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005629}
5630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005631
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005632PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005633"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005634Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005635
Barry Warsaw53699e91996-12-10 23:23:01 +00005636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005637posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005638{
Victor Stinner8c62be82010-05-06 00:08:46 +00005639 int fd;
5640 STRUCT_STAT st;
5641 int res;
5642 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5643 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005644#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005645 /* on OpenVMS we must ensure that all bytes are written to the file */
5646 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005647#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005648 if (!_PyVerify_fd(fd))
5649 return posix_error();
5650 Py_BEGIN_ALLOW_THREADS
5651 res = FSTAT(fd, &st);
5652 Py_END_ALLOW_THREADS
5653 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005654#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005655 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005656#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005657 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005658#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005659 }
Tim Peters5aa91602002-01-30 05:46:57 +00005660
Victor Stinner8c62be82010-05-06 00:08:46 +00005661 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005662}
5663
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005664PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005665"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005666Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005667connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005668
5669static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005670posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005671{
Victor Stinner8c62be82010-05-06 00:08:46 +00005672 int fd;
5673 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5674 return NULL;
5675 if (!_PyVerify_fd(fd))
5676 return PyBool_FromLong(0);
5677 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005678}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005679
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005680#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005681PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005682"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005683Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005684
Barry Warsaw53699e91996-12-10 23:23:01 +00005685static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005686posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005687{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005688#if defined(PYOS_OS2)
5689 HFILE read, write;
5690 APIRET rc;
5691
Victor Stinner8c62be82010-05-06 00:08:46 +00005692 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005693 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005694 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005695 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005696 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005697
5698 return Py_BuildValue("(ii)", read, write);
5699#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005700#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005701 int fds[2];
5702 int res;
5703 Py_BEGIN_ALLOW_THREADS
5704 res = pipe(fds);
5705 Py_END_ALLOW_THREADS
5706 if (res != 0)
5707 return posix_error();
5708 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005709#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005710 HANDLE read, write;
5711 int read_fd, write_fd;
5712 BOOL ok;
5713 Py_BEGIN_ALLOW_THREADS
5714 ok = CreatePipe(&read, &write, NULL, 0);
5715 Py_END_ALLOW_THREADS
5716 if (!ok)
5717 return win32_error("CreatePipe", NULL);
5718 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5719 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5720 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005721#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005722#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005723}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005724#endif /* HAVE_PIPE */
5725
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005726
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005727#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005728PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005729"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005730Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005731
Barry Warsaw53699e91996-12-10 23:23:01 +00005732static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005733posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005734{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005735 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005736 char *filename;
5737 int mode = 0666;
5738 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005739 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5740 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00005741 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005742 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005743 Py_BEGIN_ALLOW_THREADS
5744 res = mkfifo(filename, mode);
5745 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005746 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005747 if (res < 0)
5748 return posix_error();
5749 Py_INCREF(Py_None);
5750 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005751}
5752#endif
5753
5754
Neal Norwitz11690112002-07-30 01:08:28 +00005755#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005756PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005757"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005758Create a filesystem node (file, device special file or named pipe)\n\
5759named filename. mode specifies both the permissions to use and the\n\
5760type of node to be created, being combined (bitwise OR) with one of\n\
5761S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005762device defines the newly created device special file (probably using\n\
5763os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005764
5765
5766static PyObject *
5767posix_mknod(PyObject *self, PyObject *args)
5768{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005769 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005770 char *filename;
5771 int mode = 0600;
5772 int device = 0;
5773 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005774 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5775 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00005776 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005777 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005778 Py_BEGIN_ALLOW_THREADS
5779 res = mknod(filename, mode, device);
5780 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005781 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005782 if (res < 0)
5783 return posix_error();
5784 Py_INCREF(Py_None);
5785 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005786}
5787#endif
5788
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005789#ifdef HAVE_DEVICE_MACROS
5790PyDoc_STRVAR(posix_major__doc__,
5791"major(device) -> major number\n\
5792Extracts a device major number from a raw device number.");
5793
5794static PyObject *
5795posix_major(PyObject *self, PyObject *args)
5796{
Victor Stinner8c62be82010-05-06 00:08:46 +00005797 int device;
5798 if (!PyArg_ParseTuple(args, "i:major", &device))
5799 return NULL;
5800 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005801}
5802
5803PyDoc_STRVAR(posix_minor__doc__,
5804"minor(device) -> minor number\n\
5805Extracts a device minor number from a raw device number.");
5806
5807static PyObject *
5808posix_minor(PyObject *self, PyObject *args)
5809{
Victor Stinner8c62be82010-05-06 00:08:46 +00005810 int device;
5811 if (!PyArg_ParseTuple(args, "i:minor", &device))
5812 return NULL;
5813 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005814}
5815
5816PyDoc_STRVAR(posix_makedev__doc__,
5817"makedev(major, minor) -> device number\n\
5818Composes a raw device number from the major and minor device numbers.");
5819
5820static PyObject *
5821posix_makedev(PyObject *self, PyObject *args)
5822{
Victor Stinner8c62be82010-05-06 00:08:46 +00005823 int major, minor;
5824 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5825 return NULL;
5826 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005827}
5828#endif /* device macros */
5829
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005830
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005831#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005832PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005833"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005834Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005835
Barry Warsaw53699e91996-12-10 23:23:01 +00005836static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005837posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005838{
Victor Stinner8c62be82010-05-06 00:08:46 +00005839 int fd;
5840 off_t length;
5841 int res;
5842 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005843
Victor Stinner8c62be82010-05-06 00:08:46 +00005844 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5845 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005846
5847#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005848 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005849#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005850 length = PyLong_Check(lenobj) ?
5851 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005852#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005853 if (PyErr_Occurred())
5854 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005855
Victor Stinner8c62be82010-05-06 00:08:46 +00005856 Py_BEGIN_ALLOW_THREADS
5857 res = ftruncate(fd, length);
5858 Py_END_ALLOW_THREADS
5859 if (res < 0)
5860 return posix_error();
5861 Py_INCREF(Py_None);
5862 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005863}
5864#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005865
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005866#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005867PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005868"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005869Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005870
Fred Drake762e2061999-08-26 17:23:54 +00005871/* Save putenv() parameters as values here, so we can collect them when they
5872 * get re-set with another call for the same key. */
5873static PyObject *posix_putenv_garbage;
5874
Tim Peters5aa91602002-01-30 05:46:57 +00005875static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005876posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005877{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005878#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005879 wchar_t *s1, *s2;
5880 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005881#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005882 PyObject *os1, *os2;
5883 char *s1, *s2;
5884 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005885#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005886 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005887 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005888
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005889#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005890 if (!PyArg_ParseTuple(args,
5891 "uu:putenv",
5892 &s1, &s2))
5893 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005894#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005895 if (!PyArg_ParseTuple(args,
5896 "O&O&:putenv",
5897 PyUnicode_FSConverter, &os1,
5898 PyUnicode_FSConverter, &os2))
5899 return NULL;
5900 s1 = PyBytes_AsString(os1);
5901 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005902#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005903
5904#if defined(PYOS_OS2)
5905 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5906 APIRET rc;
5907
Guido van Rossumd48f2521997-12-05 22:19:34 +00005908 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005909 if (rc != NO_ERROR) {
5910 os2_error(rc);
5911 goto error;
5912 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005913
5914 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5915 APIRET rc;
5916
Guido van Rossumd48f2521997-12-05 22:19:34 +00005917 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005918 if (rc != NO_ERROR) {
5919 os2_error(rc);
5920 goto error;
5921 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005922 } else {
5923#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005924 /* XXX This can leak memory -- not easy to fix :-( */
5925 /* len includes space for a trailing \0; the size arg to
5926 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005927#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005928 len = wcslen(s1) + wcslen(s2) + 2;
5929 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005930#else
Victor Stinner84ae1182010-05-06 22:05:07 +00005931 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005933#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005934 if (newstr == NULL) {
5935 PyErr_NoMemory();
5936 goto error;
5937 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005938#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005939 newenv = PyUnicode_AsUnicode(newstr);
5940 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5941 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005942 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005943 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005944 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005945#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005946 newenv = PyBytes_AS_STRING(newstr);
5947 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5948 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005949 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005950 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005951 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005952#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005953
Victor Stinner8c62be82010-05-06 00:08:46 +00005954 /* Install the first arg and newstr in posix_putenv_garbage;
5955 * this will cause previous value to be collected. This has to
5956 * happen after the real putenv() call because the old value
5957 * was still accessible until then. */
5958 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00005959#ifdef MS_WINDOWS
5960 PyTuple_GET_ITEM(args, 0),
5961#else
5962 os1,
5963#endif
5964 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005965 /* really not much we can do; just leak */
5966 PyErr_Clear();
5967 }
5968 else {
5969 Py_DECREF(newstr);
5970 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005971
5972#if defined(PYOS_OS2)
5973 }
5974#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005975
Martin v. Löwis011e8422009-05-05 04:43:17 +00005976#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005977 Py_DECREF(os1);
5978 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005979#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005980 Py_RETURN_NONE;
5981
5982error:
5983#ifndef MS_WINDOWS
5984 Py_DECREF(os1);
5985 Py_DECREF(os2);
5986#endif
5987 Py_XDECREF(newstr);
5988 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005989}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005990#endif /* putenv */
5991
Guido van Rossumc524d952001-10-19 01:31:59 +00005992#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005993PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005994"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005995Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005996
5997static PyObject *
5998posix_unsetenv(PyObject *self, PyObject *args)
5999{
Victor Stinner84ae1182010-05-06 22:05:07 +00006000#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006001 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006002
Victor Stinner8c62be82010-05-06 00:08:46 +00006003 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6004 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00006005#else
6006 PyObject *os1;
6007 char *s1;
6008
6009 if (!PyArg_ParseTuple(args, "O&:unsetenv",
6010 PyUnicode_FSConverter, &os1))
6011 return NULL;
6012 s1 = PyBytes_AsString(os1);
6013#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006014
Victor Stinner8c62be82010-05-06 00:08:46 +00006015 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006016
Victor Stinner8c62be82010-05-06 00:08:46 +00006017 /* Remove the key from posix_putenv_garbage;
6018 * this will cause it to be collected. This has to
6019 * happen after the real unsetenv() call because the
6020 * old value was still accessible until then.
6021 */
6022 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006023#ifdef MS_WINDOWS
6024 PyTuple_GET_ITEM(args, 0)
6025#else
6026 os1
6027#endif
6028 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006029 /* really not much we can do; just leak */
6030 PyErr_Clear();
6031 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006032
Victor Stinner84ae1182010-05-06 22:05:07 +00006033#ifndef MS_WINDOWS
6034 Py_DECREF(os1);
6035#endif
6036 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00006037}
6038#endif /* unsetenv */
6039
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006040PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006041"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006042Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006043
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006045posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006046{
Victor Stinner8c62be82010-05-06 00:08:46 +00006047 int code;
6048 char *message;
6049 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6050 return NULL;
6051 message = strerror(code);
6052 if (message == NULL) {
6053 PyErr_SetString(PyExc_ValueError,
6054 "strerror() argument out of range");
6055 return NULL;
6056 }
6057 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006058}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006059
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006060
Guido van Rossumc9641791998-08-04 15:26:23 +00006061#ifdef HAVE_SYS_WAIT_H
6062
Fred Drake106c1a02002-04-23 15:58:02 +00006063#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006064PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006065"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006066Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006067
6068static PyObject *
6069posix_WCOREDUMP(PyObject *self, PyObject *args)
6070{
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 WAIT_TYPE status;
6072 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006073
Victor Stinner8c62be82010-05-06 00:08:46 +00006074 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6075 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006076
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006078}
6079#endif /* WCOREDUMP */
6080
6081#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006082PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006083"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006084Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006085job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006086
6087static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006088posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006089{
Victor Stinner8c62be82010-05-06 00:08:46 +00006090 WAIT_TYPE status;
6091 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006092
Victor Stinner8c62be82010-05-06 00:08:46 +00006093 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6094 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006095
Victor Stinner8c62be82010-05-06 00:08:46 +00006096 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006097}
6098#endif /* WIFCONTINUED */
6099
Guido van Rossumc9641791998-08-04 15:26:23 +00006100#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006101PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006102"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006103Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006104
6105static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006106posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006107{
Victor Stinner8c62be82010-05-06 00:08:46 +00006108 WAIT_TYPE status;
6109 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006110
Victor Stinner8c62be82010-05-06 00:08:46 +00006111 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6112 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006113
Victor Stinner8c62be82010-05-06 00:08:46 +00006114 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006115}
6116#endif /* WIFSTOPPED */
6117
6118#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006119PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006120"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006121Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006122
6123static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006124posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006125{
Victor Stinner8c62be82010-05-06 00:08:46 +00006126 WAIT_TYPE status;
6127 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006128
Victor Stinner8c62be82010-05-06 00:08:46 +00006129 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6130 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006131
Victor Stinner8c62be82010-05-06 00:08:46 +00006132 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006133}
6134#endif /* WIFSIGNALED */
6135
6136#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006137PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006138"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006139Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006140system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006141
6142static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006143posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006144{
Victor Stinner8c62be82010-05-06 00:08:46 +00006145 WAIT_TYPE status;
6146 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006147
Victor Stinner8c62be82010-05-06 00:08:46 +00006148 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6149 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006150
Victor Stinner8c62be82010-05-06 00:08:46 +00006151 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006152}
6153#endif /* WIFEXITED */
6154
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006155#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006156PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006157"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006158Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006159
6160static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006161posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006162{
Victor Stinner8c62be82010-05-06 00:08:46 +00006163 WAIT_TYPE status;
6164 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006165
Victor Stinner8c62be82010-05-06 00:08:46 +00006166 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6167 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006168
Victor Stinner8c62be82010-05-06 00:08:46 +00006169 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006170}
6171#endif /* WEXITSTATUS */
6172
6173#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006174PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006175"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006176Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006177value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006178
6179static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006180posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006181{
Victor Stinner8c62be82010-05-06 00:08:46 +00006182 WAIT_TYPE status;
6183 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006184
Victor Stinner8c62be82010-05-06 00:08:46 +00006185 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6186 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006187
Victor Stinner8c62be82010-05-06 00:08:46 +00006188 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006189}
6190#endif /* WTERMSIG */
6191
6192#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006193PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006194"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006195Return the signal that stopped the process that provided\n\
6196the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006197
6198static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006199posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006200{
Victor Stinner8c62be82010-05-06 00:08:46 +00006201 WAIT_TYPE status;
6202 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006203
Victor Stinner8c62be82010-05-06 00:08:46 +00006204 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6205 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006206
Victor Stinner8c62be82010-05-06 00:08:46 +00006207 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006208}
6209#endif /* WSTOPSIG */
6210
6211#endif /* HAVE_SYS_WAIT_H */
6212
6213
Thomas Wouters477c8d52006-05-27 19:21:47 +00006214#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006215#ifdef _SCO_DS
6216/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6217 needed definitions in sys/statvfs.h */
6218#define _SVID3
6219#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006220#include <sys/statvfs.h>
6221
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006222static PyObject*
6223_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006224 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6225 if (v == NULL)
6226 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006227
6228#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006229 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6230 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6231 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6232 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6233 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6234 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6235 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6236 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6237 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6238 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006239#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006240 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6241 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6242 PyStructSequence_SET_ITEM(v, 2,
6243 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6244 PyStructSequence_SET_ITEM(v, 3,
6245 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6246 PyStructSequence_SET_ITEM(v, 4,
6247 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6248 PyStructSequence_SET_ITEM(v, 5,
6249 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6250 PyStructSequence_SET_ITEM(v, 6,
6251 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6252 PyStructSequence_SET_ITEM(v, 7,
6253 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6254 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6255 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006256#endif
6257
Victor Stinner8c62be82010-05-06 00:08:46 +00006258 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006259}
6260
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006261PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006262"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006263Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006264
6265static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006266posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006267{
Victor Stinner8c62be82010-05-06 00:08:46 +00006268 int fd, res;
6269 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006270
Victor Stinner8c62be82010-05-06 00:08:46 +00006271 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6272 return NULL;
6273 Py_BEGIN_ALLOW_THREADS
6274 res = fstatvfs(fd, &st);
6275 Py_END_ALLOW_THREADS
6276 if (res != 0)
6277 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006278
Victor Stinner8c62be82010-05-06 00:08:46 +00006279 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006280}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006281#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006282
6283
Thomas Wouters477c8d52006-05-27 19:21:47 +00006284#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006285#include <sys/statvfs.h>
6286
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006287PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006288"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006289Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006290
6291static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006292posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006293{
Victor Stinner8c62be82010-05-06 00:08:46 +00006294 char *path;
6295 int res;
6296 struct statvfs st;
6297 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6298 return NULL;
6299 Py_BEGIN_ALLOW_THREADS
6300 res = statvfs(path, &st);
6301 Py_END_ALLOW_THREADS
6302 if (res != 0)
6303 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006304
Victor Stinner8c62be82010-05-06 00:08:46 +00006305 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006306}
6307#endif /* HAVE_STATVFS */
6308
Fred Drakec9680921999-12-13 16:37:25 +00006309/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6310 * It maps strings representing configuration variable names to
6311 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006312 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006313 * rarely-used constants. There are three separate tables that use
6314 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006315 *
6316 * This code is always included, even if none of the interfaces that
6317 * need it are included. The #if hackery needed to avoid it would be
6318 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006319 */
6320struct constdef {
6321 char *name;
6322 long value;
6323};
6324
Fred Drake12c6e2d1999-12-14 21:25:03 +00006325static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006326conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006327 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006328{
Christian Heimes217cfd12007-12-02 14:31:20 +00006329 if (PyLong_Check(arg)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006330 *valuep = PyLong_AS_LONG(arg);
6331 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006332 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006333 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00006334 /* look up the value in the table using a binary search */
6335 size_t lo = 0;
6336 size_t mid;
6337 size_t hi = tablesize;
6338 int cmp;
6339 const char *confname;
6340 if (!PyUnicode_Check(arg)) {
6341 PyErr_SetString(PyExc_TypeError,
6342 "configuration names must be strings or integers");
Guido van Rossumbce56a62007-05-10 18:04:33 +00006343 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006344 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006345 confname = _PyUnicode_AsString(arg);
6346 if (confname == NULL)
6347 return 0;
6348 while (lo < hi) {
6349 mid = (lo + hi) / 2;
6350 cmp = strcmp(confname, table[mid].name);
6351 if (cmp < 0)
6352 hi = mid;
6353 else if (cmp > 0)
6354 lo = mid + 1;
6355 else {
6356 *valuep = table[mid].value;
6357 return 1;
6358 }
6359 }
6360 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6361 return 0;
6362 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006363}
6364
6365
6366#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6367static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006368#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006369 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006370#endif
6371#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006372 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006373#endif
Fred Drakec9680921999-12-13 16:37:25 +00006374#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006375 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006376#endif
6377#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006378 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006379#endif
6380#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006382#endif
6383#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006385#endif
6386#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006387 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006388#endif
6389#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006390 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006391#endif
6392#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006393 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006394#endif
6395#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006396 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006397#endif
6398#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006400#endif
6401#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006402 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006403#endif
6404#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006406#endif
6407#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006408 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006409#endif
6410#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006411 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006412#endif
6413#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006414 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006415#endif
6416#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006417 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006418#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00006419#ifdef _PC_ACL_ENABLED
6420 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
6421#endif
6422#ifdef _PC_MIN_HOLE_SIZE
6423 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
6424#endif
6425#ifdef _PC_ALLOC_SIZE_MIN
6426 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
6427#endif
6428#ifdef _PC_REC_INCR_XFER_SIZE
6429 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
6430#endif
6431#ifdef _PC_REC_MAX_XFER_SIZE
6432 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
6433#endif
6434#ifdef _PC_REC_MIN_XFER_SIZE
6435 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
6436#endif
6437#ifdef _PC_REC_XFER_ALIGN
6438 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
6439#endif
6440#ifdef _PC_SYMLINK_MAX
6441 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
6442#endif
6443#ifdef _PC_XATTR_ENABLED
6444 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
6445#endif
6446#ifdef _PC_XATTR_EXISTS
6447 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
6448#endif
6449#ifdef _PC_TIMESTAMP_RESOLUTION
6450 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
6451#endif
Fred Drakec9680921999-12-13 16:37:25 +00006452};
6453
Fred Drakec9680921999-12-13 16:37:25 +00006454static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006455conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006456{
6457 return conv_confname(arg, valuep, posix_constants_pathconf,
6458 sizeof(posix_constants_pathconf)
6459 / sizeof(struct constdef));
6460}
6461#endif
6462
6463#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006464PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006465"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006466Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006467If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006468
6469static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006470posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006471{
6472 PyObject *result = NULL;
6473 int name, fd;
6474
Fred Drake12c6e2d1999-12-14 21:25:03 +00006475 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6476 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006478
Victor Stinner8c62be82010-05-06 00:08:46 +00006479 errno = 0;
6480 limit = fpathconf(fd, name);
6481 if (limit == -1 && errno != 0)
6482 posix_error();
6483 else
6484 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006485 }
6486 return result;
6487}
6488#endif
6489
6490
6491#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006492PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006493"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006494Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006495If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006496
6497static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006498posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006499{
6500 PyObject *result = NULL;
6501 int name;
6502 char *path;
6503
6504 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6505 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006507
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 errno = 0;
6509 limit = pathconf(path, name);
6510 if (limit == -1 && errno != 0) {
6511 if (errno == EINVAL)
6512 /* could be a path or name problem */
6513 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006514 else
Victor Stinner8c62be82010-05-06 00:08:46 +00006515 posix_error_with_filename(path);
6516 }
6517 else
6518 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006519 }
6520 return result;
6521}
6522#endif
6523
6524#ifdef HAVE_CONFSTR
6525static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006526#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006527 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006528#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006529#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006530 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006531#endif
6532#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006533 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006534#endif
Fred Draked86ed291999-12-15 15:34:33 +00006535#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006536 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006537#endif
6538#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006540#endif
6541#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006543#endif
6544#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006545 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006546#endif
Fred Drakec9680921999-12-13 16:37:25 +00006547#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006548 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006549#endif
6550#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006552#endif
6553#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006555#endif
6556#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006557 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006558#endif
6559#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006561#endif
6562#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006564#endif
6565#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006566 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006567#endif
6568#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006569 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006570#endif
Fred Draked86ed291999-12-15 15:34:33 +00006571#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006572 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006573#endif
Fred Drakec9680921999-12-13 16:37:25 +00006574#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006576#endif
Fred Draked86ed291999-12-15 15:34:33 +00006577#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006579#endif
6580#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006582#endif
6583#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006584 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006585#endif
6586#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006587 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006588#endif
Fred Drakec9680921999-12-13 16:37:25 +00006589#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006591#endif
6592#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006593 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006594#endif
6595#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006597#endif
6598#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006600#endif
6601#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006602 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006603#endif
6604#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006606#endif
6607#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006609#endif
6610#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006611 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006612#endif
6613#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006614 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006615#endif
6616#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006617 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006618#endif
6619#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006620 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006621#endif
6622#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006623 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006624#endif
6625#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006626 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006627#endif
6628#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006629 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006630#endif
6631#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006632 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006633#endif
6634#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006635 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006636#endif
Fred Draked86ed291999-12-15 15:34:33 +00006637#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006638 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006639#endif
6640#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006641 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006642#endif
6643#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006645#endif
6646#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006647 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006648#endif
6649#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006650 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006651#endif
6652#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006653 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006654#endif
6655#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006656 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006657#endif
6658#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006660#endif
6661#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006662 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006663#endif
6664#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006666#endif
6667#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006668 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006669#endif
6670#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006671 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006672#endif
6673#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006674 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006675#endif
Fred Drakec9680921999-12-13 16:37:25 +00006676};
6677
6678static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006679conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006680{
6681 return conv_confname(arg, valuep, posix_constants_confstr,
6682 sizeof(posix_constants_confstr)
6683 / sizeof(struct constdef));
6684}
6685
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006686PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006687"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006688Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006689
6690static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006691posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006692{
6693 PyObject *result = NULL;
6694 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00006695 char buffer[255];
Victor Stinner8c62be82010-05-06 00:08:46 +00006696 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006697
Victor Stinnercb043522010-09-10 23:49:04 +00006698 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
6699 return NULL;
6700
6701 errno = 0;
6702 len = confstr(name, buffer, sizeof(buffer));
6703 if (len == 0) {
6704 if (errno) {
6705 posix_error();
6706 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00006707 }
6708 else {
Victor Stinnercb043522010-09-10 23:49:04 +00006709 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00006710 }
6711 }
Victor Stinnercb043522010-09-10 23:49:04 +00006712
6713 if ((unsigned int)len >= sizeof(buffer)) {
6714 char *buf = PyMem_Malloc(len);
6715 if (buf == NULL)
6716 return PyErr_NoMemory();
6717 confstr(name, buf, len);
6718 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
6719 PyMem_Free(buf);
6720 }
6721 else
6722 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006723 return result;
6724}
6725#endif
6726
6727
6728#ifdef HAVE_SYSCONF
6729static struct constdef posix_constants_sysconf[] = {
6730#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006731 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006732#endif
6733#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006735#endif
6736#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006738#endif
6739#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006741#endif
6742#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006743 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006744#endif
6745#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006746 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006747#endif
6748#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006749 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006750#endif
6751#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006752 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006753#endif
6754#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006755 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006756#endif
6757#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006758 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006759#endif
Fred Draked86ed291999-12-15 15:34:33 +00006760#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006762#endif
6763#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006764 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006765#endif
Fred Drakec9680921999-12-13 16:37:25 +00006766#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006767 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006768#endif
Fred Drakec9680921999-12-13 16:37:25 +00006769#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006770 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006771#endif
6772#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006774#endif
6775#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006776 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006777#endif
6778#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006780#endif
6781#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006783#endif
Fred Draked86ed291999-12-15 15:34:33 +00006784#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006786#endif
Fred Drakec9680921999-12-13 16:37:25 +00006787#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006788 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006789#endif
6790#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006792#endif
6793#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006795#endif
6796#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006798#endif
6799#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006801#endif
Fred Draked86ed291999-12-15 15:34:33 +00006802#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006804#endif
Fred Drakec9680921999-12-13 16:37:25 +00006805#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006807#endif
6808#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006810#endif
6811#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006813#endif
6814#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006815 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006816#endif
6817#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006818 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006819#endif
6820#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006822#endif
6823#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006825#endif
6826#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006827 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006828#endif
6829#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006831#endif
6832#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006833 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006834#endif
6835#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006836 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006837#endif
6838#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006840#endif
6841#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006843#endif
6844#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006846#endif
6847#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006848 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006849#endif
6850#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006852#endif
6853#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006854 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006855#endif
6856#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006858#endif
6859#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006860 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006861#endif
6862#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006864#endif
6865#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006867#endif
6868#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006870#endif
6871#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006873#endif
Fred Draked86ed291999-12-15 15:34:33 +00006874#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00006875 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006876#endif
Fred Drakec9680921999-12-13 16:37:25 +00006877#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006879#endif
6880#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006881 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006882#endif
6883#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006885#endif
Fred Draked86ed291999-12-15 15:34:33 +00006886#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006888#endif
Fred Drakec9680921999-12-13 16:37:25 +00006889#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00006890 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006891#endif
Fred Draked86ed291999-12-15 15:34:33 +00006892#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006894#endif
6895#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00006896 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006897#endif
Fred Drakec9680921999-12-13 16:37:25 +00006898#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006899 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006900#endif
6901#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006902 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006903#endif
6904#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006905 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006906#endif
6907#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006909#endif
Fred Draked86ed291999-12-15 15:34:33 +00006910#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006912#endif
Fred Drakec9680921999-12-13 16:37:25 +00006913#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00006914 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006915#endif
6916#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00006917 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006918#endif
6919#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006920 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006921#endif
6922#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006923 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006924#endif
6925#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006927#endif
6928#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00006929 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006930#endif
6931#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00006932 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006933#endif
Fred Draked86ed291999-12-15 15:34:33 +00006934#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006936#endif
Fred Drakec9680921999-12-13 16:37:25 +00006937#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006939#endif
6940#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006941 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006942#endif
Fred Draked86ed291999-12-15 15:34:33 +00006943#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006945#endif
Fred Drakec9680921999-12-13 16:37:25 +00006946#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006947 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006948#endif
6949#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006950 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006951#endif
6952#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006954#endif
6955#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006956 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006957#endif
6958#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006959 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006960#endif
6961#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006962 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006963#endif
6964#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006965 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006966#endif
6967#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006968 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00006969#endif
6970#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00006972#endif
Fred Draked86ed291999-12-15 15:34:33 +00006973#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00006975#endif
6976#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006977 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00006978#endif
Fred Drakec9680921999-12-13 16:37:25 +00006979#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00006980 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00006981#endif
6982#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006983 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006984#endif
6985#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006987#endif
6988#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006989 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006990#endif
6991#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006993#endif
6994#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006995 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006996#endif
6997#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00006998 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00006999#endif
7000#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00007001 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00007002#endif
7003#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007004 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00007005#endif
7006#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007007 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00007008#endif
7009#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00007010 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00007011#endif
7012#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007013 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00007014#endif
7015#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007016 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00007017#endif
7018#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00007019 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00007020#endif
7021#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00007022 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00007023#endif
7024#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00007025 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00007026#endif
7027#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00007028 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00007029#endif
7030#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007031 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007032#endif
7033#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007035#endif
7036#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00007037 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00007038#endif
7039#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007040 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007041#endif
7042#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007044#endif
7045#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00007047#endif
7048#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007049 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007050#endif
7051#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007052 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007053#endif
7054#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007055 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00007056#endif
7057#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00007058 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00007059#endif
7060#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007061 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007062#endif
7063#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007064 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007065#endif
7066#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007067 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00007068#endif
7069#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007070 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007071#endif
7072#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007073 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007074#endif
7075#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007076 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007077#endif
7078#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007079 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007080#endif
7081#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007082 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007083#endif
Fred Draked86ed291999-12-15 15:34:33 +00007084#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00007085 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00007086#endif
Fred Drakec9680921999-12-13 16:37:25 +00007087#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00007088 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00007089#endif
7090#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007091 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007092#endif
7093#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00007095#endif
7096#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007098#endif
7099#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007100 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007101#endif
7102#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007103 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007104#endif
7105#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00007106 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00007107#endif
7108#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007109 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007110#endif
7111#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007112 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007113#endif
7114#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007115 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007116#endif
7117#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007118 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007119#endif
7120#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007121 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00007122#endif
7123#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007124 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00007125#endif
7126#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00007127 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00007128#endif
7129#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007130 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007131#endif
7132#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007133 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007134#endif
7135#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007136 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007137#endif
7138#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007139 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007140#endif
7141#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007142 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007143#endif
7144#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007145 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007146#endif
7147#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007148 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007149#endif
7150#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007151 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007152#endif
7153#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007154 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007155#endif
7156#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007157 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007158#endif
7159#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007160 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007161#endif
7162#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007163 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007164#endif
7165#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007166 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007167#endif
7168#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007169 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007170#endif
7171#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007172 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007173#endif
7174#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007175 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007176#endif
7177#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007178 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007179#endif
7180#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007181 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007182#endif
7183#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007184 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007185#endif
7186#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007187 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007188#endif
7189#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007190 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007191#endif
7192#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007193 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007194#endif
7195#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007196 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007197#endif
7198#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007199 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007200#endif
7201#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007202 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007203#endif
7204#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007205 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007206#endif
7207#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007208 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007209#endif
7210#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007211 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007212#endif
7213#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007214 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007215#endif
7216#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007217 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007218#endif
7219#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007220 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007221#endif
7222};
7223
7224static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007225conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007226{
7227 return conv_confname(arg, valuep, posix_constants_sysconf,
7228 sizeof(posix_constants_sysconf)
7229 / sizeof(struct constdef));
7230}
7231
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007232PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007233"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007234Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007235
7236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007237posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007238{
7239 PyObject *result = NULL;
7240 int name;
7241
7242 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7243 int value;
7244
7245 errno = 0;
7246 value = sysconf(name);
7247 if (value == -1 && errno != 0)
7248 posix_error();
7249 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007250 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007251 }
7252 return result;
7253}
7254#endif
7255
7256
Fred Drakebec628d1999-12-15 18:31:10 +00007257/* This code is used to ensure that the tables of configuration value names
7258 * are in sorted order as required by conv_confname(), and also to build the
7259 * the exported dictionaries that are used to publish information about the
7260 * names available on the host platform.
7261 *
7262 * Sorting the table at runtime ensures that the table is properly ordered
7263 * when used, even for platforms we're not able to test on. It also makes
7264 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007265 */
Fred Drakebec628d1999-12-15 18:31:10 +00007266
7267static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007268cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007269{
7270 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007271 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007272 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007273 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007274
7275 return strcmp(c1->name, c2->name);
7276}
7277
7278static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007279setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007280 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007281{
Fred Drakebec628d1999-12-15 18:31:10 +00007282 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007283 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007284
7285 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7286 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007287 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007288 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007289
Barry Warsaw3155db32000-04-13 15:20:40 +00007290 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007291 PyObject *o = PyLong_FromLong(table[i].value);
7292 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7293 Py_XDECREF(o);
7294 Py_DECREF(d);
7295 return -1;
7296 }
7297 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007298 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007299 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007300}
7301
Fred Drakebec628d1999-12-15 18:31:10 +00007302/* Return -1 on failure, 0 on success. */
7303static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007304setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007305{
7306#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007307 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007308 sizeof(posix_constants_pathconf)
7309 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007310 "pathconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007311 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007312#endif
7313#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007314 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007315 sizeof(posix_constants_confstr)
7316 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007317 "confstr_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007318 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007319#endif
7320#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007321 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007322 sizeof(posix_constants_sysconf)
7323 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007324 "sysconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007325 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007326#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007327 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007328}
Fred Draked86ed291999-12-15 15:34:33 +00007329
7330
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007331PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007332"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007333Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007334in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007335
7336static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007337posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007338{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007339 abort();
7340 /*NOTREACHED*/
7341 Py_FatalError("abort() called from Python code didn't abort!");
7342 return NULL;
7343}
Fred Drakebec628d1999-12-15 18:31:10 +00007344
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007345#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007346PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007347"startfile(filepath [, operation]) - Start a file with its associated\n\
7348application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007349\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007350When \"operation\" is not specified or \"open\", this acts like\n\
7351double-clicking the file in Explorer, or giving the file name as an\n\
7352argument to the DOS \"start\" command: the file is opened with whatever\n\
7353application (if any) its extension is associated.\n\
7354When another \"operation\" is given, it specifies what should be done with\n\
7355the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007356\n\
7357startfile returns as soon as the associated application is launched.\n\
7358There is no option to wait for the application to close, and no way\n\
7359to retrieve the application's exit status.\n\
7360\n\
7361The filepath is relative to the current directory. If you want to use\n\
7362an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007363the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007364
7365static PyObject *
7366win32_startfile(PyObject *self, PyObject *args)
7367{
Victor Stinner8c62be82010-05-06 00:08:46 +00007368 PyObject *ofilepath;
7369 char *filepath;
7370 char *operation = NULL;
7371 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007372
Victor Stinner8c62be82010-05-06 00:08:46 +00007373 PyObject *unipath, *woperation = NULL;
7374 if (!PyArg_ParseTuple(args, "U|s:startfile",
7375 &unipath, &operation)) {
7376 PyErr_Clear();
7377 goto normal;
7378 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007379
Victor Stinner8c62be82010-05-06 00:08:46 +00007380 if (operation) {
7381 woperation = PyUnicode_DecodeASCII(operation,
7382 strlen(operation), NULL);
7383 if (!woperation) {
7384 PyErr_Clear();
7385 operation = NULL;
7386 goto normal;
7387 }
7388 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007389
Victor Stinner8c62be82010-05-06 00:08:46 +00007390 Py_BEGIN_ALLOW_THREADS
7391 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7392 PyUnicode_AS_UNICODE(unipath),
7393 NULL, NULL, SW_SHOWNORMAL);
7394 Py_END_ALLOW_THREADS
7395
7396 Py_XDECREF(woperation);
7397 if (rc <= (HINSTANCE)32) {
7398 PyObject *errval = win32_error_unicode("startfile",
7399 PyUnicode_AS_UNICODE(unipath));
7400 return errval;
7401 }
7402 Py_INCREF(Py_None);
7403 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007404
7405normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007406 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7407 PyUnicode_FSConverter, &ofilepath,
7408 &operation))
7409 return NULL;
7410 filepath = PyBytes_AsString(ofilepath);
7411 Py_BEGIN_ALLOW_THREADS
7412 rc = ShellExecute((HWND)0, operation, filepath,
7413 NULL, NULL, SW_SHOWNORMAL);
7414 Py_END_ALLOW_THREADS
7415 if (rc <= (HINSTANCE)32) {
7416 PyObject *errval = win32_error("startfile", filepath);
7417 Py_DECREF(ofilepath);
7418 return errval;
7419 }
7420 Py_DECREF(ofilepath);
7421 Py_INCREF(Py_None);
7422 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007423}
7424#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007425
Martin v. Löwis438b5342002-12-27 10:16:42 +00007426#ifdef HAVE_GETLOADAVG
7427PyDoc_STRVAR(posix_getloadavg__doc__,
7428"getloadavg() -> (float, float, float)\n\n\
7429Return the number of processes in the system run queue averaged over\n\
7430the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7431was unobtainable");
7432
7433static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007434posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007435{
7436 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007437 if (getloadavg(loadavg, 3)!=3) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007438 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7439 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007440 } else
Victor Stinner8c62be82010-05-06 00:08:46 +00007441 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007442}
7443#endif
7444
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007445#ifdef MS_WINDOWS
7446
7447PyDoc_STRVAR(win32_urandom__doc__,
7448"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007449Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007450
7451typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7452 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7453 DWORD dwFlags );
7454typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7455 BYTE *pbBuffer );
7456
7457static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007458/* This handle is never explicitly released. Instead, the operating
7459 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007460static HCRYPTPROV hCryptProv = 0;
7461
Tim Peters4ad82172004-08-30 17:02:04 +00007462static PyObject*
7463win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007464{
Victor Stinner8c62be82010-05-06 00:08:46 +00007465 int howMany;
7466 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007467
Victor Stinner8c62be82010-05-06 00:08:46 +00007468 /* Read arguments */
7469 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7470 return NULL;
7471 if (howMany < 0)
7472 return PyErr_Format(PyExc_ValueError,
7473 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007474
Victor Stinner8c62be82010-05-06 00:08:46 +00007475 if (hCryptProv == 0) {
7476 HINSTANCE hAdvAPI32 = NULL;
7477 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007478
Victor Stinner8c62be82010-05-06 00:08:46 +00007479 /* Obtain handle to the DLL containing CryptoAPI
7480 This should not fail */
7481 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7482 if(hAdvAPI32 == NULL)
7483 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007484
Victor Stinner8c62be82010-05-06 00:08:46 +00007485 /* Obtain pointers to the CryptoAPI functions
7486 This will fail on some early versions of Win95 */
7487 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7488 hAdvAPI32,
7489 "CryptAcquireContextA");
7490 if (pCryptAcquireContext == NULL)
7491 return PyErr_Format(PyExc_NotImplementedError,
7492 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007493
Victor Stinner8c62be82010-05-06 00:08:46 +00007494 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7495 hAdvAPI32, "CryptGenRandom");
7496 if (pCryptGenRandom == NULL)
7497 return PyErr_Format(PyExc_NotImplementedError,
7498 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007499
Victor Stinner8c62be82010-05-06 00:08:46 +00007500 /* Acquire context */
7501 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7502 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7503 return win32_error("CryptAcquireContext", NULL);
7504 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007505
Victor Stinner8c62be82010-05-06 00:08:46 +00007506 /* Allocate bytes */
7507 result = PyBytes_FromStringAndSize(NULL, howMany);
7508 if (result != NULL) {
7509 /* Get random data */
7510 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7511 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7512 PyBytes_AS_STRING(result))) {
7513 Py_DECREF(result);
7514 return win32_error("CryptGenRandom", NULL);
7515 }
7516 }
7517 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007518}
7519#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007520
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007521PyDoc_STRVAR(device_encoding__doc__,
7522"device_encoding(fd) -> str\n\n\
7523Return a string describing the encoding of the device\n\
7524if the output is a terminal; else return None.");
7525
7526static PyObject *
7527device_encoding(PyObject *self, PyObject *args)
7528{
Victor Stinner8c62be82010-05-06 00:08:46 +00007529 int fd;
7530 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7531 return NULL;
7532 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7533 Py_INCREF(Py_None);
7534 return Py_None;
7535 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007536#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007537 if (fd == 0) {
7538 char buf[100];
7539 sprintf(buf, "cp%d", GetConsoleCP());
7540 return PyUnicode_FromString(buf);
7541 }
7542 if (fd == 1 || fd == 2) {
7543 char buf[100];
7544 sprintf(buf, "cp%d", GetConsoleOutputCP());
7545 return PyUnicode_FromString(buf);
7546 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007547#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007548 {
7549 char *codeset = nl_langinfo(CODESET);
7550 if (codeset != NULL && codeset[0] != 0)
7551 return PyUnicode_FromString(codeset);
7552 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007553#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007554 Py_INCREF(Py_None);
7555 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007556}
7557
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007558#ifdef __VMS
7559/* Use openssl random routine */
7560#include <openssl/rand.h>
7561PyDoc_STRVAR(vms_urandom__doc__,
7562"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007563Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007564
7565static PyObject*
7566vms_urandom(PyObject *self, PyObject *args)
7567{
Victor Stinner8c62be82010-05-06 00:08:46 +00007568 int howMany;
7569 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007570
Victor Stinner8c62be82010-05-06 00:08:46 +00007571 /* Read arguments */
7572 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7573 return NULL;
7574 if (howMany < 0)
7575 return PyErr_Format(PyExc_ValueError,
7576 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007577
Victor Stinner8c62be82010-05-06 00:08:46 +00007578 /* Allocate bytes */
7579 result = PyBytes_FromStringAndSize(NULL, howMany);
7580 if (result != NULL) {
7581 /* Get random data */
7582 if (RAND_pseudo_bytes((unsigned char*)
7583 PyBytes_AS_STRING(result),
7584 howMany) < 0) {
7585 Py_DECREF(result);
7586 return PyErr_Format(PyExc_ValueError,
7587 "RAND_pseudo_bytes");
7588 }
7589 }
7590 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007591}
7592#endif
7593
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007594#ifdef HAVE_SETRESUID
7595PyDoc_STRVAR(posix_setresuid__doc__,
7596"setresuid(ruid, euid, suid)\n\n\
7597Set the current process's real, effective, and saved user ids.");
7598
7599static PyObject*
7600posix_setresuid (PyObject *self, PyObject *args)
7601{
Victor Stinner8c62be82010-05-06 00:08:46 +00007602 /* We assume uid_t is no larger than a long. */
7603 long ruid, euid, suid;
7604 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7605 return NULL;
7606 if (setresuid(ruid, euid, suid) < 0)
7607 return posix_error();
7608 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007609}
7610#endif
7611
7612#ifdef HAVE_SETRESGID
7613PyDoc_STRVAR(posix_setresgid__doc__,
7614"setresgid(rgid, egid, sgid)\n\n\
7615Set the current process's real, effective, and saved group ids.");
7616
7617static PyObject*
7618posix_setresgid (PyObject *self, PyObject *args)
7619{
Victor Stinner8c62be82010-05-06 00:08:46 +00007620 /* We assume uid_t is no larger than a long. */
7621 long rgid, egid, sgid;
7622 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7623 return NULL;
7624 if (setresgid(rgid, egid, sgid) < 0)
7625 return posix_error();
7626 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007627}
7628#endif
7629
7630#ifdef HAVE_GETRESUID
7631PyDoc_STRVAR(posix_getresuid__doc__,
7632"getresuid() -> (ruid, euid, suid)\n\n\
7633Get tuple of the current process's real, effective, and saved user ids.");
7634
7635static PyObject*
7636posix_getresuid (PyObject *self, PyObject *noargs)
7637{
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 uid_t ruid, euid, suid;
7639 long l_ruid, l_euid, l_suid;
7640 if (getresuid(&ruid, &euid, &suid) < 0)
7641 return posix_error();
7642 /* Force the values into long's as we don't know the size of uid_t. */
7643 l_ruid = ruid;
7644 l_euid = euid;
7645 l_suid = suid;
7646 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007647}
7648#endif
7649
7650#ifdef HAVE_GETRESGID
7651PyDoc_STRVAR(posix_getresgid__doc__,
7652"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00007653Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007654
7655static PyObject*
7656posix_getresgid (PyObject *self, PyObject *noargs)
7657{
Victor Stinner8c62be82010-05-06 00:08:46 +00007658 uid_t rgid, egid, sgid;
7659 long l_rgid, l_egid, l_sgid;
7660 if (getresgid(&rgid, &egid, &sgid) < 0)
7661 return posix_error();
7662 /* Force the values into long's as we don't know the size of uid_t. */
7663 l_rgid = rgid;
7664 l_egid = egid;
7665 l_sgid = sgid;
7666 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007667}
7668#endif
7669
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007670static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007671 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007672#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007673 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007674#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007675 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007676#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007677 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007678#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007679 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007680#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007681 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007682#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007683#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007684 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007685#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007686#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007687 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007688#endif /* HAVE_LCHMOD */
7689#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007690 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007691#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007692#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007693 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007694#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007695#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007696 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007697#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007698#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007699 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007700#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007701#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007702 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007703#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007704#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007705 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7706 METH_NOARGS, posix_getcwd__doc__},
7707 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7708 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007709#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007710#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007712#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007713 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7714 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7715 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007716#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007717 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007718#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007719#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007720 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007721#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007722#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007723 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007724#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007725 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7726 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7727 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007729#ifdef HAVE_SYMLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007730 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007731#endif /* HAVE_SYMLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007732#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin74e45612010-07-09 15:58:59 +00007733 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
7734 win_symlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007735#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007736#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007737 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007738#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007739 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007740#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007741 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007742#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007743 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7744 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7745 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007746#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007747 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007748#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007749 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007750#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007751 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7752 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007753#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007754#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007755 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7756 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007757#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007758 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7759 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007760#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007761#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007762#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007763 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007764#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007765#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007767#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007768#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007770#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007771#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007772 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007773#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007774#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007776#endif /* HAVE_GETEGID */
7777#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007778 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007779#endif /* HAVE_GETEUID */
7780#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007781 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007782#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007783#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007785#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007786 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007787#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007789#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007790#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007792#endif /* HAVE_GETPPID */
7793#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007795#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007796#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007797 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007798#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007799#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007800 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007801#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007802#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007803 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007804#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007805#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007806 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007807#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007808#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007809 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7810 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007811#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007812#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007813 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007814#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007815#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007816 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007817#endif /* HAVE_SETEUID */
7818#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007819 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007820#endif /* HAVE_SETEGID */
7821#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007822 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007823#endif /* HAVE_SETREUID */
7824#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007825 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007826#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007827#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007829#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007830#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007831 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007832#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007833#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007834 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00007835#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007836#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007837 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007838#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007839#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007840 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007841#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007842#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007843 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007844#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007845#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00007846 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007847#endif /* HAVE_WAIT3 */
7848#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00007849 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007850#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007851#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007852 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007853#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007854#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007856#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007857#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007858 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007859#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007860#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007861 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007862#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007863#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007864 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007865#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007866#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007868#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7870 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7871 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7872 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7873 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7874 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7875 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7876 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7877 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7878 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7879 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007880#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00007881 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007882#endif
7883#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00007884 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007885#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007886#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00007887 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007888#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007889#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00007890 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7891 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7892 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007893#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007894#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00007895 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007896#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007897#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007898 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007899#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007900#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007901 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007902#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007903 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007904#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00007905 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007906#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007907#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007908 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007909#endif
7910#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007911 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007912#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007913#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007914#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00007915 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007916#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007917#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007918 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007919#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007920#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007922#endif /* WIFSTOPPED */
7923#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007925#endif /* WIFSIGNALED */
7926#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00007927 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007928#endif /* WIFEXITED */
7929#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00007930 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007931#endif /* WEXITSTATUS */
7932#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007933 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007934#endif /* WTERMSIG */
7935#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007937#endif /* WSTOPSIG */
7938#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007939#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007940 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007941#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007942#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007943 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007944#endif
Fred Drakec9680921999-12-13 16:37:25 +00007945#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00007946 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007947#endif
7948#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007949 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007950#endif
7951#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007952 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007953#endif
7954#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007956#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007957 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007958#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007959 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00007960 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +00007961 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00007962#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007963#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00007964 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007965#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007966 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007967 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007968 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007969 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007970 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007971 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007972#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007974#endif
7975#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007977#endif
7978#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007979 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007980#endif
7981#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007983#endif
7984
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007986};
7987
7988
Barry Warsaw4a342091996-12-19 23:50:02 +00007989static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007990ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007991{
Victor Stinner8c62be82010-05-06 00:08:46 +00007992 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007993}
7994
Guido van Rossumd48f2521997-12-05 22:19:34 +00007995#if defined(PYOS_OS2)
7996/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007997static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007998{
7999 APIRET rc;
8000 ULONG values[QSV_MAX+1];
8001 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008002 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008003
8004 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008005 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008006 Py_END_ALLOW_THREADS
8007
8008 if (rc != NO_ERROR) {
8009 os2_error(rc);
8010 return -1;
8011 }
8012
Fred Drake4d1e64b2002-04-15 19:40:07 +00008013 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8014 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8015 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8016 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8017 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8018 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8019 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008020
8021 switch (values[QSV_VERSION_MINOR]) {
8022 case 0: ver = "2.00"; break;
8023 case 10: ver = "2.10"; break;
8024 case 11: ver = "2.11"; break;
8025 case 30: ver = "3.00"; break;
8026 case 40: ver = "4.00"; break;
8027 case 50: ver = "5.00"; break;
8028 default:
Tim Peters885d4572001-11-28 20:27:42 +00008029 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00008030 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00008031 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008032 ver = &tmp[0];
8033 }
8034
8035 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008036 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008037 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008038
8039 /* Add Indicator of Which Drive was Used to Boot the System */
8040 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8041 tmp[1] = ':';
8042 tmp[2] = '\0';
8043
Fred Drake4d1e64b2002-04-15 19:40:07 +00008044 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008045}
8046#endif
8047
Barry Warsaw4a342091996-12-19 23:50:02 +00008048static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008049all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008050{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008051#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008052 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008053#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008054#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008055 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008056#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008057#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008058 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008059#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008060#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008061 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008062#endif
Fred Drakec9680921999-12-13 16:37:25 +00008063#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008064 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00008065#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008066#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008067 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008068#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008069#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008070 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008071#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008072#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00008073 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008074#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008075#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00008076 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008077#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008078#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008079 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008080#endif
8081#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008082 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008083#endif
8084#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00008085 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008086#endif
8087#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00008088 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008089#endif
8090#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008091 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008092#endif
8093#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00008094 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008095#endif
8096#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008097 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008098#endif
8099#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008100 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008101#endif
8102#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008103 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008104#endif
8105#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008106 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008107#endif
8108#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008109 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008110#endif
8111#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00008112 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008113#endif
8114#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008115 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008116#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008117#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008118 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008119#endif
8120#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00008121 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008122#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008123#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008124 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008125#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008126#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008127 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008128#endif
8129#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008130 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008131#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008132
Tim Peters5aa91602002-01-30 05:46:57 +00008133/* MS Windows */
8134#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008135 /* Don't inherit in child processes. */
8136 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008137#endif
8138#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008139 /* Optimize for short life (keep in memory). */
8140 /* MS forgot to define this one with a non-underscore form too. */
8141 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008142#endif
8143#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008144 /* Automatically delete when last handle is closed. */
8145 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008146#endif
8147#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008148 /* Optimize for random access. */
8149 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008150#endif
8151#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008152 /* Optimize for sequential access. */
8153 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008154#endif
8155
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008156/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008157#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008158 /* Send a SIGIO signal whenever input or output
8159 becomes available on file descriptor */
8160 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008161#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008162#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008163 /* Direct disk access. */
8164 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008165#endif
8166#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008167 /* Must be a directory. */
8168 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008169#endif
8170#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008171 /* Do not follow links. */
8172 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008173#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008174#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008175 /* Do not update the access time. */
8176 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008177#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008178
Victor Stinner8c62be82010-05-06 00:08:46 +00008179 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008180#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008181 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008182#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008183#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008184 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008185#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008186#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008187 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008188#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008189#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008191#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008192#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008193 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008194#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008195#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008196 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008197#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008198#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008199 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008200#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008201#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008202 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008203#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008204#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008205 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008206#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008207#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008208 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008209#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008210#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008211 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008212#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008213#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008214 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008215#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008216#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008217 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008218#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008219#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008220 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008221#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008222#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008223 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008224#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008225#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008226 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008227#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008228#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008229 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008230#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008231
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008232 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008233#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008234 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008235#endif /* ST_RDONLY */
8236#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008237 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008238#endif /* ST_NOSUID */
8239
Guido van Rossum246bc171999-02-01 23:54:31 +00008240#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008241#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008242 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8243 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8244 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8245 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8246 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8247 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8248 if (ins(d, "P_PM", (long)P_PM)) return -1;
8249 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8250 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8251 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8252 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8253 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8254 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8255 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8256 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8257 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8258 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8259 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8260 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8261 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008262#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008263 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8264 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8265 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8266 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8267 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008268#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008269#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008270
Guido van Rossumd48f2521997-12-05 22:19:34 +00008271#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008272 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008273#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008274 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008275}
8276
8277
Tim Peters5aa91602002-01-30 05:46:57 +00008278#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008279#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008280#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008281
8282#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008283#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008284#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008285
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008286#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008287#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008288#define MODNAME "posix"
8289#endif
8290
Martin v. Löwis1a214512008-06-11 05:26:20 +00008291static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008292 PyModuleDef_HEAD_INIT,
8293 MODNAME,
8294 posix__doc__,
8295 -1,
8296 posix_methods,
8297 NULL,
8298 NULL,
8299 NULL,
8300 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008301};
8302
8303
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008304PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008305INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008306{
Victor Stinner8c62be82010-05-06 00:08:46 +00008307 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008308
Victor Stinner8c62be82010-05-06 00:08:46 +00008309 m = PyModule_Create(&posixmodule);
8310 if (m == NULL)
8311 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008312
Victor Stinner8c62be82010-05-06 00:08:46 +00008313 /* Initialize environ dictionary */
8314 v = convertenviron();
8315 Py_XINCREF(v);
8316 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8317 return NULL;
8318 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008319
Victor Stinner8c62be82010-05-06 00:08:46 +00008320 if (all_ins(m))
8321 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008322
Victor Stinner8c62be82010-05-06 00:08:46 +00008323 if (setup_confname_tables(m))
8324 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008325
Victor Stinner8c62be82010-05-06 00:08:46 +00008326 Py_INCREF(PyExc_OSError);
8327 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008328
Guido van Rossumb3d39562000-01-31 18:41:26 +00008329#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008330 if (posix_putenv_garbage == NULL)
8331 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008332#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008333
Victor Stinner8c62be82010-05-06 00:08:46 +00008334 if (!initialized) {
8335 stat_result_desc.name = MODNAME ".stat_result";
8336 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8337 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8338 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8339 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8340 structseq_new = StatResultType.tp_new;
8341 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008342
Victor Stinner8c62be82010-05-06 00:08:46 +00008343 statvfs_result_desc.name = MODNAME ".statvfs_result";
8344 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008345#ifdef NEED_TICKS_PER_SECOND
8346# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008347 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008348# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008349 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008350# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008351 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008352# endif
8353#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008354 }
8355 Py_INCREF((PyObject*) &StatResultType);
8356 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8357 Py_INCREF((PyObject*) &StatVFSResultType);
8358 PyModule_AddObject(m, "statvfs_result",
8359 (PyObject*) &StatVFSResultType);
8360 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008361
8362#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008363 /*
8364 * Step 2 of weak-linking support on Mac OS X.
8365 *
8366 * The code below removes functions that are not available on the
8367 * currently active platform.
8368 *
8369 * This block allow one to use a python binary that was build on
8370 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8371 * OSX 10.4.
8372 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008373#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008374 if (fstatvfs == NULL) {
8375 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8376 return NULL;
8377 }
8378 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008379#endif /* HAVE_FSTATVFS */
8380
8381#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008382 if (statvfs == NULL) {
8383 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8384 return NULL;
8385 }
8386 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008387#endif /* HAVE_STATVFS */
8388
8389# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008390 if (lchown == NULL) {
8391 if (PyObject_DelAttrString(m, "lchown") == -1) {
8392 return NULL;
8393 }
8394 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008395#endif /* HAVE_LCHOWN */
8396
8397
8398#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008399 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008400
Guido van Rossumb6775db1994-08-01 11:34:53 +00008401}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008402
8403#ifdef __cplusplus
8404}
8405#endif