blob: da42f3a287a92eb11f1acaaeaf8cf61ca70b4268 [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
Thomas Wouters477c8d52006-05-27 19:21:47 +000014#ifdef __APPLE__
15 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000016 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000017 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
18 * at the end of this file for more information.
19 */
20# pragma weak lchown
21# pragma weak statvfs
22# pragma weak fstatvfs
23
24#endif /* __APPLE__ */
25
Thomas Wouters68bc4f92006-03-01 01:05:10 +000026#define PY_SSIZE_T_CLEAN
27
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000028#include "Python.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000029
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000030#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020031# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#endif /* defined(__VMS) */
34
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000046#if defined(PYOS_OS2)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020047#error "PEP 11: OS/2 is now unsupported, code will be removed in Python 3.4"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#define INCL_DOS
49#define INCL_DOSERRORS
50#define INCL_DOSPROCESS
51#define INCL_NOPMAPI
52#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000053#if defined(PYCC_GCC)
54#include <ctype.h>
55#include <io.h>
56#include <stdio.h>
57#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000059#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000060#endif
61
Ross Lagerwall4d076da2011-03-18 06:56:53 +020062#ifdef HAVE_SYS_UIO_H
63#include <sys/uio.h>
64#endif
65
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000067#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068#endif /* HAVE_SYS_TYPES_H */
69
70#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000073
Guido van Rossum36bc6801995-06-14 22:54:23 +000074#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000075#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000076#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000079#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000080#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000081
Guido van Rossumb6775db1994-08-01 11:34:53 +000082#ifdef HAVE_FCNTL_H
83#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000084#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000085
Guido van Rossuma6535fd2001-10-18 19:44:10 +000086#ifdef HAVE_GRP_H
87#include <grp.h>
88#endif
89
Barry Warsaw5676bd12003-01-07 20:57:09 +000090#ifdef HAVE_SYSEXITS_H
91#include <sysexits.h>
92#endif /* HAVE_SYSEXITS_H */
93
Anthony Baxter8a560de2004-10-13 15:30:56 +000094#ifdef HAVE_SYS_LOADAVG_H
95#include <sys/loadavg.h>
96#endif
97
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000098#ifdef HAVE_LANGINFO_H
99#include <langinfo.h>
100#endif
101
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000102#ifdef HAVE_SYS_SENDFILE_H
103#include <sys/sendfile.h>
104#endif
105
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500106#ifdef HAVE_SCHED_H
107#include <sched.h>
108#endif
109
Benjamin Peterson9428d532011-09-14 11:45:52 -0400110#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
111#define USE_XATTRS
112#endif
113
114#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400115#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400116#endif
117
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000118#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
119#ifdef HAVE_SYS_SOCKET_H
120#include <sys/socket.h>
121#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000122#endif
123
Victor Stinner8b905bd2011-10-25 13:34:04 +0200124#ifdef HAVE_DLFCN_H
125#include <dlfcn.h>
126#endif
127
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000129/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000130#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000131#include <process.h>
132#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000133#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#define HAVE_GETCWD 1
135#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000136#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137#if defined(__OS2__)
138#define HAVE_EXECV 1
139#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000140#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#include <process.h>
142#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000143#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#define HAVE_EXECV 1
145#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#define HAVE_OPENDIR 1
147#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000148#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_WAIT 1
150#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000152#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000153#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000154#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000155#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156#define HAVE_EXECV 1
157#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000158#define HAVE_SYSTEM 1
159#define HAVE_CWAIT 1
160#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000161#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000162#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000163#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
164/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166/* Unix functions that the configure script doesn't check for */
167#define HAVE_EXECV 1
168#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000169#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000170#define HAVE_FORK1 1
171#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_GETCWD 1
173#define HAVE_GETEGID 1
174#define HAVE_GETEUID 1
175#define HAVE_GETGID 1
176#define HAVE_GETPPID 1
177#define HAVE_GETUID 1
178#define HAVE_KILL 1
179#define HAVE_OPENDIR 1
180#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000181#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000183#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000184#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#endif /* _MSC_VER */
186#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000187#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000188#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000189
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000190#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000191
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000192#if defined(__sgi)&&_COMPILER_VERSION>=700
193/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
194 (default) */
195extern char *ctermid_r(char *);
196#endif
197
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000198#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000199#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000201#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000202#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000205extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000206#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000207#endif
208#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000209extern int chdir(char *);
210extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000211#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int chdir(const char *);
213extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000214#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000215#ifdef __BORLANDC__
216extern int chmod(const char *, int);
217#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000218extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000219#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000220/*#ifdef HAVE_FCHMOD
221extern int fchmod(int, mode_t);
222#endif*/
223/*#ifdef HAVE_LCHMOD
224extern int lchmod(const char *, mode_t);
225#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000226extern int chown(const char *, uid_t, gid_t);
227extern char *getcwd(char *, int);
228extern char *strerror(int);
229extern int link(const char *, const char *);
230extern int rename(const char *, const char *);
231extern int stat(const char *, struct stat *);
232extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000234extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000235#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000237extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000238#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000240
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000241#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000242
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#ifdef HAVE_UTIME_H
244#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000245#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000247#ifdef HAVE_SYS_UTIME_H
248#include <sys/utime.h>
249#define HAVE_UTIME_H /* pretend we do for the rest of this file */
250#endif /* HAVE_SYS_UTIME_H */
251
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#ifdef HAVE_SYS_TIMES_H
253#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000254#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255
256#ifdef HAVE_SYS_PARAM_H
257#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000258#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259
260#ifdef HAVE_SYS_UTSNAME_H
261#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000262#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000264#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000266#define NAMLEN(dirent) strlen((dirent)->d_name)
267#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000268#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000269#include <direct.h>
270#define NAMLEN(dirent) strlen((dirent)->d_name)
271#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000273#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000274#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000275#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000276#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000277#endif
278#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#endif
281#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#endif
284#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000286#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000287#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000288#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000289#endif
290#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000292#endif
293#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000294#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000296#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000297#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000298#endif
299#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000300#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000301#endif
302#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000303#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000305#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000306#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000307#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000308#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000309#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000310#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
311#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000312static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000313#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000314#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000315
Guido van Rossumd48f2521997-12-05 22:19:34 +0000316#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000317#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000318#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319
Tim Petersbc2e10e2002-03-03 23:17:02 +0000320#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000321#if defined(PATH_MAX) && PATH_MAX > 1024
322#define MAXPATHLEN PATH_MAX
323#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000326#endif /* MAXPATHLEN */
327
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000328#ifdef UNION_WAIT
329/* Emulate some macros on systems that have a union instead of macros */
330
331#ifndef WIFEXITED
332#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
333#endif
334
335#ifndef WEXITSTATUS
336#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
337#endif
338
339#ifndef WTERMSIG
340#define WTERMSIG(u_wait) ((u_wait).w_termsig)
341#endif
342
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000343#define WAIT_TYPE union wait
344#define WAIT_STATUS_INT(s) (s.w_status)
345
346#else /* !UNION_WAIT */
347#define WAIT_TYPE int
348#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000349#endif /* UNION_WAIT */
350
Greg Wardb48bc172000-03-01 21:51:56 +0000351/* Don't use the "_r" form if we don't need it (also, won't have a
352 prototype for it, at least on Solaris -- maybe others as well?). */
353#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
354#define USE_CTERMID_R
355#endif
356
Fred Drake699f3522000-06-29 21:12:41 +0000357/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000358#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000359#undef FSTAT
360#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000361#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000362# define STAT win32_stat
363# define FSTAT win32_fstat
364# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000365#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000366# define STAT stat
367# define FSTAT fstat
368# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000369#endif
370
Tim Peters11b23062003-04-23 02:39:17 +0000371#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000372#include <sys/mkdev.h>
373#else
374#if defined(MAJOR_IN_SYSMACROS)
375#include <sys/sysmacros.h>
376#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000377#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
378#include <sys/mkdev.h>
379#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000380#endif
Fred Drake699f3522000-06-29 21:12:41 +0000381
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200382/* A helper used by a number of POSIX-only functions */
383#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000384static int
385_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000386{
387#if !defined(HAVE_LARGEFILE_SUPPORT)
388 *((off_t*)addr) = PyLong_AsLong(arg);
389#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000390 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000391#endif
392 if (PyErr_Occurred())
393 return 0;
394 return 1;
395}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200396#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000397
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000398#if defined _MSC_VER && _MSC_VER >= 1400
399/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
400 * valid and throw an assertion if it isn't.
401 * Normally, an invalid fd is likely to be a C program error and therefore
402 * an assertion can be useful, but it does contradict the POSIX standard
403 * which for write(2) states:
404 * "Otherwise, -1 shall be returned and errno set to indicate the error."
405 * "[EBADF] The fildes argument is not a valid file descriptor open for
406 * writing."
407 * Furthermore, python allows the user to enter any old integer
408 * as a fd and should merely raise a python exception on error.
409 * The Microsoft CRT doesn't provide an official way to check for the
410 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000411 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000412 * internal structures involved.
413 * The structures below must be updated for each version of visual studio
414 * according to the file internal.h in the CRT source, until MS comes
415 * up with a less hacky way to do this.
416 * (all of this is to avoid globally modifying the CRT behaviour using
417 * _set_invalid_parameter_handler() and _CrtSetReportMode())
418 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000419/* The actual size of the structure is determined at runtime.
420 * Only the first items must be present.
421 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000422typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000423 intptr_t osfhnd;
424 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000425} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000426
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000427extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000428#define IOINFO_L2E 5
429#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
430#define IOINFO_ARRAYS 64
431#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
432#define FOPEN 0x01
433#define _NO_CONSOLE_FILENO (intptr_t)-2
434
435/* This function emulates what the windows CRT does to validate file handles */
436int
437_PyVerify_fd(int fd)
438{
Victor Stinner8c62be82010-05-06 00:08:46 +0000439 const int i1 = fd >> IOINFO_L2E;
440 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000441
Antoine Pitrou22e41552010-08-15 18:07:50 +0000442 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000443
Victor Stinner8c62be82010-05-06 00:08:46 +0000444 /* Determine the actual size of the ioinfo structure,
445 * as used by the CRT loaded in memory
446 */
447 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
448 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
449 }
450 if (sizeof_ioinfo == 0) {
451 /* This should not happen... */
452 goto fail;
453 }
454
455 /* See that it isn't a special CLEAR fileno */
456 if (fd != _NO_CONSOLE_FILENO) {
457 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
458 * we check pointer validity and other info
459 */
460 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
461 /* finally, check that the file is open */
462 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
463 if (info->osfile & FOPEN) {
464 return 1;
465 }
466 }
467 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000468 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000469 errno = EBADF;
470 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000471}
472
473/* the special case of checking dup2. The target fd must be in a sensible range */
474static int
475_PyVerify_fd_dup2(int fd1, int fd2)
476{
Victor Stinner8c62be82010-05-06 00:08:46 +0000477 if (!_PyVerify_fd(fd1))
478 return 0;
479 if (fd2 == _NO_CONSOLE_FILENO)
480 return 0;
481 if ((unsigned)fd2 < _NHANDLE_)
482 return 1;
483 else
484 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000485}
486#else
487/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
488#define _PyVerify_fd_dup2(A, B) (1)
489#endif
490
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000491#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000492/* The following structure was copied from
493 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
494 include doesn't seem to be present in the Windows SDK (at least as included
495 with Visual Studio Express). */
496typedef struct _REPARSE_DATA_BUFFER {
497 ULONG ReparseTag;
498 USHORT ReparseDataLength;
499 USHORT Reserved;
500 union {
501 struct {
502 USHORT SubstituteNameOffset;
503 USHORT SubstituteNameLength;
504 USHORT PrintNameOffset;
505 USHORT PrintNameLength;
506 ULONG Flags;
507 WCHAR PathBuffer[1];
508 } SymbolicLinkReparseBuffer;
509
510 struct {
511 USHORT SubstituteNameOffset;
512 USHORT SubstituteNameLength;
513 USHORT PrintNameOffset;
514 USHORT PrintNameLength;
515 WCHAR PathBuffer[1];
516 } MountPointReparseBuffer;
517
518 struct {
519 UCHAR DataBuffer[1];
520 } GenericReparseBuffer;
521 };
522} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
523
524#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
525 GenericReparseBuffer)
526#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
527
528static int
Brian Curtind25aef52011-06-13 15:16:04 -0500529win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000530{
531 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
532 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
533 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000534
535 if (0 == DeviceIoControl(
536 reparse_point_handle,
537 FSCTL_GET_REPARSE_POINT,
538 NULL, 0, /* in buffer */
539 target_buffer, sizeof(target_buffer),
540 &n_bytes_returned,
541 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500542 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000543
544 if (reparse_tag)
545 *reparse_tag = rdb->ReparseTag;
546
Brian Curtind25aef52011-06-13 15:16:04 -0500547 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000548}
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000549#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000550
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000551/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000552#ifdef WITH_NEXT_FRAMEWORK
553/* On Darwin/MacOSX a shared library or framework has no access to
554** environ directly, we must obtain it with _NSGetEnviron().
555*/
556#include <crt_externs.h>
557static char **environ;
558#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000559extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000560#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000561
Barry Warsaw53699e91996-12-10 23:23:01 +0000562static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000563convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000564{
Victor Stinner8c62be82010-05-06 00:08:46 +0000565 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000566#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000567 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000568#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000569 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000570#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000571#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000572 APIRET rc;
573 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
574#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000575
Victor Stinner8c62be82010-05-06 00:08:46 +0000576 d = PyDict_New();
577 if (d == NULL)
578 return NULL;
579#ifdef WITH_NEXT_FRAMEWORK
580 if (environ == NULL)
581 environ = *_NSGetEnviron();
582#endif
583#ifdef MS_WINDOWS
584 /* _wenviron must be initialized in this way if the program is started
585 through main() instead of wmain(). */
586 _wgetenv(L"");
587 if (_wenviron == NULL)
588 return d;
589 /* This part ignores errors */
590 for (e = _wenviron; *e != NULL; e++) {
591 PyObject *k;
592 PyObject *v;
593 wchar_t *p = wcschr(*e, L'=');
594 if (p == NULL)
595 continue;
596 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
597 if (k == NULL) {
598 PyErr_Clear();
599 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000600 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000601 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
602 if (v == NULL) {
603 PyErr_Clear();
604 Py_DECREF(k);
605 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000606 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000607 if (PyDict_GetItem(d, k) == NULL) {
608 if (PyDict_SetItem(d, k, v) != 0)
609 PyErr_Clear();
610 }
611 Py_DECREF(k);
612 Py_DECREF(v);
613 }
614#else
615 if (environ == NULL)
616 return d;
617 /* This part ignores errors */
618 for (e = environ; *e != NULL; e++) {
619 PyObject *k;
620 PyObject *v;
621 char *p = strchr(*e, '=');
622 if (p == NULL)
623 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000624 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000625 if (k == NULL) {
626 PyErr_Clear();
627 continue;
628 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000629 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000630 if (v == NULL) {
631 PyErr_Clear();
632 Py_DECREF(k);
633 continue;
634 }
635 if (PyDict_GetItem(d, k) == NULL) {
636 if (PyDict_SetItem(d, k, v) != 0)
637 PyErr_Clear();
638 }
639 Py_DECREF(k);
640 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000641 }
642#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000643#if defined(PYOS_OS2)
644 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
645 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
646 PyObject *v = PyBytes_FromString(buffer);
647 PyDict_SetItemString(d, "BEGINLIBPATH", v);
648 Py_DECREF(v);
649 }
650 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
651 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
652 PyObject *v = PyBytes_FromString(buffer);
653 PyDict_SetItemString(d, "ENDLIBPATH", v);
654 Py_DECREF(v);
655 }
656#endif
657 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000658}
659
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000660/* Set a POSIX-specific error from errno, and return NULL */
661
Barry Warsawd58d7641998-07-23 16:14:40 +0000662static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000663posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000664{
Victor Stinner8c62be82010-05-06 00:08:46 +0000665 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000666}
Barry Warsawd58d7641998-07-23 16:14:40 +0000667static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000668posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000669{
Victor Stinner8c62be82010-05-06 00:08:46 +0000670 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000671}
672
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000673
Mark Hammondef8b6542001-05-13 08:04:26 +0000674static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000675posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000676{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000677 PyObject *name_str, *rc;
678 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
679 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000680 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000681 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
682 name_str);
683 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000684 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000685}
686
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000687#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000688static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000689win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000690{
Victor Stinner8c62be82010-05-06 00:08:46 +0000691 /* XXX We should pass the function name along in the future.
692 (winreg.c also wants to pass the function name.)
693 This would however require an additional param to the
694 Windows error object, which is non-trivial.
695 */
696 errno = GetLastError();
697 if (filename)
698 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
699 else
700 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000701}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000702
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000703static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +0200704win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000705{
Victor Stinner8c62be82010-05-06 00:08:46 +0000706 /* XXX - see win32_error for comments on 'function' */
707 errno = GetLastError();
708 if (filename)
709 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
710 else
711 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000712}
713
Victor Stinnereb5657a2011-09-30 01:44:27 +0200714static PyObject *
715win32_error_object(char* function, PyObject* filename)
716{
717 /* XXX - see win32_error for comments on 'function' */
718 errno = GetLastError();
719 if (filename)
720 return PyErr_SetExcFromWindowsErrWithFilenameObject(
721 PyExc_WindowsError,
722 errno,
723 filename);
724 else
725 return PyErr_SetFromWindowsErr(errno);
726}
727
Thomas Wouters477c8d52006-05-27 19:21:47 +0000728static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000729convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000730{
Victor Stinner8c62be82010-05-06 00:08:46 +0000731 if (PyUnicode_CheckExact(*param))
732 Py_INCREF(*param);
733 else if (PyUnicode_Check(*param))
734 /* For a Unicode subtype that's not a Unicode object,
735 return a true Unicode object with the same data. */
Victor Stinner034f6cf2011-09-30 02:26:44 +0200736 *param = PyUnicode_Copy(*param);
Victor Stinner8c62be82010-05-06 00:08:46 +0000737 else
738 *param = PyUnicode_FromEncodedObject(*param,
739 Py_FileSystemDefaultEncoding,
740 "strict");
741 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000742}
743
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000744#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000745
Guido van Rossumd48f2521997-12-05 22:19:34 +0000746#if defined(PYOS_OS2)
747/**********************************************************************
748 * Helper Function to Trim and Format OS/2 Messages
749 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000750static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000751os2_formatmsg(char *msgbuf, int msglen, char *reason)
752{
753 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
754
755 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
756 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
757
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000758 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000759 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
760 }
761
762 /* Add Optional Reason Text */
763 if (reason) {
764 strcat(msgbuf, " : ");
765 strcat(msgbuf, reason);
766 }
767}
768
769/**********************************************************************
770 * Decode an OS/2 Operating System Error Code
771 *
772 * A convenience function to lookup an OS/2 error code and return a
773 * text message we can use to raise a Python exception.
774 *
775 * Notes:
776 * The messages for errors returned from the OS/2 kernel reside in
777 * the file OSO001.MSG in the \OS2 directory hierarchy.
778 *
779 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000780static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000781os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
782{
783 APIRET rc;
784 ULONG msglen;
785
786 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
787 Py_BEGIN_ALLOW_THREADS
788 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
789 errorcode, "oso001.msg", &msglen);
790 Py_END_ALLOW_THREADS
791
792 if (rc == NO_ERROR)
793 os2_formatmsg(msgbuf, msglen, reason);
794 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000795 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000796 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000797
798 return msgbuf;
799}
800
801/* Set an OS/2-specific error and return NULL. OS/2 kernel
802 errors are not in a global variable e.g. 'errno' nor are
803 they congruent with posix error numbers. */
804
Victor Stinner8c62be82010-05-06 00:08:46 +0000805static PyObject *
806os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000807{
808 char text[1024];
809 PyObject *v;
810
811 os2_strerror(text, sizeof(text), code, "");
812
813 v = Py_BuildValue("(is)", code, text);
814 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000815 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000816 Py_DECREF(v);
817 }
818 return NULL; /* Signal to Python that an Exception is Pending */
819}
820
821#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000822
823/* POSIX generic methods */
824
Barry Warsaw53699e91996-12-10 23:23:01 +0000825static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000826posix_fildes(PyObject *fdobj, int (*func)(int))
827{
Victor Stinner8c62be82010-05-06 00:08:46 +0000828 int fd;
829 int res;
830 fd = PyObject_AsFileDescriptor(fdobj);
831 if (fd < 0)
832 return NULL;
833 if (!_PyVerify_fd(fd))
834 return posix_error();
835 Py_BEGIN_ALLOW_THREADS
836 res = (*func)(fd);
837 Py_END_ALLOW_THREADS
838 if (res < 0)
839 return posix_error();
840 Py_INCREF(Py_None);
841 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000842}
Guido van Rossum21142a01999-01-08 21:05:37 +0000843
844static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000845posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000846{
Victor Stinner8c62be82010-05-06 00:08:46 +0000847 PyObject *opath1 = NULL;
848 char *path1;
849 int res;
850 if (!PyArg_ParseTuple(args, format,
851 PyUnicode_FSConverter, &opath1))
852 return NULL;
853 path1 = PyBytes_AsString(opath1);
854 Py_BEGIN_ALLOW_THREADS
855 res = (*func)(path1);
856 Py_END_ALLOW_THREADS
857 if (res < 0)
858 return posix_error_with_allocated_filename(opath1);
859 Py_DECREF(opath1);
860 Py_INCREF(Py_None);
861 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000862}
863
Barry Warsaw53699e91996-12-10 23:23:01 +0000864static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000865posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000866 char *format,
867 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000868{
Victor Stinner8c62be82010-05-06 00:08:46 +0000869 PyObject *opath1 = NULL, *opath2 = NULL;
870 char *path1, *path2;
871 int res;
872 if (!PyArg_ParseTuple(args, format,
873 PyUnicode_FSConverter, &opath1,
874 PyUnicode_FSConverter, &opath2)) {
875 return NULL;
876 }
877 path1 = PyBytes_AsString(opath1);
878 path2 = PyBytes_AsString(opath2);
879 Py_BEGIN_ALLOW_THREADS
880 res = (*func)(path1, path2);
881 Py_END_ALLOW_THREADS
882 Py_DECREF(opath1);
883 Py_DECREF(opath2);
884 if (res != 0)
885 /* XXX how to report both path1 and path2??? */
886 return posix_error();
887 Py_INCREF(Py_None);
888 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000889}
890
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000891#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000892static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000893win32_1str(PyObject* args, char* func,
894 char* format, BOOL (__stdcall *funcA)(LPCSTR),
895 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000896{
Victor Stinner8c62be82010-05-06 00:08:46 +0000897 PyObject *uni;
898 char *ansi;
899 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000900
Victor Stinnereb5657a2011-09-30 01:44:27 +0200901 if (PyArg_ParseTuple(args, wformat, &uni))
902 {
903 wchar_t *wstr = PyUnicode_AsUnicode(uni);
904 if (wstr == NULL)
905 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +0000906 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +0200907 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +0000908 Py_END_ALLOW_THREADS
909 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +0200910 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +0000911 Py_INCREF(Py_None);
912 return Py_None;
913 }
Victor Stinnereb5657a2011-09-30 01:44:27 +0200914 PyErr_Clear();
915
Victor Stinner8c62be82010-05-06 00:08:46 +0000916 if (!PyArg_ParseTuple(args, format, &ansi))
917 return NULL;
918 Py_BEGIN_ALLOW_THREADS
919 result = funcA(ansi);
920 Py_END_ALLOW_THREADS
921 if (!result)
922 return win32_error(func, ansi);
923 Py_INCREF(Py_None);
924 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000925
926}
927
928/* This is a reimplementation of the C library's chdir function,
929 but one that produces Win32 errors instead of DOS error codes.
930 chdir is essentially a wrapper around SetCurrentDirectory; however,
931 it also needs to set "magic" environment variables indicating
932 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000933static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000934win32_chdir(LPCSTR path)
935{
Victor Stinner8c62be82010-05-06 00:08:46 +0000936 char new_path[MAX_PATH+1];
937 int result;
938 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000939
Victor Stinner8c62be82010-05-06 00:08:46 +0000940 if(!SetCurrentDirectoryA(path))
941 return FALSE;
942 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
943 if (!result)
944 return FALSE;
945 /* In the ANSI API, there should not be any paths longer
946 than MAX_PATH. */
947 assert(result <= MAX_PATH+1);
948 if (strncmp(new_path, "\\\\", 2) == 0 ||
949 strncmp(new_path, "//", 2) == 0)
950 /* UNC path, nothing to do. */
951 return TRUE;
952 env[1] = new_path[0];
953 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000954}
955
956/* The Unicode version differs from the ANSI version
957 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000958static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000959win32_wchdir(LPCWSTR path)
960{
Victor Stinner8c62be82010-05-06 00:08:46 +0000961 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
962 int result;
963 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000964
Victor Stinner8c62be82010-05-06 00:08:46 +0000965 if(!SetCurrentDirectoryW(path))
966 return FALSE;
967 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
968 if (!result)
969 return FALSE;
970 if (result > MAX_PATH+1) {
971 new_path = malloc(result * sizeof(wchar_t));
972 if (!new_path) {
973 SetLastError(ERROR_OUTOFMEMORY);
974 return FALSE;
975 }
976 result = GetCurrentDirectoryW(result, new_path);
977 if (!result) {
978 free(new_path);
979 return FALSE;
980 }
981 }
982 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
983 wcsncmp(new_path, L"//", 2) == 0)
984 /* UNC path, nothing to do. */
985 return TRUE;
986 env[1] = new_path[0];
987 result = SetEnvironmentVariableW(env, new_path);
988 if (new_path != _new_path)
989 free(new_path);
990 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000991}
992#endif
993
Martin v. Löwis14694662006-02-03 12:54:16 +0000994#ifdef MS_WINDOWS
995/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
996 - time stamps are restricted to second resolution
997 - file modification times suffer from forth-and-back conversions between
998 UTC and local time
999 Therefore, we implement our own stat, based on the Win32 API directly.
1000*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001001#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001002
1003struct win32_stat{
1004 int st_dev;
1005 __int64 st_ino;
1006 unsigned short st_mode;
1007 int st_nlink;
1008 int st_uid;
1009 int st_gid;
1010 int st_rdev;
1011 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001012 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001013 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001014 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001015 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001016 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001017 int st_ctime_nsec;
1018};
1019
1020static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1021
1022static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001023FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001024{
Victor Stinner8c62be82010-05-06 00:08:46 +00001025 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1026 /* Cannot simply cast and dereference in_ptr,
1027 since it might not be aligned properly */
1028 __int64 in;
1029 memcpy(&in, in_ptr, sizeof(in));
1030 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001031 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001032}
1033
Thomas Wouters477c8d52006-05-27 19:21:47 +00001034static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001035time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001036{
Victor Stinner8c62be82010-05-06 00:08:46 +00001037 /* XXX endianness */
1038 __int64 out;
1039 out = time_in + secs_between_epochs;
1040 out = out * 10000000 + nsec_in / 100;
1041 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001042}
1043
Martin v. Löwis14694662006-02-03 12:54:16 +00001044/* Below, we *know* that ugo+r is 0444 */
1045#if _S_IREAD != 0400
1046#error Unsupported C library
1047#endif
1048static int
1049attributes_to_mode(DWORD attr)
1050{
Victor Stinner8c62be82010-05-06 00:08:46 +00001051 int m = 0;
1052 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1053 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1054 else
1055 m |= _S_IFREG;
1056 if (attr & FILE_ATTRIBUTE_READONLY)
1057 m |= 0444;
1058 else
1059 m |= 0666;
1060 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001061}
1062
1063static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001064attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001065{
Victor Stinner8c62be82010-05-06 00:08:46 +00001066 memset(result, 0, sizeof(*result));
1067 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1068 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1069 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1070 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1071 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001072 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001073 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001074 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1075 /* first clear the S_IFMT bits */
1076 result->st_mode ^= (result->st_mode & 0170000);
1077 /* now set the bits that make this a symlink */
1078 result->st_mode |= 0120000;
1079 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001080
Victor Stinner8c62be82010-05-06 00:08:46 +00001081 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001082}
1083
Guido van Rossumd8faa362007-04-27 19:54:29 +00001084static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001085attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001086{
Victor Stinner8c62be82010-05-06 00:08:46 +00001087 HANDLE hFindFile;
1088 WIN32_FIND_DATAA FileData;
1089 hFindFile = FindFirstFileA(pszFile, &FileData);
1090 if (hFindFile == INVALID_HANDLE_VALUE)
1091 return FALSE;
1092 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001093 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001094 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001095 info->dwFileAttributes = FileData.dwFileAttributes;
1096 info->ftCreationTime = FileData.ftCreationTime;
1097 info->ftLastAccessTime = FileData.ftLastAccessTime;
1098 info->ftLastWriteTime = FileData.ftLastWriteTime;
1099 info->nFileSizeHigh = FileData.nFileSizeHigh;
1100 info->nFileSizeLow = FileData.nFileSizeLow;
1101/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001102 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1103 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001104 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001105}
1106
1107static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001108attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001109{
Victor Stinner8c62be82010-05-06 00:08:46 +00001110 HANDLE hFindFile;
1111 WIN32_FIND_DATAW FileData;
1112 hFindFile = FindFirstFileW(pszFile, &FileData);
1113 if (hFindFile == INVALID_HANDLE_VALUE)
1114 return FALSE;
1115 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001116 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001117 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001118 info->dwFileAttributes = FileData.dwFileAttributes;
1119 info->ftCreationTime = FileData.ftCreationTime;
1120 info->ftLastAccessTime = FileData.ftLastAccessTime;
1121 info->ftLastWriteTime = FileData.ftLastWriteTime;
1122 info->nFileSizeHigh = FileData.nFileSizeHigh;
1123 info->nFileSizeLow = FileData.nFileSizeLow;
1124/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001125 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1126 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001127 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001128}
1129
Brian Curtind25aef52011-06-13 15:16:04 -05001130/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1131static int has_GetFinalPathNameByHandle = 0;
1132static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1133 DWORD);
1134static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1135 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001136static int
Brian Curtind25aef52011-06-13 15:16:04 -05001137check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001138{
Brian Curtind25aef52011-06-13 15:16:04 -05001139 HINSTANCE hKernel32;
1140 /* only recheck */
1141 if (!has_GetFinalPathNameByHandle)
1142 {
1143 hKernel32 = GetModuleHandle("KERNEL32");
1144 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1145 "GetFinalPathNameByHandleA");
1146 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1147 "GetFinalPathNameByHandleW");
1148 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1149 Py_GetFinalPathNameByHandleW;
1150 }
1151 return has_GetFinalPathNameByHandle;
1152}
1153
1154static BOOL
1155get_target_path(HANDLE hdl, wchar_t **target_path)
1156{
1157 int buf_size, result_length;
1158 wchar_t *buf;
1159
1160 /* We have a good handle to the target, use it to determine
1161 the target path name (then we'll call lstat on it). */
1162 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1163 VOLUME_NAME_DOS);
1164 if(!buf_size)
1165 return FALSE;
1166
1167 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001168 if (!buf) {
1169 SetLastError(ERROR_OUTOFMEMORY);
1170 return FALSE;
1171 }
1172
Brian Curtind25aef52011-06-13 15:16:04 -05001173 result_length = Py_GetFinalPathNameByHandleW(hdl,
1174 buf, buf_size, VOLUME_NAME_DOS);
1175
1176 if(!result_length) {
1177 free(buf);
1178 return FALSE;
1179 }
1180
1181 if(!CloseHandle(hdl)) {
1182 free(buf);
1183 return FALSE;
1184 }
1185
1186 buf[result_length] = 0;
1187
1188 *target_path = buf;
1189 return TRUE;
1190}
1191
1192static int
1193win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1194 BOOL traverse);
1195static int
1196win32_xstat_impl(const char *path, struct win32_stat *result,
1197 BOOL traverse)
1198{
Victor Stinner26de69d2011-06-17 15:15:38 +02001199 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001200 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001201 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001202 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001203 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001204 const char *dot;
1205
Brian Curtind25aef52011-06-13 15:16:04 -05001206 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001207 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1208 traverse reparse point. */
1209 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001210 }
1211
Brian Curtinf5e76d02010-11-24 13:14:05 +00001212 hFile = CreateFileA(
1213 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001214 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001215 0, /* share mode */
1216 NULL, /* security attributes */
1217 OPEN_EXISTING,
1218 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001219 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1220 Because of this, calls like GetFinalPathNameByHandle will return
1221 the symlink path agin and not the actual final path. */
1222 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1223 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001224 NULL);
1225
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001226 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001227 /* Either the target doesn't exist, or we don't have access to
1228 get a handle to it. If the former, we need to return an error.
1229 If the latter, we can use attributes_from_dir. */
1230 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001231 return -1;
1232 /* Could not get attributes on open file. Fall back to
1233 reading the directory. */
1234 if (!attributes_from_dir(path, &info, &reparse_tag))
1235 /* Very strange. This should not fail now */
1236 return -1;
1237 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1238 if (traverse) {
1239 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001240 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001241 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001242 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001243 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001244 } else {
1245 if (!GetFileInformationByHandle(hFile, &info)) {
1246 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001247 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001248 }
1249 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001250 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1251 return -1;
1252
1253 /* Close the outer open file handle now that we're about to
1254 reopen it with different flags. */
1255 if (!CloseHandle(hFile))
1256 return -1;
1257
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001258 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001259 /* In order to call GetFinalPathNameByHandle we need to open
1260 the file without the reparse handling flag set. */
1261 hFile2 = CreateFileA(
1262 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1263 NULL, OPEN_EXISTING,
1264 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1265 NULL);
1266 if (hFile2 == INVALID_HANDLE_VALUE)
1267 return -1;
1268
1269 if (!get_target_path(hFile2, &target_path))
1270 return -1;
1271
1272 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001273 free(target_path);
1274 return code;
1275 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001276 } else
1277 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001278 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001279 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001280
1281 /* Set S_IEXEC if it is an .exe, .bat, ... */
1282 dot = strrchr(path, '.');
1283 if (dot) {
1284 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1285 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1286 result->st_mode |= 0111;
1287 }
1288 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001289}
1290
1291static int
Brian Curtind25aef52011-06-13 15:16:04 -05001292win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1293 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001294{
1295 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001296 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001297 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001298 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001299 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001300 const wchar_t *dot;
1301
Brian Curtind25aef52011-06-13 15:16:04 -05001302 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001303 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1304 traverse reparse point. */
1305 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001306 }
1307
Brian Curtinf5e76d02010-11-24 13:14:05 +00001308 hFile = CreateFileW(
1309 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001310 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001311 0, /* share mode */
1312 NULL, /* security attributes */
1313 OPEN_EXISTING,
1314 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001315 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1316 Because of this, calls like GetFinalPathNameByHandle will return
1317 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001318 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001319 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001320 NULL);
1321
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001322 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001323 /* Either the target doesn't exist, or we don't have access to
1324 get a handle to it. If the former, we need to return an error.
1325 If the latter, we can use attributes_from_dir. */
1326 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001327 return -1;
1328 /* Could not get attributes on open file. Fall back to
1329 reading the directory. */
1330 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1331 /* Very strange. This should not fail now */
1332 return -1;
1333 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1334 if (traverse) {
1335 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001336 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001337 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001338 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001339 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001340 } else {
1341 if (!GetFileInformationByHandle(hFile, &info)) {
1342 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001343 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001344 }
1345 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001346 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1347 return -1;
1348
1349 /* Close the outer open file handle now that we're about to
1350 reopen it with different flags. */
1351 if (!CloseHandle(hFile))
1352 return -1;
1353
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001354 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001355 /* In order to call GetFinalPathNameByHandle we need to open
1356 the file without the reparse handling flag set. */
1357 hFile2 = CreateFileW(
1358 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1359 NULL, OPEN_EXISTING,
1360 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1361 NULL);
1362 if (hFile2 == INVALID_HANDLE_VALUE)
1363 return -1;
1364
1365 if (!get_target_path(hFile2, &target_path))
1366 return -1;
1367
1368 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001369 free(target_path);
1370 return code;
1371 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001372 } else
1373 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001374 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001375 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001376
1377 /* Set S_IEXEC if it is an .exe, .bat, ... */
1378 dot = wcsrchr(path, '.');
1379 if (dot) {
1380 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1381 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1382 result->st_mode |= 0111;
1383 }
1384 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001385}
1386
1387static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001388win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001389{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001390 /* Protocol violation: we explicitly clear errno, instead of
1391 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001392 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001393 errno = 0;
1394 return code;
1395}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001396
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001397static int
1398win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1399{
1400 /* Protocol violation: we explicitly clear errno, instead of
1401 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001402 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001403 errno = 0;
1404 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001405}
Brian Curtind25aef52011-06-13 15:16:04 -05001406/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001407
1408 In Posix, stat automatically traverses symlinks and returns the stat
1409 structure for the target. In Windows, the equivalent GetFileAttributes by
1410 default does not traverse symlinks and instead returns attributes for
1411 the symlink.
1412
1413 Therefore, win32_lstat will get the attributes traditionally, and
1414 win32_stat will first explicitly resolve the symlink target and then will
1415 call win32_lstat on that result.
1416
Ezio Melotti4969f702011-03-15 05:59:46 +02001417 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001418
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001419static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001420win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001421{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001422 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001423}
1424
Victor Stinner8c62be82010-05-06 00:08:46 +00001425static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001426win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001427{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001428 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001429}
1430
1431static int
1432win32_stat(const char* path, struct win32_stat *result)
1433{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001434 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001435}
1436
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001437static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001438win32_stat_w(const wchar_t* path, struct win32_stat *result)
1439{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001440 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001441}
1442
1443static int
1444win32_fstat(int file_number, struct win32_stat *result)
1445{
Victor Stinner8c62be82010-05-06 00:08:46 +00001446 BY_HANDLE_FILE_INFORMATION info;
1447 HANDLE h;
1448 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001449
Victor Stinner8c62be82010-05-06 00:08:46 +00001450 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001451
Victor Stinner8c62be82010-05-06 00:08:46 +00001452 /* Protocol violation: we explicitly clear errno, instead of
1453 setting it to a POSIX error. Callers should use GetLastError. */
1454 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001455
Victor Stinner8c62be82010-05-06 00:08:46 +00001456 if (h == INVALID_HANDLE_VALUE) {
1457 /* This is really a C library error (invalid file handle).
1458 We set the Win32 error to the closes one matching. */
1459 SetLastError(ERROR_INVALID_HANDLE);
1460 return -1;
1461 }
1462 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001463
Victor Stinner8c62be82010-05-06 00:08:46 +00001464 type = GetFileType(h);
1465 if (type == FILE_TYPE_UNKNOWN) {
1466 DWORD error = GetLastError();
1467 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001468 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001469 }
1470 /* else: valid but unknown file */
1471 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001472
Victor Stinner8c62be82010-05-06 00:08:46 +00001473 if (type != FILE_TYPE_DISK) {
1474 if (type == FILE_TYPE_CHAR)
1475 result->st_mode = _S_IFCHR;
1476 else if (type == FILE_TYPE_PIPE)
1477 result->st_mode = _S_IFIFO;
1478 return 0;
1479 }
1480
1481 if (!GetFileInformationByHandle(h, &info)) {
1482 return -1;
1483 }
1484
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001485 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001486 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001487 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1488 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001489}
1490
1491#endif /* MS_WINDOWS */
1492
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001493PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001494"stat_result: Result from stat or lstat.\n\n\
1495This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001496 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001497or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1498\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001499Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1500or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001501\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001502See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001503
1504static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001505 {"st_mode", "protection bits"},
1506 {"st_ino", "inode"},
1507 {"st_dev", "device"},
1508 {"st_nlink", "number of hard links"},
1509 {"st_uid", "user ID of owner"},
1510 {"st_gid", "group ID of owner"},
1511 {"st_size", "total size, in bytes"},
1512 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1513 {NULL, "integer time of last access"},
1514 {NULL, "integer time of last modification"},
1515 {NULL, "integer time of last change"},
1516 {"st_atime", "time of last access"},
1517 {"st_mtime", "time of last modification"},
1518 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001519#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001520 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001521#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001522#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001523 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001524#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001525#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001526 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001527#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001528#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001529 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001530#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001531#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001532 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001533#endif
1534#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001535 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001536#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001537 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001538};
1539
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001540#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001541#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001542#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001543#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001544#endif
1545
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001546#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001547#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1548#else
1549#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1550#endif
1551
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001552#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001553#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1554#else
1555#define ST_RDEV_IDX ST_BLOCKS_IDX
1556#endif
1557
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001558#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1559#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1560#else
1561#define ST_FLAGS_IDX ST_RDEV_IDX
1562#endif
1563
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001564#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001565#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001566#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001567#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001568#endif
1569
1570#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1571#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1572#else
1573#define ST_BIRTHTIME_IDX ST_GEN_IDX
1574#endif
1575
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001576static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001577 "stat_result", /* name */
1578 stat_result__doc__, /* doc */
1579 stat_result_fields,
1580 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001581};
1582
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001583PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001584"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1585This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001586 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001587or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001588\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001589See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001590
1591static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001592 {"f_bsize", },
1593 {"f_frsize", },
1594 {"f_blocks", },
1595 {"f_bfree", },
1596 {"f_bavail", },
1597 {"f_files", },
1598 {"f_ffree", },
1599 {"f_favail", },
1600 {"f_flag", },
1601 {"f_namemax",},
1602 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001603};
1604
1605static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001606 "statvfs_result", /* name */
1607 statvfs_result__doc__, /* doc */
1608 statvfs_result_fields,
1609 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001610};
1611
Ross Lagerwall7807c352011-03-17 20:20:30 +02001612#if defined(HAVE_WAITID) && !defined(__APPLE__)
1613PyDoc_STRVAR(waitid_result__doc__,
1614"waitid_result: Result from waitid.\n\n\
1615This object may be accessed either as a tuple of\n\
1616 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1617or via the attributes si_pid, si_uid, and so on.\n\
1618\n\
1619See os.waitid for more information.");
1620
1621static PyStructSequence_Field waitid_result_fields[] = {
1622 {"si_pid", },
1623 {"si_uid", },
1624 {"si_signo", },
1625 {"si_status", },
1626 {"si_code", },
1627 {0}
1628};
1629
1630static PyStructSequence_Desc waitid_result_desc = {
1631 "waitid_result", /* name */
1632 waitid_result__doc__, /* doc */
1633 waitid_result_fields,
1634 5
1635};
1636static PyTypeObject WaitidResultType;
1637#endif
1638
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001639static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001640static PyTypeObject StatResultType;
1641static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001642#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001643static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001644#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001645static newfunc structseq_new;
1646
1647static PyObject *
1648statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1649{
Victor Stinner8c62be82010-05-06 00:08:46 +00001650 PyStructSequence *result;
1651 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001652
Victor Stinner8c62be82010-05-06 00:08:46 +00001653 result = (PyStructSequence*)structseq_new(type, args, kwds);
1654 if (!result)
1655 return NULL;
1656 /* If we have been initialized from a tuple,
1657 st_?time might be set to None. Initialize it
1658 from the int slots. */
1659 for (i = 7; i <= 9; i++) {
1660 if (result->ob_item[i+3] == Py_None) {
1661 Py_DECREF(Py_None);
1662 Py_INCREF(result->ob_item[i]);
1663 result->ob_item[i+3] = result->ob_item[i];
1664 }
1665 }
1666 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001667}
1668
1669
1670
1671/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001672static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001673
1674PyDoc_STRVAR(stat_float_times__doc__,
1675"stat_float_times([newval]) -> oldval\n\n\
1676Determine whether os.[lf]stat represents time stamps as float objects.\n\
1677If newval is True, future calls to stat() return floats, if it is False,\n\
1678future calls return ints. \n\
1679If newval is omitted, return the current setting.\n");
1680
1681static PyObject*
1682stat_float_times(PyObject* self, PyObject *args)
1683{
Victor Stinner8c62be82010-05-06 00:08:46 +00001684 int newval = -1;
1685 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1686 return NULL;
1687 if (newval == -1)
1688 /* Return old value */
1689 return PyBool_FromLong(_stat_float_times);
1690 _stat_float_times = newval;
1691 Py_INCREF(Py_None);
1692 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001693}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001694
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001695static void
1696fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1697{
Victor Stinner8c62be82010-05-06 00:08:46 +00001698 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001699#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001700 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001701#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001702 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001703#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001704 if (!ival)
1705 return;
1706 if (_stat_float_times) {
1707 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1708 } else {
1709 fval = ival;
1710 Py_INCREF(fval);
1711 }
1712 PyStructSequence_SET_ITEM(v, index, ival);
1713 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001714}
1715
Tim Peters5aa91602002-01-30 05:46:57 +00001716/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001717 (used by posix_stat() and posix_fstat()) */
1718static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001719_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001720{
Victor Stinner8c62be82010-05-06 00:08:46 +00001721 unsigned long ansec, mnsec, cnsec;
1722 PyObject *v = PyStructSequence_New(&StatResultType);
1723 if (v == NULL)
1724 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001725
Victor Stinner8c62be82010-05-06 00:08:46 +00001726 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001727#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001728 PyStructSequence_SET_ITEM(v, 1,
1729 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001730#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001731 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001732#endif
1733#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001734 PyStructSequence_SET_ITEM(v, 2,
1735 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001736#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001737 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001738#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001739 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1740 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1741 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001742#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001743 PyStructSequence_SET_ITEM(v, 6,
1744 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001745#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001746 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001747#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001748
Martin v. Löwis14694662006-02-03 12:54:16 +00001749#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001750 ansec = st->st_atim.tv_nsec;
1751 mnsec = st->st_mtim.tv_nsec;
1752 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001753#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001754 ansec = st->st_atimespec.tv_nsec;
1755 mnsec = st->st_mtimespec.tv_nsec;
1756 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001757#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001758 ansec = st->st_atime_nsec;
1759 mnsec = st->st_mtime_nsec;
1760 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001761#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001762 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001763#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001764 fill_time(v, 7, st->st_atime, ansec);
1765 fill_time(v, 8, st->st_mtime, mnsec);
1766 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001767
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001768#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001769 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1770 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001771#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001772#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001773 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1774 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001775#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001776#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001777 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1778 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001779#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001780#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001781 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1782 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001783#endif
1784#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001785 {
1786 PyObject *val;
1787 unsigned long bsec,bnsec;
1788 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001789#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001790 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001791#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001792 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001793#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001794 if (_stat_float_times) {
1795 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1796 } else {
1797 val = PyLong_FromLong((long)bsec);
1798 }
1799 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1800 val);
1801 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001802#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001803#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001804 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1805 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001806#endif
Fred Drake699f3522000-06-29 21:12:41 +00001807
Victor Stinner8c62be82010-05-06 00:08:46 +00001808 if (PyErr_Occurred()) {
1809 Py_DECREF(v);
1810 return NULL;
1811 }
Fred Drake699f3522000-06-29 21:12:41 +00001812
Victor Stinner8c62be82010-05-06 00:08:46 +00001813 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001814}
1815
Barry Warsaw53699e91996-12-10 23:23:01 +00001816static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001817posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001818 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001819#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001820 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001821#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001822 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001823#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001824 char *wformat,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001825 int (*wstatfunc)(const wchar_t *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001826{
Victor Stinner8c62be82010-05-06 00:08:46 +00001827 STRUCT_STAT st;
1828 PyObject *opath;
1829 char *path;
1830 int res;
1831 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001832
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001833#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001834 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00001835 if (PyArg_ParseTuple(args, wformat, &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02001836 wchar_t *wpath = PyUnicode_AsUnicode(po);
1837 if (wpath == NULL)
1838 return NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00001839
Victor Stinner8c62be82010-05-06 00:08:46 +00001840 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00001841 res = wstatfunc(wpath, &st);
1842 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001843
Victor Stinner8c62be82010-05-06 00:08:46 +00001844 if (res != 0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001845 return win32_error_object("stat", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 return _pystat_fromstructstat(&st);
1847 }
1848 /* Drop the argument parsing error as narrow strings
1849 are also valid. */
1850 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001851#endif
1852
Victor Stinner8c62be82010-05-06 00:08:46 +00001853 if (!PyArg_ParseTuple(args, format,
1854 PyUnicode_FSConverter, &opath))
1855 return NULL;
1856 path = PyBytes_AsString(opath);
1857 Py_BEGIN_ALLOW_THREADS
1858 res = (*statfunc)(path, &st);
1859 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001860
Victor Stinner8c62be82010-05-06 00:08:46 +00001861 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001862#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001863 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001864#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001865 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001866#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001867 }
1868 else
1869 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001870
Victor Stinner8c62be82010-05-06 00:08:46 +00001871 Py_DECREF(opath);
1872 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001873}
1874
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001875/* POSIX methods */
1876
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001877PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001878"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001879Use the real uid/gid to test for access to a path. Note that most\n\
1880operations will use the effective uid/gid, therefore this routine can\n\
1881be used in a suid/sgid environment to test if the invoking user has the\n\
1882specified access to the path. The mode argument can be F_OK to test\n\
1883existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001884
1885static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001886posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001887{
Victor Stinner8c62be82010-05-06 00:08:46 +00001888 PyObject *opath;
1889 char *path;
1890 int mode;
1891
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001892#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001893 DWORD attr;
Victor Stinnereb5657a2011-09-30 01:44:27 +02001894 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00001895 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02001896 wchar_t* wpath = PyUnicode_AsUnicode(po);
1897 if (wpath == NULL)
1898 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001899 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001900 attr = GetFileAttributesW(wpath);
Victor Stinner8c62be82010-05-06 00:08:46 +00001901 Py_END_ALLOW_THREADS
1902 goto finish;
1903 }
1904 /* Drop the argument parsing error as narrow strings
1905 are also valid. */
1906 PyErr_Clear();
1907 if (!PyArg_ParseTuple(args, "O&i:access",
1908 PyUnicode_FSConverter, &opath, &mode))
1909 return NULL;
1910 path = PyBytes_AsString(opath);
1911 Py_BEGIN_ALLOW_THREADS
1912 attr = GetFileAttributesA(path);
1913 Py_END_ALLOW_THREADS
1914 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001915finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001916 if (attr == 0xFFFFFFFF)
1917 /* File does not exist, or cannot read attributes */
1918 return PyBool_FromLong(0);
1919 /* Access is possible if either write access wasn't requested, or
1920 the file isn't read-only, or if it's a directory, as there are
1921 no read-only directories on Windows. */
1922 return PyBool_FromLong(!(mode & 2)
1923 || !(attr & FILE_ATTRIBUTE_READONLY)
1924 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001925#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001926 int res;
1927 if (!PyArg_ParseTuple(args, "O&i:access",
1928 PyUnicode_FSConverter, &opath, &mode))
1929 return NULL;
1930 path = PyBytes_AsString(opath);
1931 Py_BEGIN_ALLOW_THREADS
1932 res = access(path, mode);
1933 Py_END_ALLOW_THREADS
1934 Py_DECREF(opath);
1935 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001936#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001937}
1938
Guido van Rossumd371ff11999-01-25 16:12:23 +00001939#ifndef F_OK
1940#define F_OK 0
1941#endif
1942#ifndef R_OK
1943#define R_OK 4
1944#endif
1945#ifndef W_OK
1946#define W_OK 2
1947#endif
1948#ifndef X_OK
1949#define X_OK 1
1950#endif
1951
1952#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001953PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001954"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001955Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001956
1957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001958posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001959{
Victor Stinner8c62be82010-05-06 00:08:46 +00001960 int id;
1961 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001962
Victor Stinner8c62be82010-05-06 00:08:46 +00001963 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1964 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001965
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001966#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001967 /* file descriptor 0 only, the default input device (stdin) */
1968 if (id == 0) {
1969 ret = ttyname();
1970 }
1971 else {
1972 ret = NULL;
1973 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001974#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001975 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001976#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 if (ret == NULL)
1978 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001979 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001980}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001981#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001982
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001983#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001984PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001985"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001986Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001987
1988static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001989posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001990{
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 char *ret;
1992 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001993
Greg Wardb48bc172000-03-01 21:51:56 +00001994#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001995 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001996#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001997 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001998#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001999 if (ret == NULL)
2000 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002001 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002002}
2003#endif
2004
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002005PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002006"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002007Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002008
Barry Warsaw53699e91996-12-10 23:23:01 +00002009static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002010posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002011{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002012#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002014#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002015 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00002016#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002017 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002018#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002019 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002020#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002021}
2022
Fred Drake4d1e64b2002-04-15 19:40:07 +00002023#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002024PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002025"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00002026Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002027opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002028
2029static PyObject *
2030posix_fchdir(PyObject *self, PyObject *fdobj)
2031{
Victor Stinner8c62be82010-05-06 00:08:46 +00002032 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002033}
2034#endif /* HAVE_FCHDIR */
2035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002036
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002037PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002038"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002039Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002040
Barry Warsaw53699e91996-12-10 23:23:01 +00002041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002042posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002043{
Victor Stinner8c62be82010-05-06 00:08:46 +00002044 PyObject *opath = NULL;
2045 char *path = NULL;
2046 int i;
2047 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002048#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002049 DWORD attr;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002050 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00002051 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002052 wchar_t *wpath = PyUnicode_AsUnicode(po);
2053 if (wpath == NULL)
2054 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002055 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02002056 attr = GetFileAttributesW(wpath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002057 if (attr != 0xFFFFFFFF) {
2058 if (i & _S_IWRITE)
2059 attr &= ~FILE_ATTRIBUTE_READONLY;
2060 else
2061 attr |= FILE_ATTRIBUTE_READONLY;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002062 res = SetFileAttributesW(wpath, attr);
Victor Stinner8c62be82010-05-06 00:08:46 +00002063 }
2064 else
2065 res = 0;
2066 Py_END_ALLOW_THREADS
2067 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02002068 return win32_error_object("chmod", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 Py_INCREF(Py_None);
2070 return Py_None;
2071 }
2072 /* Drop the argument parsing error as narrow strings
2073 are also valid. */
2074 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002075
Victor Stinner8c62be82010-05-06 00:08:46 +00002076 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
2077 &opath, &i))
2078 return NULL;
2079 path = PyBytes_AsString(opath);
2080 Py_BEGIN_ALLOW_THREADS
2081 attr = GetFileAttributesA(path);
2082 if (attr != 0xFFFFFFFF) {
2083 if (i & _S_IWRITE)
2084 attr &= ~FILE_ATTRIBUTE_READONLY;
2085 else
2086 attr |= FILE_ATTRIBUTE_READONLY;
2087 res = SetFileAttributesA(path, attr);
2088 }
2089 else
2090 res = 0;
2091 Py_END_ALLOW_THREADS
2092 if (!res) {
2093 win32_error("chmod", path);
2094 Py_DECREF(opath);
2095 return NULL;
2096 }
2097 Py_DECREF(opath);
2098 Py_INCREF(Py_None);
2099 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002100#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00002101 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
2102 &opath, &i))
2103 return NULL;
2104 path = PyBytes_AsString(opath);
2105 Py_BEGIN_ALLOW_THREADS
2106 res = chmod(path, i);
2107 Py_END_ALLOW_THREADS
2108 if (res < 0)
2109 return posix_error_with_allocated_filename(opath);
2110 Py_DECREF(opath);
2111 Py_INCREF(Py_None);
2112 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002113#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002114}
2115
Christian Heimes4e30a842007-11-30 22:12:06 +00002116#ifdef HAVE_FCHMOD
2117PyDoc_STRVAR(posix_fchmod__doc__,
2118"fchmod(fd, mode)\n\n\
2119Change the access permissions of the file given by file\n\
2120descriptor fd.");
2121
2122static PyObject *
2123posix_fchmod(PyObject *self, PyObject *args)
2124{
Victor Stinner8c62be82010-05-06 00:08:46 +00002125 int fd, mode, res;
2126 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2127 return NULL;
2128 Py_BEGIN_ALLOW_THREADS
2129 res = fchmod(fd, mode);
2130 Py_END_ALLOW_THREADS
2131 if (res < 0)
2132 return posix_error();
2133 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002134}
2135#endif /* HAVE_FCHMOD */
2136
2137#ifdef HAVE_LCHMOD
2138PyDoc_STRVAR(posix_lchmod__doc__,
2139"lchmod(path, mode)\n\n\
2140Change the access permissions of a file. If path is a symlink, this\n\
2141affects the link itself rather than the target.");
2142
2143static PyObject *
2144posix_lchmod(PyObject *self, PyObject *args)
2145{
Victor Stinner8c62be82010-05-06 00:08:46 +00002146 PyObject *opath;
2147 char *path;
2148 int i;
2149 int res;
2150 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2151 &opath, &i))
2152 return NULL;
2153 path = PyBytes_AsString(opath);
2154 Py_BEGIN_ALLOW_THREADS
2155 res = lchmod(path, i);
2156 Py_END_ALLOW_THREADS
2157 if (res < 0)
2158 return posix_error_with_allocated_filename(opath);
2159 Py_DECREF(opath);
2160 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002161}
2162#endif /* HAVE_LCHMOD */
2163
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002164
Thomas Wouterscf297e42007-02-23 15:07:44 +00002165#ifdef HAVE_CHFLAGS
2166PyDoc_STRVAR(posix_chflags__doc__,
2167"chflags(path, flags)\n\n\
2168Set file flags.");
2169
2170static PyObject *
2171posix_chflags(PyObject *self, PyObject *args)
2172{
Victor Stinner8c62be82010-05-06 00:08:46 +00002173 PyObject *opath;
2174 char *path;
2175 unsigned long flags;
2176 int res;
2177 if (!PyArg_ParseTuple(args, "O&k:chflags",
2178 PyUnicode_FSConverter, &opath, &flags))
2179 return NULL;
2180 path = PyBytes_AsString(opath);
2181 Py_BEGIN_ALLOW_THREADS
2182 res = chflags(path, flags);
2183 Py_END_ALLOW_THREADS
2184 if (res < 0)
2185 return posix_error_with_allocated_filename(opath);
2186 Py_DECREF(opath);
2187 Py_INCREF(Py_None);
2188 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002189}
2190#endif /* HAVE_CHFLAGS */
2191
2192#ifdef HAVE_LCHFLAGS
2193PyDoc_STRVAR(posix_lchflags__doc__,
2194"lchflags(path, flags)\n\n\
2195Set file flags.\n\
2196This function will not follow symbolic links.");
2197
2198static PyObject *
2199posix_lchflags(PyObject *self, PyObject *args)
2200{
Victor Stinner8c62be82010-05-06 00:08:46 +00002201 PyObject *opath;
2202 char *path;
2203 unsigned long flags;
2204 int res;
2205 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2206 PyUnicode_FSConverter, &opath, &flags))
2207 return NULL;
2208 path = PyBytes_AsString(opath);
2209 Py_BEGIN_ALLOW_THREADS
2210 res = lchflags(path, flags);
2211 Py_END_ALLOW_THREADS
2212 if (res < 0)
2213 return posix_error_with_allocated_filename(opath);
2214 Py_DECREF(opath);
2215 Py_INCREF(Py_None);
2216 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002217}
2218#endif /* HAVE_LCHFLAGS */
2219
Martin v. Löwis244edc82001-10-04 22:44:26 +00002220#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002221PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002222"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002223Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002224
2225static PyObject *
2226posix_chroot(PyObject *self, PyObject *args)
2227{
Victor Stinner8c62be82010-05-06 00:08:46 +00002228 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002229}
2230#endif
2231
Guido van Rossum21142a01999-01-08 21:05:37 +00002232#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002233PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002234"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002235force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002236
2237static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002238posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002239{
Stefan Krah0e803b32010-11-26 16:16:47 +00002240 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002241}
2242#endif /* HAVE_FSYNC */
2243
Ross Lagerwall7807c352011-03-17 20:20:30 +02002244#ifdef HAVE_SYNC
2245PyDoc_STRVAR(posix_sync__doc__,
2246"sync()\n\n\
2247Force write of everything to disk.");
2248
2249static PyObject *
2250posix_sync(PyObject *self, PyObject *noargs)
2251{
2252 Py_BEGIN_ALLOW_THREADS
2253 sync();
2254 Py_END_ALLOW_THREADS
2255 Py_RETURN_NONE;
2256}
2257#endif
2258
Guido van Rossum21142a01999-01-08 21:05:37 +00002259#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002260
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002261#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002262extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2263#endif
2264
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002265PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002266"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002267force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002268 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002269
2270static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002271posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002272{
Stefan Krah0e803b32010-11-26 16:16:47 +00002273 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002274}
2275#endif /* HAVE_FDATASYNC */
2276
2277
Fredrik Lundh10723342000-07-10 16:38:09 +00002278#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002279PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002280"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002281Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002282
Barry Warsaw53699e91996-12-10 23:23:01 +00002283static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002284posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002285{
Victor Stinner8c62be82010-05-06 00:08:46 +00002286 PyObject *opath;
2287 char *path;
2288 long uid, gid;
2289 int res;
2290 if (!PyArg_ParseTuple(args, "O&ll:chown",
2291 PyUnicode_FSConverter, &opath,
2292 &uid, &gid))
2293 return NULL;
2294 path = PyBytes_AsString(opath);
2295 Py_BEGIN_ALLOW_THREADS
2296 res = chown(path, (uid_t) uid, (gid_t) gid);
2297 Py_END_ALLOW_THREADS
2298 if (res < 0)
2299 return posix_error_with_allocated_filename(opath);
2300 Py_DECREF(opath);
2301 Py_INCREF(Py_None);
2302 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002303}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002304#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002305
Christian Heimes4e30a842007-11-30 22:12:06 +00002306#ifdef HAVE_FCHOWN
2307PyDoc_STRVAR(posix_fchown__doc__,
2308"fchown(fd, uid, gid)\n\n\
2309Change the owner and group id of the file given by file descriptor\n\
2310fd to the numeric uid and gid.");
2311
2312static PyObject *
2313posix_fchown(PyObject *self, PyObject *args)
2314{
Victor Stinner8c62be82010-05-06 00:08:46 +00002315 int fd;
2316 long uid, gid;
2317 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002318 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002319 return NULL;
2320 Py_BEGIN_ALLOW_THREADS
2321 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2322 Py_END_ALLOW_THREADS
2323 if (res < 0)
2324 return posix_error();
2325 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002326}
2327#endif /* HAVE_FCHOWN */
2328
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002329#ifdef HAVE_LCHOWN
2330PyDoc_STRVAR(posix_lchown__doc__,
2331"lchown(path, uid, gid)\n\n\
2332Change the owner and group id of path to the numeric uid and gid.\n\
2333This function will not follow symbolic links.");
2334
2335static PyObject *
2336posix_lchown(PyObject *self, PyObject *args)
2337{
Victor Stinner8c62be82010-05-06 00:08:46 +00002338 PyObject *opath;
2339 char *path;
2340 long uid, gid;
2341 int res;
2342 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2343 PyUnicode_FSConverter, &opath,
2344 &uid, &gid))
2345 return NULL;
2346 path = PyBytes_AsString(opath);
2347 Py_BEGIN_ALLOW_THREADS
2348 res = lchown(path, (uid_t) uid, (gid_t) gid);
2349 Py_END_ALLOW_THREADS
2350 if (res < 0)
2351 return posix_error_with_allocated_filename(opath);
2352 Py_DECREF(opath);
2353 Py_INCREF(Py_None);
2354 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002355}
2356#endif /* HAVE_LCHOWN */
2357
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002358
Guido van Rossum36bc6801995-06-14 22:54:23 +00002359#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002360static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002361posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002362{
Victor Stinner8c62be82010-05-06 00:08:46 +00002363 char buf[1026];
2364 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002365
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002366#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002367 if (!use_bytes) {
2368 wchar_t wbuf[1026];
2369 wchar_t *wbuf2 = wbuf;
2370 PyObject *resobj;
2371 DWORD len;
2372 Py_BEGIN_ALLOW_THREADS
2373 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2374 /* If the buffer is large enough, len does not include the
2375 terminating \0. If the buffer is too small, len includes
2376 the space needed for the terminator. */
2377 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2378 wbuf2 = malloc(len * sizeof(wchar_t));
2379 if (wbuf2)
2380 len = GetCurrentDirectoryW(len, wbuf2);
2381 }
2382 Py_END_ALLOW_THREADS
2383 if (!wbuf2) {
2384 PyErr_NoMemory();
2385 return NULL;
2386 }
2387 if (!len) {
2388 if (wbuf2 != wbuf) free(wbuf2);
2389 return win32_error("getcwdu", NULL);
2390 }
2391 resobj = PyUnicode_FromWideChar(wbuf2, len);
2392 if (wbuf2 != wbuf) free(wbuf2);
2393 return resobj;
2394 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002395#endif
2396
Victor Stinner8c62be82010-05-06 00:08:46 +00002397 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002398#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002399 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002400#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002401 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002402#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002403 Py_END_ALLOW_THREADS
2404 if (res == NULL)
2405 return posix_error();
2406 if (use_bytes)
2407 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002408 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002409}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002410
2411PyDoc_STRVAR(posix_getcwd__doc__,
2412"getcwd() -> path\n\n\
2413Return a unicode string representing the current working directory.");
2414
2415static PyObject *
2416posix_getcwd_unicode(PyObject *self)
2417{
2418 return posix_getcwd(0);
2419}
2420
2421PyDoc_STRVAR(posix_getcwdb__doc__,
2422"getcwdb() -> path\n\n\
2423Return a bytes string representing the current working directory.");
2424
2425static PyObject *
2426posix_getcwd_bytes(PyObject *self)
2427{
2428 return posix_getcwd(1);
2429}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002430#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002431
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002432
Guido van Rossumb6775db1994-08-01 11:34:53 +00002433#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002434PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002435"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002436Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002437
Barry Warsaw53699e91996-12-10 23:23:01 +00002438static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002439posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002440{
Victor Stinner8c62be82010-05-06 00:08:46 +00002441 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002442}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002443#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002444
Brian Curtin1b9df392010-11-24 20:24:31 +00002445#ifdef MS_WINDOWS
2446PyDoc_STRVAR(win32_link__doc__,
2447"link(src, dst)\n\n\
2448Create a hard link to a file.");
2449
2450static PyObject *
2451win32_link(PyObject *self, PyObject *args)
2452{
2453 PyObject *osrc, *odst;
2454 char *src, *dst;
2455 BOOL rslt;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002456 PyObject *usrc, *udst;
Brian Curtin1b9df392010-11-24 20:24:31 +00002457
Victor Stinnereb5657a2011-09-30 01:44:27 +02002458 if (PyArg_ParseTuple(args, "UU:link", &usrc, &udst))
2459 {
2460 wchar_t *wsrc, *wdst;
2461 wsrc = PyUnicode_AsUnicode(usrc);
2462 if (wsrc == NULL)
2463 return NULL;
2464 wdst = PyUnicode_AsUnicode(udst);
2465 if (wdst == NULL)
2466 return NULL;
2467
Brian Curtinfc889c42010-11-28 23:59:46 +00002468 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02002469 rslt = CreateHardLinkW(wdst, wsrc, NULL);
Brian Curtinfc889c42010-11-28 23:59:46 +00002470 Py_END_ALLOW_THREADS
2471
2472 if (rslt == 0)
2473 return win32_error("link", NULL);
2474
2475 Py_RETURN_NONE;
2476 }
2477
2478 /* Narrow strings also valid. */
2479 PyErr_Clear();
2480
Brian Curtin1b9df392010-11-24 20:24:31 +00002481 if (!PyArg_ParseTuple(args, "O&O&:link", PyUnicode_FSConverter, &osrc,
2482 PyUnicode_FSConverter, &odst))
2483 return NULL;
2484
2485 src = PyBytes_AsString(osrc);
2486 dst = PyBytes_AsString(odst);
2487
2488 Py_BEGIN_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00002489 rslt = CreateHardLinkA(dst, src, NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002490 Py_END_ALLOW_THREADS
2491
Stefan Krah30b341f2010-11-27 11:44:18 +00002492 Py_DECREF(osrc);
2493 Py_DECREF(odst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002494 if (rslt == 0)
Brian Curtinfc889c42010-11-28 23:59:46 +00002495 return win32_error("link", NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002496
2497 Py_RETURN_NONE;
2498}
2499#endif /* MS_WINDOWS */
2500
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002501
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002502PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002503"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002504Return a list containing the names of the entries in the directory.\n\
2505\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002506 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002507\n\
2508The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002509entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002510
Barry Warsaw53699e91996-12-10 23:23:01 +00002511static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002512posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002513{
Victor Stinner8c62be82010-05-06 00:08:46 +00002514 /* XXX Should redo this putting the (now four) versions of opendir
2515 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002516#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002517
Victor Stinner8c62be82010-05-06 00:08:46 +00002518 PyObject *d, *v;
2519 HANDLE hFindFile;
2520 BOOL result;
2521 WIN32_FIND_DATA FileData;
2522 PyObject *opath;
2523 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2524 char *bufptr = namebuf;
2525 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002526
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002527 PyObject *po = NULL;
2528 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002529 WIN32_FIND_DATAW wFileData;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002530 wchar_t *wnamebuf, *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002531
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002532 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002533 po_wchars = L".";
2534 len = 1;
2535 } else {
Victor Stinnerbeac78b2011-10-11 21:55:01 +02002536 po_wchars = PyUnicode_AsUnicodeAndSize(po, &len);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002537 if (po_wchars == NULL)
2538 return NULL;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002539 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002540 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002541 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2542 if (!wnamebuf) {
2543 PyErr_NoMemory();
2544 return NULL;
2545 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002546 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002547 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002548 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00002549 if (wch != L'/' && wch != L'\\' && wch != L':')
2550 wnamebuf[len++] = L'\\';
2551 wcscpy(wnamebuf + len, L"*.*");
2552 }
2553 if ((d = PyList_New(0)) == NULL) {
2554 free(wnamebuf);
2555 return NULL;
2556 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002557 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002558 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002559 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002560 if (hFindFile == INVALID_HANDLE_VALUE) {
2561 int error = GetLastError();
2562 if (error == ERROR_FILE_NOT_FOUND) {
2563 free(wnamebuf);
2564 return d;
2565 }
2566 Py_DECREF(d);
2567 win32_error_unicode("FindFirstFileW", wnamebuf);
2568 free(wnamebuf);
2569 return NULL;
2570 }
2571 do {
2572 /* Skip over . and .. */
2573 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2574 wcscmp(wFileData.cFileName, L"..") != 0) {
2575 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2576 if (v == NULL) {
2577 Py_DECREF(d);
2578 d = NULL;
2579 break;
2580 }
2581 if (PyList_Append(d, v) != 0) {
2582 Py_DECREF(v);
2583 Py_DECREF(d);
2584 d = NULL;
2585 break;
2586 }
2587 Py_DECREF(v);
2588 }
2589 Py_BEGIN_ALLOW_THREADS
2590 result = FindNextFileW(hFindFile, &wFileData);
2591 Py_END_ALLOW_THREADS
2592 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2593 it got to the end of the directory. */
2594 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2595 Py_DECREF(d);
2596 win32_error_unicode("FindNextFileW", wnamebuf);
2597 FindClose(hFindFile);
2598 free(wnamebuf);
2599 return NULL;
2600 }
2601 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002602
Victor Stinner8c62be82010-05-06 00:08:46 +00002603 if (FindClose(hFindFile) == FALSE) {
2604 Py_DECREF(d);
2605 win32_error_unicode("FindClose", wnamebuf);
2606 free(wnamebuf);
2607 return NULL;
2608 }
2609 free(wnamebuf);
2610 return d;
2611 }
2612 /* Drop the argument parsing error as narrow strings
2613 are also valid. */
2614 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002615
Victor Stinner8c62be82010-05-06 00:08:46 +00002616 if (!PyArg_ParseTuple(args, "O&:listdir",
2617 PyUnicode_FSConverter, &opath))
2618 return NULL;
2619 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2620 PyErr_SetString(PyExc_ValueError, "path too long");
2621 Py_DECREF(opath);
2622 return NULL;
2623 }
2624 strcpy(namebuf, PyBytes_AsString(opath));
2625 len = PyObject_Size(opath);
Stefan Krah2a7feee2010-11-27 22:06:49 +00002626 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002627 if (len > 0) {
2628 char ch = namebuf[len-1];
2629 if (ch != SEP && ch != ALTSEP && ch != ':')
2630 namebuf[len++] = '/';
2631 strcpy(namebuf + len, "*.*");
2632 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002633
Victor Stinner8c62be82010-05-06 00:08:46 +00002634 if ((d = PyList_New(0)) == NULL)
2635 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002636
Antoine Pitroub73caab2010-08-09 23:39:31 +00002637 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002638 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002639 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002640 if (hFindFile == INVALID_HANDLE_VALUE) {
2641 int error = GetLastError();
2642 if (error == ERROR_FILE_NOT_FOUND)
2643 return d;
2644 Py_DECREF(d);
2645 return win32_error("FindFirstFile", namebuf);
2646 }
2647 do {
2648 /* Skip over . and .. */
2649 if (strcmp(FileData.cFileName, ".") != 0 &&
2650 strcmp(FileData.cFileName, "..") != 0) {
2651 v = PyBytes_FromString(FileData.cFileName);
2652 if (v == NULL) {
2653 Py_DECREF(d);
2654 d = NULL;
2655 break;
2656 }
2657 if (PyList_Append(d, v) != 0) {
2658 Py_DECREF(v);
2659 Py_DECREF(d);
2660 d = NULL;
2661 break;
2662 }
2663 Py_DECREF(v);
2664 }
2665 Py_BEGIN_ALLOW_THREADS
2666 result = FindNextFile(hFindFile, &FileData);
2667 Py_END_ALLOW_THREADS
2668 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2669 it got to the end of the directory. */
2670 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2671 Py_DECREF(d);
2672 win32_error("FindNextFile", namebuf);
2673 FindClose(hFindFile);
2674 return NULL;
2675 }
2676 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002677
Victor Stinner8c62be82010-05-06 00:08:46 +00002678 if (FindClose(hFindFile) == FALSE) {
2679 Py_DECREF(d);
2680 return win32_error("FindClose", namebuf);
2681 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002682
Victor Stinner8c62be82010-05-06 00:08:46 +00002683 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002684
Tim Peters0bb44a42000-09-15 07:44:49 +00002685#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002686
2687#ifndef MAX_PATH
2688#define MAX_PATH CCHMAXPATH
2689#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002690 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002691 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002692 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002693 PyObject *d, *v;
2694 char namebuf[MAX_PATH+5];
2695 HDIR hdir = 1;
2696 ULONG srchcnt = 1;
2697 FILEFINDBUF3 ep;
2698 APIRET rc;
2699
Victor Stinner8c62be82010-05-06 00:08:46 +00002700 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002701 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002702 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002703 name = PyBytes_AsString(oname);
2704 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002705 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002706 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002707 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002708 return NULL;
2709 }
2710 strcpy(namebuf, name);
2711 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002712 if (*pt == ALTSEP)
2713 *pt = SEP;
2714 if (namebuf[len-1] != SEP)
2715 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002716 strcpy(namebuf + len, "*.*");
2717
Neal Norwitz6c913782007-10-14 03:23:09 +00002718 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002719 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002720 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002721 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002722
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002723 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2724 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002725 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002726 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2727 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2728 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002729
2730 if (rc != NO_ERROR) {
2731 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002732 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002733 }
2734
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002735 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002736 do {
2737 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002738 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002739 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002740
2741 strcpy(namebuf, ep.achName);
2742
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002743 /* Leave Case of Name Alone -- In Native Form */
2744 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002745
Christian Heimes72b710a2008-05-26 13:28:38 +00002746 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002747 if (v == NULL) {
2748 Py_DECREF(d);
2749 d = NULL;
2750 break;
2751 }
2752 if (PyList_Append(d, v) != 0) {
2753 Py_DECREF(v);
2754 Py_DECREF(d);
2755 d = NULL;
2756 break;
2757 }
2758 Py_DECREF(v);
2759 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2760 }
2761
Victor Stinnerdcb24032010-04-22 12:08:36 +00002762 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002763 return d;
2764#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002765 PyObject *oname;
2766 char *name;
2767 PyObject *d, *v;
2768 DIR *dirp;
2769 struct dirent *ep;
2770 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002771
Victor Stinner8c62be82010-05-06 00:08:46 +00002772 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002773 /* v is never read, so it does not need to be initialized yet. */
2774 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002775 arg_is_unicode = 0;
2776 PyErr_Clear();
2777 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002778 oname = NULL;
2779 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002780 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002781 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002782 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002783 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002784 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002785 Py_BEGIN_ALLOW_THREADS
2786 dirp = opendir(name);
2787 Py_END_ALLOW_THREADS
2788 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002789 return posix_error_with_allocated_filename(oname);
2790 }
2791 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002792 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002793 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002794 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002795 Py_DECREF(oname);
2796 return NULL;
2797 }
2798 for (;;) {
2799 errno = 0;
2800 Py_BEGIN_ALLOW_THREADS
2801 ep = readdir(dirp);
2802 Py_END_ALLOW_THREADS
2803 if (ep == NULL) {
2804 if (errno == 0) {
2805 break;
2806 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002807 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002808 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002809 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002810 Py_DECREF(d);
2811 return posix_error_with_allocated_filename(oname);
2812 }
2813 }
2814 if (ep->d_name[0] == '.' &&
2815 (NAMLEN(ep) == 1 ||
2816 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2817 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002818 if (arg_is_unicode)
2819 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2820 else
2821 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002822 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002823 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002824 break;
2825 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002826 if (PyList_Append(d, v) != 0) {
2827 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002828 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002829 break;
2830 }
2831 Py_DECREF(v);
2832 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002833 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002834 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002835 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002836 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002837
Victor Stinner8c62be82010-05-06 00:08:46 +00002838 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002839
Tim Peters0bb44a42000-09-15 07:44:49 +00002840#endif /* which OS */
2841} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002842
Antoine Pitrou8250e232011-02-25 23:41:16 +00002843#ifdef HAVE_FDOPENDIR
2844PyDoc_STRVAR(posix_fdlistdir__doc__,
2845"fdlistdir(fd) -> list_of_strings\n\n\
2846Like listdir(), but uses a file descriptor instead.\n\
2847After succesful execution of this function, fd will be closed.");
2848
2849static PyObject *
2850posix_fdlistdir(PyObject *self, PyObject *args)
2851{
2852 PyObject *d, *v;
2853 DIR *dirp;
2854 struct dirent *ep;
2855 int fd;
2856
2857 errno = 0;
2858 if (!PyArg_ParseTuple(args, "i:fdlistdir", &fd))
2859 return NULL;
2860 Py_BEGIN_ALLOW_THREADS
2861 dirp = fdopendir(fd);
2862 Py_END_ALLOW_THREADS
2863 if (dirp == NULL) {
2864 close(fd);
2865 return posix_error();
2866 }
2867 if ((d = PyList_New(0)) == NULL) {
2868 Py_BEGIN_ALLOW_THREADS
2869 closedir(dirp);
2870 Py_END_ALLOW_THREADS
2871 return NULL;
2872 }
2873 for (;;) {
2874 errno = 0;
2875 Py_BEGIN_ALLOW_THREADS
2876 ep = readdir(dirp);
2877 Py_END_ALLOW_THREADS
2878 if (ep == NULL) {
2879 if (errno == 0) {
2880 break;
2881 } else {
2882 Py_BEGIN_ALLOW_THREADS
2883 closedir(dirp);
2884 Py_END_ALLOW_THREADS
2885 Py_DECREF(d);
2886 return posix_error();
2887 }
2888 }
2889 if (ep->d_name[0] == '.' &&
2890 (NAMLEN(ep) == 1 ||
2891 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2892 continue;
2893 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2894 if (v == NULL) {
2895 Py_CLEAR(d);
2896 break;
2897 }
2898 if (PyList_Append(d, v) != 0) {
2899 Py_DECREF(v);
2900 Py_CLEAR(d);
2901 break;
2902 }
2903 Py_DECREF(v);
2904 }
2905 Py_BEGIN_ALLOW_THREADS
2906 closedir(dirp);
2907 Py_END_ALLOW_THREADS
2908
2909 return d;
2910}
2911#endif
2912
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002913#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002914/* A helper function for abspath on win32 */
2915static PyObject *
2916posix__getfullpathname(PyObject *self, PyObject *args)
2917{
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 PyObject *opath;
2919 char *path;
2920 char outbuf[MAX_PATH*2];
2921 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002922#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02002923 PyObject *po;
2924
2925 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
2926 {
2927 wchar_t *wpath;
2928 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2929 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00002930 DWORD result;
2931 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002932
2933 wpath = PyUnicode_AsUnicode(po);
2934 if (wpath == NULL)
2935 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002936 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02002937 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00002938 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02002939 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002940 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00002941 if (!woutbufp)
2942 return PyErr_NoMemory();
2943 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2944 }
2945 if (result)
2946 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2947 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02002948 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00002949 if (woutbufp != woutbuf)
2950 free(woutbufp);
2951 return v;
2952 }
2953 /* Drop the argument parsing error as narrow strings
2954 are also valid. */
2955 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002956#endif
Victor Stinnereb5657a2011-09-30 01:44:27 +02002957
Victor Stinner8c62be82010-05-06 00:08:46 +00002958 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2959 PyUnicode_FSConverter, &opath))
2960 return NULL;
2961 path = PyBytes_AsString(opath);
Victor Stinner63941882011-09-29 00:42:28 +02002962 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00002963 outbuf, &temp)) {
2964 win32_error("GetFullPathName", path);
2965 Py_DECREF(opath);
2966 return NULL;
2967 }
2968 Py_DECREF(opath);
2969 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2970 return PyUnicode_Decode(outbuf, strlen(outbuf),
2971 Py_FileSystemDefaultEncoding, NULL);
2972 }
2973 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002974} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002975
Brian Curtind25aef52011-06-13 15:16:04 -05002976
Brian Curtinf5e76d02010-11-24 13:14:05 +00002977
Brian Curtind40e6f72010-07-08 21:39:08 +00002978/* A helper function for samepath on windows */
2979static PyObject *
2980posix__getfinalpathname(PyObject *self, PyObject *args)
2981{
2982 HANDLE hFile;
2983 int buf_size;
2984 wchar_t *target_path;
2985 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002986 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00002987 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002988
Victor Stinnereb5657a2011-09-30 01:44:27 +02002989 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00002990 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002991 path = PyUnicode_AsUnicode(po);
2992 if (path == NULL)
2993 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00002994
2995 if(!check_GetFinalPathNameByHandle()) {
2996 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2997 NotImplementedError. */
2998 return PyErr_Format(PyExc_NotImplementedError,
2999 "GetFinalPathNameByHandle not available on this platform");
3000 }
3001
3002 hFile = CreateFileW(
3003 path,
3004 0, /* desired access */
3005 0, /* share mode */
3006 NULL, /* security attributes */
3007 OPEN_EXISTING,
3008 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3009 FILE_FLAG_BACKUP_SEMANTICS,
3010 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003011
Victor Stinnereb5657a2011-09-30 01:44:27 +02003012 if(hFile == INVALID_HANDLE_VALUE)
3013 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003014
3015 /* We have a good handle to the target, use it to determine the
3016 target path name. */
3017 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3018
3019 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003020 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003021
3022 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3023 if(!target_path)
3024 return PyErr_NoMemory();
3025
3026 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3027 buf_size, VOLUME_NAME_DOS);
3028 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003029 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003030
3031 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003032 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003033
3034 target_path[result_length] = 0;
3035 result = PyUnicode_FromUnicode(target_path, result_length);
3036 free(target_path);
3037 return result;
3038
3039} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003040
3041static PyObject *
3042posix__getfileinformation(PyObject *self, PyObject *args)
3043{
3044 HANDLE hFile;
3045 BY_HANDLE_FILE_INFORMATION info;
3046 int fd;
3047
3048 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3049 return NULL;
3050
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003051 if (!_PyVerify_fd(fd))
3052 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003053
3054 hFile = (HANDLE)_get_osfhandle(fd);
3055 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003056 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003057
3058 if (!GetFileInformationByHandle(hFile, &info))
3059 return win32_error("_getfileinformation", NULL);
3060
3061 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3062 info.nFileIndexHigh,
3063 info.nFileIndexLow);
3064}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003065
Brian Curtin95d028f2011-06-09 09:10:38 -05003066PyDoc_STRVAR(posix__isdir__doc__,
3067"Return true if the pathname refers to an existing directory.");
3068
Brian Curtin9c669cc2011-06-08 18:17:18 -05003069static PyObject *
3070posix__isdir(PyObject *self, PyObject *args)
3071{
3072 PyObject *opath;
3073 char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003074 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003075 DWORD attributes;
3076
3077 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003078 wchar_t *wpath = PyUnicode_AsUnicode(po);
3079 if (wpath == NULL)
3080 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003081
3082 attributes = GetFileAttributesW(wpath);
3083 if (attributes == INVALID_FILE_ATTRIBUTES)
3084 Py_RETURN_FALSE;
3085 goto check;
3086 }
3087 /* Drop the argument parsing error as narrow strings
3088 are also valid. */
3089 PyErr_Clear();
3090
3091 if (!PyArg_ParseTuple(args, "O&:_isdir",
3092 PyUnicode_FSConverter, &opath))
3093 return NULL;
3094
3095 path = PyBytes_AsString(opath);
3096 attributes = GetFileAttributesA(path);
3097 if (attributes == INVALID_FILE_ATTRIBUTES)
3098 Py_RETURN_FALSE;
3099
3100check:
3101 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3102 Py_RETURN_TRUE;
3103 else
3104 Py_RETURN_FALSE;
3105}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003106#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003107
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003108PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003109"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003110Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003111
Barry Warsaw53699e91996-12-10 23:23:01 +00003112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003113posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003114{
Victor Stinner8c62be82010-05-06 00:08:46 +00003115 int res;
3116 PyObject *opath;
3117 char *path;
3118 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003119
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003120#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003121 PyObject *po;
3122 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode))
3123 {
3124 wchar_t *wpath = PyUnicode_AsUnicode(po);
3125 if (wpath == NULL)
3126 return NULL;
3127
Victor Stinner8c62be82010-05-06 00:08:46 +00003128 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003129 res = CreateDirectoryW(wpath, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003130 Py_END_ALLOW_THREADS
3131 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003132 return win32_error_object("mkdir", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003133 Py_INCREF(Py_None);
3134 return Py_None;
3135 }
3136 /* Drop the argument parsing error as narrow strings
3137 are also valid. */
3138 PyErr_Clear();
3139 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
3140 PyUnicode_FSConverter, &opath, &mode))
3141 return NULL;
3142 path = PyBytes_AsString(opath);
3143 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003144 res = CreateDirectoryA(path, NULL);
3145 Py_END_ALLOW_THREADS
3146 if (!res) {
3147 win32_error("mkdir", path);
3148 Py_DECREF(opath);
3149 return NULL;
3150 }
3151 Py_DECREF(opath);
3152 Py_INCREF(Py_None);
3153 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003154#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003155
Victor Stinner8c62be82010-05-06 00:08:46 +00003156 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
3157 PyUnicode_FSConverter, &opath, &mode))
3158 return NULL;
3159 path = PyBytes_AsString(opath);
3160 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00003161#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00003162 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003163#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003164 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003165#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003166 Py_END_ALLOW_THREADS
3167 if (res < 0)
3168 return posix_error_with_allocated_filename(opath);
3169 Py_DECREF(opath);
3170 Py_INCREF(Py_None);
3171 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003172#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003173}
3174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003175
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003176/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3177#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003178#include <sys/resource.h>
3179#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003180
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003181
3182#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003183PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003184"nice(inc) -> new_priority\n\n\
3185Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003186
Barry Warsaw53699e91996-12-10 23:23:01 +00003187static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003188posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003189{
Victor Stinner8c62be82010-05-06 00:08:46 +00003190 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003191
Victor Stinner8c62be82010-05-06 00:08:46 +00003192 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3193 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003194
Victor Stinner8c62be82010-05-06 00:08:46 +00003195 /* There are two flavours of 'nice': one that returns the new
3196 priority (as required by almost all standards out there) and the
3197 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3198 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003199
Victor Stinner8c62be82010-05-06 00:08:46 +00003200 If we are of the nice family that returns the new priority, we
3201 need to clear errno before the call, and check if errno is filled
3202 before calling posix_error() on a returnvalue of -1, because the
3203 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003204
Victor Stinner8c62be82010-05-06 00:08:46 +00003205 errno = 0;
3206 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003207#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003208 if (value == 0)
3209 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003210#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003211 if (value == -1 && errno != 0)
3212 /* either nice() or getpriority() returned an error */
3213 return posix_error();
3214 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003215}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003216#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003217
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003218
3219#ifdef HAVE_GETPRIORITY
3220PyDoc_STRVAR(posix_getpriority__doc__,
3221"getpriority(which, who) -> current_priority\n\n\
3222Get program scheduling priority.");
3223
3224static PyObject *
3225posix_getpriority(PyObject *self, PyObject *args)
3226{
3227 int which, who, retval;
3228
3229 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3230 return NULL;
3231 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003232 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003233 if (errno != 0)
3234 return posix_error();
3235 return PyLong_FromLong((long)retval);
3236}
3237#endif /* HAVE_GETPRIORITY */
3238
3239
3240#ifdef HAVE_SETPRIORITY
3241PyDoc_STRVAR(posix_setpriority__doc__,
3242"setpriority(which, who, prio) -> None\n\n\
3243Set program scheduling priority.");
3244
3245static PyObject *
3246posix_setpriority(PyObject *self, PyObject *args)
3247{
3248 int which, who, prio, retval;
3249
3250 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3251 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003252 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003253 if (retval == -1)
3254 return posix_error();
3255 Py_RETURN_NONE;
3256}
3257#endif /* HAVE_SETPRIORITY */
3258
3259
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003260PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003261"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003262Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003263
Barry Warsaw53699e91996-12-10 23:23:01 +00003264static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003265posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003266{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003267#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003268 PyObject *o1, *o2;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003269 wchar_t *w1, *w2;
Victor Stinner8c62be82010-05-06 00:08:46 +00003270 char *p1, *p2;
3271 BOOL result;
3272 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
3273 goto error;
3274 if (!convert_to_unicode(&o1))
3275 goto error;
3276 if (!convert_to_unicode(&o2)) {
3277 Py_DECREF(o1);
3278 goto error;
3279 }
Victor Stinnereb5657a2011-09-30 01:44:27 +02003280 w1 = PyUnicode_AsUnicode(o1);
3281 if (w1 == NULL)
3282 goto error;
3283 w2 = PyUnicode_AsUnicode(o2);
3284 if (w2 == NULL)
3285 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00003286 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003287 result = MoveFileW(w1, w2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003288 Py_END_ALLOW_THREADS
3289 Py_DECREF(o1);
3290 Py_DECREF(o2);
3291 if (!result)
3292 return win32_error("rename", NULL);
3293 Py_INCREF(Py_None);
3294 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003295error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003296 PyErr_Clear();
3297 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
3298 return NULL;
3299 Py_BEGIN_ALLOW_THREADS
3300 result = MoveFileA(p1, p2);
3301 Py_END_ALLOW_THREADS
3302 if (!result)
3303 return win32_error("rename", NULL);
3304 Py_INCREF(Py_None);
3305 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003306#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003307 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003308#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003309}
3310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003311
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003312PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003313"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003314Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003315
Barry Warsaw53699e91996-12-10 23:23:01 +00003316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003317posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003318{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003319#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003320 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003321#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003322 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003323#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003324}
3325
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003326
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003327PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003328"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003329Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003330
Barry Warsaw53699e91996-12-10 23:23:01 +00003331static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003332posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003333{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003334#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00003335 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003336#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003337 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003338#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003339}
3340
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003341
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003342#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003343PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003344"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003345Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003346
Barry Warsaw53699e91996-12-10 23:23:01 +00003347static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003348posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003349{
Victor Stinner8c62be82010-05-06 00:08:46 +00003350 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003351#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003352 wchar_t *command;
3353 if (!PyArg_ParseTuple(args, "u:system", &command))
3354 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003355
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 Py_BEGIN_ALLOW_THREADS
3357 sts = _wsystem(command);
3358 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003359#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003360 PyObject *command_obj;
3361 char *command;
3362 if (!PyArg_ParseTuple(args, "O&:system",
3363 PyUnicode_FSConverter, &command_obj))
3364 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003365
Victor Stinner8c62be82010-05-06 00:08:46 +00003366 command = PyBytes_AsString(command_obj);
3367 Py_BEGIN_ALLOW_THREADS
3368 sts = system(command);
3369 Py_END_ALLOW_THREADS
3370 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003371#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003373}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003374#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003375
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003376
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003377PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003378"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003379Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003380
Barry Warsaw53699e91996-12-10 23:23:01 +00003381static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003382posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003383{
Victor Stinner8c62be82010-05-06 00:08:46 +00003384 int i;
3385 if (!PyArg_ParseTuple(args, "i:umask", &i))
3386 return NULL;
3387 i = (int)umask(i);
3388 if (i < 0)
3389 return posix_error();
3390 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003391}
3392
Brian Curtind40e6f72010-07-08 21:39:08 +00003393#ifdef MS_WINDOWS
3394
3395/* override the default DeleteFileW behavior so that directory
3396symlinks can be removed with this function, the same as with
3397Unix symlinks */
3398BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3399{
3400 WIN32_FILE_ATTRIBUTE_DATA info;
3401 WIN32_FIND_DATAW find_data;
3402 HANDLE find_data_handle;
3403 int is_directory = 0;
3404 int is_link = 0;
3405
3406 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3407 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003408
Brian Curtind40e6f72010-07-08 21:39:08 +00003409 /* Get WIN32_FIND_DATA structure for the path to determine if
3410 it is a symlink */
3411 if(is_directory &&
3412 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3413 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3414
3415 if(find_data_handle != INVALID_HANDLE_VALUE) {
3416 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3417 FindClose(find_data_handle);
3418 }
3419 }
3420 }
3421
3422 if (is_directory && is_link)
3423 return RemoveDirectoryW(lpFileName);
3424
3425 return DeleteFileW(lpFileName);
3426}
3427#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003428
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003429PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003430"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003431Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003432
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003433PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003434"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003435Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003436
Barry Warsaw53699e91996-12-10 23:23:01 +00003437static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003438posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003439{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003440#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003441 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3442 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003443#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003444 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003445#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003446}
3447
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003448
Guido van Rossumb6775db1994-08-01 11:34:53 +00003449#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003450PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003451"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003452Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003453
Barry Warsaw53699e91996-12-10 23:23:01 +00003454static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003455posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003456{
Victor Stinner8c62be82010-05-06 00:08:46 +00003457 struct utsname u;
3458 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003459
Victor Stinner8c62be82010-05-06 00:08:46 +00003460 Py_BEGIN_ALLOW_THREADS
3461 res = uname(&u);
3462 Py_END_ALLOW_THREADS
3463 if (res < 0)
3464 return posix_error();
3465 return Py_BuildValue("(sssss)",
3466 u.sysname,
3467 u.nodename,
3468 u.release,
3469 u.version,
3470 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003471}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003472#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003473
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003474
3475/*
3476 * Classic POSIX utime functions supported microseconds (1m/sec).
3477 * Newer POSIX functions support nanoseconds (1 billion per sec).
3478 * posixmodule now uses the new functions where possible.
3479 * This improves accuracy in many situations, for example shutil.copy2().
3480 *
3481 * The implementation isn't currently sophisticated enough to handle
3482 * a platform where HAVE_UTIMENSAT is true but HAVE_FUTIMENS is false.
3483 * Specifically, posix_futimes() would break.
3484 *
3485 * Supporting such a platform wouldn't be impossible; you'd need two
3486 * extract_time() functions, or make its precision a parameter.
3487 * Since such a platform seems unlikely we haven't bothered.
3488 */
3489#if defined(HAVE_UTIMENSAT)
3490#define EXTRACT_TIME_PRECISION (1e9)
3491#if !defined(HAVE_FUTIMENS)
3492#error You HAVE_UTIMENSAT but not HAVE_FUTIMENS... please see accompanying comment.
3493#endif
3494#else
3495#define EXTRACT_TIME_PRECISION (1e6)
3496#endif
3497
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003498static int
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003499extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003500{
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003501 time_t intval;
Victor Stinner8c62be82010-05-06 00:08:46 +00003502 if (PyFloat_Check(t)) {
3503 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003504 PyObject *intobj = PyNumber_Long(t);
Victor Stinner8c62be82010-05-06 00:08:46 +00003505 if (!intobj)
3506 return -1;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003507#if SIZEOF_TIME_T > SIZEOF_LONG
3508 intval = PyLong_AsUnsignedLongLongMask(intobj);
3509#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003510 intval = PyLong_AsLong(intobj);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003511#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003512 Py_DECREF(intobj);
3513 if (intval == -1 && PyErr_Occurred())
3514 return -1;
3515 *sec = intval;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003516
3517 *usec = (long)((tval - intval) * EXTRACT_TIME_PRECISION);
Victor Stinner8c62be82010-05-06 00:08:46 +00003518 if (*usec < 0)
3519 /* If rounding gave us a negative number,
3520 truncate. */
3521 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003522 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003523 }
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003524#if SIZEOF_TIME_T > SIZEOF_LONG
3525 intval = PyLong_AsUnsignedLongLongMask(t);
3526#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003527 intval = PyLong_AsLong(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003528#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003529 if (intval == -1 && PyErr_Occurred())
3530 return -1;
3531 *sec = intval;
3532 *usec = 0;
3533 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003534}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003535
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003536PyDoc_STRVAR(posix_utime__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003537"utime(path[, (atime, mtime)])\n\
3538Set the access and modified time of the file to the given values.\n\
3539If no second argument is used, set the access and modified times to\n\
3540the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003541
Barry Warsaw53699e91996-12-10 23:23:01 +00003542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003543posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003544{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003545#ifdef MS_WINDOWS
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003546 PyObject *arg = Py_None;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003547 PyObject *obwpath;
Victor Stinner8c62be82010-05-06 00:08:46 +00003548 wchar_t *wpath = NULL;
3549 PyObject *oapath;
3550 char *apath;
3551 HANDLE hFile;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003552 time_t atimesec, mtimesec;
3553 long ausec, musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003554 FILETIME atime, mtime;
3555 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003556
Brian Curtin52fbea12011-11-06 13:41:17 -06003557 if (PyArg_ParseTuple(args, "U|O:utime", &obwpath, &arg)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003558 wpath = PyUnicode_AsUnicode(obwpath);
3559 if (wpath == NULL)
3560 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003561 Py_BEGIN_ALLOW_THREADS
3562 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3563 NULL, OPEN_EXISTING,
3564 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3565 Py_END_ALLOW_THREADS
3566 if (hFile == INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003567 return win32_error_object("utime", obwpath);
3568 }
3569 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00003570 /* Drop the argument parsing error as narrow strings
3571 are also valid. */
3572 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003573
Brian Curtin52fbea12011-11-06 13:41:17 -06003574 if (!PyArg_ParseTuple(args, "O&|O:utime",
Victor Stinner8c62be82010-05-06 00:08:46 +00003575 PyUnicode_FSConverter, &oapath, &arg))
3576 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003577
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 apath = PyBytes_AsString(oapath);
3579 Py_BEGIN_ALLOW_THREADS
3580 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3581 NULL, OPEN_EXISTING,
3582 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3583 Py_END_ALLOW_THREADS
3584 if (hFile == INVALID_HANDLE_VALUE) {
3585 win32_error("utime", apath);
3586 Py_DECREF(oapath);
3587 return NULL;
3588 }
3589 Py_DECREF(oapath);
3590 }
3591
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003592 if (arg == Py_None) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 SYSTEMTIME now;
3594 GetSystemTime(&now);
3595 if (!SystemTimeToFileTime(&now, &mtime) ||
3596 !SystemTimeToFileTime(&now, &atime)) {
3597 win32_error("utime", NULL);
3598 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003599 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 }
3601 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3602 PyErr_SetString(PyExc_TypeError,
3603 "utime() arg 2 must be a tuple (atime, mtime)");
3604 goto done;
3605 }
3606 else {
3607 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3608 &atimesec, &ausec) == -1)
3609 goto done;
3610 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3611 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3612 &mtimesec, &musec) == -1)
3613 goto done;
3614 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3615 }
3616 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3617 /* Avoid putting the file name into the error here,
3618 as that may confuse the user into believing that
3619 something is wrong with the file, when it also
3620 could be the time stamp that gives a problem. */
3621 win32_error("utime", NULL);
Antoine Pitroue85da7a2011-01-06 18:25:55 +00003622 goto done;
Victor Stinner8c62be82010-05-06 00:08:46 +00003623 }
3624 Py_INCREF(Py_None);
3625 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003626done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003627 CloseHandle(hFile);
3628 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003629#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003630
Victor Stinner8c62be82010-05-06 00:08:46 +00003631 PyObject *opath;
3632 char *path;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003633 time_t atime, mtime;
3634 long ausec, musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 int res;
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003636 PyObject* arg = Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003637
Brian Curtin52fbea12011-11-06 13:41:17 -06003638 if (!PyArg_ParseTuple(args, "O&|O:utime",
Victor Stinner8c62be82010-05-06 00:08:46 +00003639 PyUnicode_FSConverter, &opath, &arg))
3640 return NULL;
3641 path = PyBytes_AsString(opath);
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003642 if (arg == Py_None) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 /* optional time values not given */
3644 Py_BEGIN_ALLOW_THREADS
3645 res = utime(path, NULL);
3646 Py_END_ALLOW_THREADS
3647 }
3648 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3649 PyErr_SetString(PyExc_TypeError,
3650 "utime() arg 2 must be a tuple (atime, mtime)");
3651 Py_DECREF(opath);
3652 return NULL;
3653 }
3654 else {
3655 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3656 &atime, &ausec) == -1) {
3657 Py_DECREF(opath);
3658 return NULL;
3659 }
3660 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3661 &mtime, &musec) == -1) {
3662 Py_DECREF(opath);
3663 return NULL;
3664 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003665
3666 Py_BEGIN_ALLOW_THREADS
3667 {
3668#ifdef HAVE_UTIMENSAT
3669 struct timespec buf[2];
3670 buf[0].tv_sec = atime;
3671 buf[0].tv_nsec = ausec;
3672 buf[1].tv_sec = mtime;
3673 buf[1].tv_nsec = musec;
3674 res = utimensat(AT_FDCWD, path, buf, 0);
3675#elif defined(HAVE_UTIMES)
3676 struct timeval buf[2];
3677 buf[0].tv_sec = atime;
Victor Stinner8c62be82010-05-06 00:08:46 +00003678 buf[0].tv_usec = ausec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003679 buf[1].tv_sec = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00003680 buf[1].tv_usec = musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003681 res = utimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003682#elif defined(HAVE_UTIME_H)
3683 /* XXX should define struct utimbuf instead, above */
3684 struct utimbuf buf;
3685 buf.actime = atime;
3686 buf.modtime = mtime;
3687 res = utime(path, &buf);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003688#else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003689 time_t buf[2];
3690 buf[0] = atime;
3691 buf[1] = mtime;
3692 res = utime(path, buf);
3693#endif
3694 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 }
3697 if (res < 0) {
3698 return posix_error_with_allocated_filename(opath);
3699 }
3700 Py_DECREF(opath);
3701 Py_INCREF(Py_None);
3702 return Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003703#undef UTIME_EXTRACT
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003704#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003705}
3706
Ross Lagerwall7807c352011-03-17 20:20:30 +02003707#ifdef HAVE_FUTIMES
3708PyDoc_STRVAR(posix_futimes__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003709"futimes(fd[, (atime, mtime)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003710Set the access and modified time of the file specified by the file\n\
Brian Curtinc1b65d12011-11-07 14:18:54 -06003711descriptor fd to the given values. If no second argument is used, set the\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003712access and modified times to the current time.");
3713
3714static PyObject *
3715posix_futimes(PyObject *self, PyObject *args)
3716{
3717 int res, fd;
Brian Curtinc1b65d12011-11-07 14:18:54 -06003718 PyObject* arg = Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003719 time_t atime, mtime;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003720 long ausec, musec;
3721
Brian Curtinc1b65d12011-11-07 14:18:54 -06003722 if (!PyArg_ParseTuple(args, "i|O:futimes", &fd, &arg))
Ross Lagerwall7807c352011-03-17 20:20:30 +02003723 return NULL;
3724
3725 if (arg == Py_None) {
3726 /* optional time values not given */
3727 Py_BEGIN_ALLOW_THREADS
3728 res = futimes(fd, NULL);
3729 Py_END_ALLOW_THREADS
3730 }
3731 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3732 PyErr_SetString(PyExc_TypeError,
3733 "futimes() arg 2 must be a tuple (atime, mtime)");
3734 return NULL;
3735 }
3736 else {
3737 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003738 &atime, &ausec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003739 return NULL;
3740 }
3741 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003742 &mtime, &musec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003743 return NULL;
3744 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003745 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003746 {
3747#ifdef HAVE_FUTIMENS
3748 struct timespec buf[2];
3749 buf[0].tv_sec = atime;
3750 buf[0].tv_nsec = ausec;
3751 buf[1].tv_sec = mtime;
3752 buf[1].tv_nsec = musec;
3753 res = futimens(fd, buf);
3754#else
3755 struct timeval buf[2];
3756 buf[0].tv_sec = atime;
3757 buf[0].tv_usec = ausec;
3758 buf[1].tv_sec = mtime;
3759 buf[1].tv_usec = musec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003760 res = futimes(fd, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003761#endif
3762 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003763 Py_END_ALLOW_THREADS
3764 }
3765 if (res < 0)
3766 return posix_error();
3767 Py_RETURN_NONE;
3768}
3769#endif
3770
3771#ifdef HAVE_LUTIMES
3772PyDoc_STRVAR(posix_lutimes__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003773"lutimes(path[, (atime, mtime)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003774Like utime(), but if path is a symbolic link, it is not dereferenced.");
3775
3776static PyObject *
3777posix_lutimes(PyObject *self, PyObject *args)
3778{
Brian Curtinc1b65d12011-11-07 14:18:54 -06003779 PyObject *opath;
3780 PyObject *arg = Py_None;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003781 const char *path;
3782 int res;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003783 time_t atime, mtime;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003784 long ausec, musec;
3785
Brian Curtinc1b65d12011-11-07 14:18:54 -06003786 if (!PyArg_ParseTuple(args, "O&|O:lutimes",
Ross Lagerwall7807c352011-03-17 20:20:30 +02003787 PyUnicode_FSConverter, &opath, &arg))
3788 return NULL;
3789 path = PyBytes_AsString(opath);
3790 if (arg == Py_None) {
3791 /* optional time values not given */
3792 Py_BEGIN_ALLOW_THREADS
3793 res = lutimes(path, NULL);
3794 Py_END_ALLOW_THREADS
3795 }
3796 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3797 PyErr_SetString(PyExc_TypeError,
3798 "lutimes() arg 2 must be a tuple (atime, mtime)");
3799 Py_DECREF(opath);
3800 return NULL;
3801 }
3802 else {
3803 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003804 &atime, &ausec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003805 Py_DECREF(opath);
3806 return NULL;
3807 }
3808 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003809 &mtime, &musec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003810 Py_DECREF(opath);
3811 return NULL;
3812 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003813 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003814 {
3815#ifdef HAVE_UTIMENSAT
3816 struct timespec buf[2];
3817 buf[0].tv_sec = atime;
3818 buf[0].tv_nsec = ausec;
3819 buf[1].tv_sec = mtime;
3820 buf[1].tv_nsec = musec;
3821 res = utimensat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
3822#else
3823 struct timeval buf[2];
3824 buf[0].tv_sec = atime;
3825 buf[0].tv_usec = ausec;
3826 buf[1].tv_sec = mtime;
3827 buf[1].tv_usec = musec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003828 res = lutimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003829#endif
3830 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003831 Py_END_ALLOW_THREADS
3832 }
3833 Py_DECREF(opath);
3834 if (res < 0)
3835 return posix_error();
3836 Py_RETURN_NONE;
3837}
3838#endif
3839
3840#ifdef HAVE_FUTIMENS
3841PyDoc_STRVAR(posix_futimens__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003842"futimens(fd[, (atime_sec, atime_nsec), (mtime_sec, mtime_nsec)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003843Updates the timestamps of a file specified by the file descriptor fd, with\n\
3844nanosecond precision.\n\
Brian Curtinc1b65d12011-11-07 14:18:54 -06003845If no second argument is given, set atime and mtime to the current time.\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003846If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
3847current time.\n\
3848If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
3849
3850static PyObject *
3851posix_futimens(PyObject *self, PyObject *args)
3852{
3853 int res, fd;
Brian Curtinc1b65d12011-11-07 14:18:54 -06003854 PyObject *atime = Py_None;
3855 PyObject *mtime = Py_None;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003856 struct timespec buf[2];
3857
Brian Curtinc1b65d12011-11-07 14:18:54 -06003858 if (!PyArg_ParseTuple(args, "i|OO:futimens",
Ross Lagerwall7807c352011-03-17 20:20:30 +02003859 &fd, &atime, &mtime))
3860 return NULL;
3861 if (atime == Py_None && mtime == Py_None) {
3862 /* optional time values not given */
3863 Py_BEGIN_ALLOW_THREADS
3864 res = futimens(fd, NULL);
3865 Py_END_ALLOW_THREADS
3866 }
3867 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
3868 PyErr_SetString(PyExc_TypeError,
3869 "futimens() arg 2 must be a tuple (atime_sec, atime_nsec)");
3870 return NULL;
3871 }
3872 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
3873 PyErr_SetString(PyExc_TypeError,
3874 "futimens() arg 3 must be a tuple (mtime_sec, mtime_nsec)");
3875 return NULL;
3876 }
3877 else {
3878 if (!PyArg_ParseTuple(atime, "ll:futimens",
3879 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
3880 return NULL;
3881 }
3882 if (!PyArg_ParseTuple(mtime, "ll:futimens",
3883 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
3884 return NULL;
3885 }
3886 Py_BEGIN_ALLOW_THREADS
3887 res = futimens(fd, buf);
3888 Py_END_ALLOW_THREADS
3889 }
3890 if (res < 0)
3891 return posix_error();
3892 Py_RETURN_NONE;
3893}
3894#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003895
Guido van Rossum3b066191991-06-04 19:40:25 +00003896/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003897
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003898PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003899"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003900Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003901
Barry Warsaw53699e91996-12-10 23:23:01 +00003902static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003903posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003904{
Victor Stinner8c62be82010-05-06 00:08:46 +00003905 int sts;
3906 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3907 return NULL;
3908 _exit(sts);
3909 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003910}
3911
Martin v. Löwis114619e2002-10-07 06:44:21 +00003912#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3913static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003914free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003915{
Victor Stinner8c62be82010-05-06 00:08:46 +00003916 Py_ssize_t i;
3917 for (i = 0; i < count; i++)
3918 PyMem_Free(array[i]);
3919 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003920}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003921
Antoine Pitrou69f71142009-05-24 21:25:49 +00003922static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003923int fsconvert_strdup(PyObject *o, char**out)
3924{
Victor Stinner8c62be82010-05-06 00:08:46 +00003925 PyObject *bytes;
3926 Py_ssize_t size;
3927 if (!PyUnicode_FSConverter(o, &bytes))
3928 return 0;
3929 size = PyBytes_GET_SIZE(bytes);
3930 *out = PyMem_Malloc(size+1);
3931 if (!*out)
3932 return 0;
3933 memcpy(*out, PyBytes_AsString(bytes), size+1);
3934 Py_DECREF(bytes);
3935 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003936}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003937#endif
3938
Ross Lagerwall7807c352011-03-17 20:20:30 +02003939#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00003940static char**
3941parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3942{
Victor Stinner8c62be82010-05-06 00:08:46 +00003943 char **envlist;
3944 Py_ssize_t i, pos, envc;
3945 PyObject *keys=NULL, *vals=NULL;
3946 PyObject *key, *val, *key2, *val2;
3947 char *p, *k, *v;
3948 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003949
Victor Stinner8c62be82010-05-06 00:08:46 +00003950 i = PyMapping_Size(env);
3951 if (i < 0)
3952 return NULL;
3953 envlist = PyMem_NEW(char *, i + 1);
3954 if (envlist == NULL) {
3955 PyErr_NoMemory();
3956 return NULL;
3957 }
3958 envc = 0;
3959 keys = PyMapping_Keys(env);
3960 vals = PyMapping_Values(env);
3961 if (!keys || !vals)
3962 goto error;
3963 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3964 PyErr_Format(PyExc_TypeError,
3965 "env.keys() or env.values() is not a list");
3966 goto error;
3967 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003968
Victor Stinner8c62be82010-05-06 00:08:46 +00003969 for (pos = 0; pos < i; pos++) {
3970 key = PyList_GetItem(keys, pos);
3971 val = PyList_GetItem(vals, pos);
3972 if (!key || !val)
3973 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003974
Victor Stinner8c62be82010-05-06 00:08:46 +00003975 if (PyUnicode_FSConverter(key, &key2) == 0)
3976 goto error;
3977 if (PyUnicode_FSConverter(val, &val2) == 0) {
3978 Py_DECREF(key2);
3979 goto error;
3980 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003981
3982#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003983 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3984 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003985#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003986 k = PyBytes_AsString(key2);
3987 v = PyBytes_AsString(val2);
3988 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003989
Victor Stinner8c62be82010-05-06 00:08:46 +00003990 p = PyMem_NEW(char, len);
3991 if (p == NULL) {
3992 PyErr_NoMemory();
3993 Py_DECREF(key2);
3994 Py_DECREF(val2);
3995 goto error;
3996 }
3997 PyOS_snprintf(p, len, "%s=%s", k, v);
3998 envlist[envc++] = p;
3999 Py_DECREF(key2);
4000 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004001#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004002 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004003#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004004 }
4005 Py_DECREF(vals);
4006 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004007
Victor Stinner8c62be82010-05-06 00:08:46 +00004008 envlist[envc] = 0;
4009 *envc_ptr = envc;
4010 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004011
4012error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004013 Py_XDECREF(keys);
4014 Py_XDECREF(vals);
4015 while (--envc >= 0)
4016 PyMem_DEL(envlist[envc]);
4017 PyMem_DEL(envlist);
4018 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004019}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004020
Ross Lagerwall7807c352011-03-17 20:20:30 +02004021static char**
4022parse_arglist(PyObject* argv, Py_ssize_t *argc)
4023{
4024 int i;
4025 char **argvlist = PyMem_NEW(char *, *argc+1);
4026 if (argvlist == NULL) {
4027 PyErr_NoMemory();
4028 return NULL;
4029 }
4030 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004031 PyObject* item = PySequence_ITEM(argv, i);
4032 if (item == NULL)
4033 goto fail;
4034 if (!fsconvert_strdup(item, &argvlist[i])) {
4035 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004036 goto fail;
4037 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004038 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004039 }
4040 argvlist[*argc] = NULL;
4041 return argvlist;
4042fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004043 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004044 free_string_array(argvlist, *argc);
4045 return NULL;
4046}
4047#endif
4048
4049#ifdef HAVE_EXECV
4050PyDoc_STRVAR(posix_execv__doc__,
4051"execv(path, args)\n\n\
4052Execute an executable path with arguments, replacing current process.\n\
4053\n\
4054 path: path of executable file\n\
4055 args: tuple or list of strings");
4056
4057static PyObject *
4058posix_execv(PyObject *self, PyObject *args)
4059{
4060 PyObject *opath;
4061 char *path;
4062 PyObject *argv;
4063 char **argvlist;
4064 Py_ssize_t argc;
4065
4066 /* execv has two arguments: (path, argv), where
4067 argv is a list or tuple of strings. */
4068
4069 if (!PyArg_ParseTuple(args, "O&O:execv",
4070 PyUnicode_FSConverter,
4071 &opath, &argv))
4072 return NULL;
4073 path = PyBytes_AsString(opath);
4074 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4075 PyErr_SetString(PyExc_TypeError,
4076 "execv() arg 2 must be a tuple or list");
4077 Py_DECREF(opath);
4078 return NULL;
4079 }
4080 argc = PySequence_Size(argv);
4081 if (argc < 1) {
4082 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4083 Py_DECREF(opath);
4084 return NULL;
4085 }
4086
4087 argvlist = parse_arglist(argv, &argc);
4088 if (argvlist == NULL) {
4089 Py_DECREF(opath);
4090 return NULL;
4091 }
4092
4093 execv(path, argvlist);
4094
4095 /* If we get here it's definitely an error */
4096
4097 free_string_array(argvlist, argc);
4098 Py_DECREF(opath);
4099 return posix_error();
4100}
4101
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004102PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004103"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004104Execute a path with arguments and environment, replacing current process.\n\
4105\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004106 path: path of executable file\n\
4107 args: tuple or list of arguments\n\
4108 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004109
Barry Warsaw53699e91996-12-10 23:23:01 +00004110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004111posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004112{
Victor Stinner8c62be82010-05-06 00:08:46 +00004113 PyObject *opath;
4114 char *path;
4115 PyObject *argv, *env;
4116 char **argvlist;
4117 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004118 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004119
Victor Stinner8c62be82010-05-06 00:08:46 +00004120 /* execve has three arguments: (path, argv, env), where
4121 argv is a list or tuple of strings and env is a dictionary
4122 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004123
Victor Stinner8c62be82010-05-06 00:08:46 +00004124 if (!PyArg_ParseTuple(args, "O&OO:execve",
4125 PyUnicode_FSConverter,
4126 &opath, &argv, &env))
4127 return NULL;
4128 path = PyBytes_AsString(opath);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004129 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004130 PyErr_SetString(PyExc_TypeError,
4131 "execve() arg 2 must be a tuple or list");
4132 goto fail_0;
4133 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004134 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004135 if (!PyMapping_Check(env)) {
4136 PyErr_SetString(PyExc_TypeError,
4137 "execve() arg 3 must be a mapping object");
4138 goto fail_0;
4139 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004140
Ross Lagerwall7807c352011-03-17 20:20:30 +02004141 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004142 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004143 goto fail_0;
4144 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004145
Victor Stinner8c62be82010-05-06 00:08:46 +00004146 envlist = parse_envlist(env, &envc);
4147 if (envlist == NULL)
4148 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004149
Victor Stinner8c62be82010-05-06 00:08:46 +00004150 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00004151
Victor Stinner8c62be82010-05-06 00:08:46 +00004152 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004153
Victor Stinner8c62be82010-05-06 00:08:46 +00004154 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004155
Victor Stinner8c62be82010-05-06 00:08:46 +00004156 while (--envc >= 0)
4157 PyMem_DEL(envlist[envc]);
4158 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004159 fail_1:
Ross Lagerwall7807c352011-03-17 20:20:30 +02004160 free_string_array(argvlist, argc);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004161 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004162 Py_DECREF(opath);
4163 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004164}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004165#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004166
Ross Lagerwall7807c352011-03-17 20:20:30 +02004167#ifdef HAVE_FEXECVE
4168PyDoc_STRVAR(posix_fexecve__doc__,
4169"fexecve(fd, args, env)\n\n\
4170Execute the program specified by a file descriptor with arguments and\n\
4171environment, replacing the current process.\n\
4172\n\
4173 fd: file descriptor of executable\n\
4174 args: tuple or list of arguments\n\
4175 env: dictionary of strings mapping to strings");
4176
4177static PyObject *
4178posix_fexecve(PyObject *self, PyObject *args)
4179{
4180 int fd;
4181 PyObject *argv, *env;
4182 char **argvlist;
4183 char **envlist;
4184 Py_ssize_t argc, envc;
4185
4186 if (!PyArg_ParseTuple(args, "iOO:fexecve",
4187 &fd, &argv, &env))
4188 return NULL;
4189 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4190 PyErr_SetString(PyExc_TypeError,
4191 "fexecve() arg 2 must be a tuple or list");
4192 return NULL;
4193 }
4194 argc = PySequence_Size(argv);
4195 if (!PyMapping_Check(env)) {
4196 PyErr_SetString(PyExc_TypeError,
4197 "fexecve() arg 3 must be a mapping object");
4198 return NULL;
4199 }
4200
4201 argvlist = parse_arglist(argv, &argc);
4202 if (argvlist == NULL)
4203 return NULL;
4204
4205 envlist = parse_envlist(env, &envc);
4206 if (envlist == NULL)
4207 goto fail;
4208
4209 fexecve(fd, argvlist, envlist);
4210
4211 /* If we get here it's definitely an error */
4212
4213 (void) posix_error();
4214
4215 while (--envc >= 0)
4216 PyMem_DEL(envlist[envc]);
4217 PyMem_DEL(envlist);
4218 fail:
4219 free_string_array(argvlist, argc);
4220 return NULL;
4221}
4222#endif /* HAVE_FEXECVE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004223
Guido van Rossuma1065681999-01-25 23:20:23 +00004224#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004225PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004226"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004227Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004228\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004229 mode: mode of process creation\n\
4230 path: path of executable file\n\
4231 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004232
4233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004234posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004235{
Victor Stinner8c62be82010-05-06 00:08:46 +00004236 PyObject *opath;
4237 char *path;
4238 PyObject *argv;
4239 char **argvlist;
4240 int mode, i;
4241 Py_ssize_t argc;
4242 Py_intptr_t spawnval;
4243 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004244
Victor Stinner8c62be82010-05-06 00:08:46 +00004245 /* spawnv has three arguments: (mode, path, argv), where
4246 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004247
Victor Stinner8c62be82010-05-06 00:08:46 +00004248 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4249 PyUnicode_FSConverter,
4250 &opath, &argv))
4251 return NULL;
4252 path = PyBytes_AsString(opath);
4253 if (PyList_Check(argv)) {
4254 argc = PyList_Size(argv);
4255 getitem = PyList_GetItem;
4256 }
4257 else if (PyTuple_Check(argv)) {
4258 argc = PyTuple_Size(argv);
4259 getitem = PyTuple_GetItem;
4260 }
4261 else {
4262 PyErr_SetString(PyExc_TypeError,
4263 "spawnv() arg 2 must be a tuple or list");
4264 Py_DECREF(opath);
4265 return NULL;
4266 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004267
Victor Stinner8c62be82010-05-06 00:08:46 +00004268 argvlist = PyMem_NEW(char *, argc+1);
4269 if (argvlist == NULL) {
4270 Py_DECREF(opath);
4271 return PyErr_NoMemory();
4272 }
4273 for (i = 0; i < argc; i++) {
4274 if (!fsconvert_strdup((*getitem)(argv, i),
4275 &argvlist[i])) {
4276 free_string_array(argvlist, i);
4277 PyErr_SetString(
4278 PyExc_TypeError,
4279 "spawnv() arg 2 must contain only strings");
4280 Py_DECREF(opath);
4281 return NULL;
4282 }
4283 }
4284 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004285
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004286#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004287 Py_BEGIN_ALLOW_THREADS
4288 spawnval = spawnv(mode, path, argvlist);
4289 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004290#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004291 if (mode == _OLD_P_OVERLAY)
4292 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004293
Victor Stinner8c62be82010-05-06 00:08:46 +00004294 Py_BEGIN_ALLOW_THREADS
4295 spawnval = _spawnv(mode, path, argvlist);
4296 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004297#endif
Tim Peters5aa91602002-01-30 05:46:57 +00004298
Victor Stinner8c62be82010-05-06 00:08:46 +00004299 free_string_array(argvlist, argc);
4300 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004301
Victor Stinner8c62be82010-05-06 00:08:46 +00004302 if (spawnval == -1)
4303 return posix_error();
4304 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004305#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004306 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004307#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004308 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004309#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004310}
4311
4312
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004313PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004314"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004315Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004316\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004317 mode: mode of process creation\n\
4318 path: path of executable file\n\
4319 args: tuple or list of arguments\n\
4320 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004321
4322static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004323posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004324{
Victor Stinner8c62be82010-05-06 00:08:46 +00004325 PyObject *opath;
4326 char *path;
4327 PyObject *argv, *env;
4328 char **argvlist;
4329 char **envlist;
4330 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004331 int mode;
4332 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004333 Py_intptr_t spawnval;
4334 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4335 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004336
Victor Stinner8c62be82010-05-06 00:08:46 +00004337 /* spawnve has four arguments: (mode, path, argv, env), where
4338 argv is a list or tuple of strings and env is a dictionary
4339 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004340
Victor Stinner8c62be82010-05-06 00:08:46 +00004341 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4342 PyUnicode_FSConverter,
4343 &opath, &argv, &env))
4344 return NULL;
4345 path = PyBytes_AsString(opath);
4346 if (PyList_Check(argv)) {
4347 argc = PyList_Size(argv);
4348 getitem = PyList_GetItem;
4349 }
4350 else if (PyTuple_Check(argv)) {
4351 argc = PyTuple_Size(argv);
4352 getitem = PyTuple_GetItem;
4353 }
4354 else {
4355 PyErr_SetString(PyExc_TypeError,
4356 "spawnve() arg 2 must be a tuple or list");
4357 goto fail_0;
4358 }
4359 if (!PyMapping_Check(env)) {
4360 PyErr_SetString(PyExc_TypeError,
4361 "spawnve() arg 3 must be a mapping object");
4362 goto fail_0;
4363 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004364
Victor Stinner8c62be82010-05-06 00:08:46 +00004365 argvlist = PyMem_NEW(char *, argc+1);
4366 if (argvlist == NULL) {
4367 PyErr_NoMemory();
4368 goto fail_0;
4369 }
4370 for (i = 0; i < argc; i++) {
4371 if (!fsconvert_strdup((*getitem)(argv, i),
4372 &argvlist[i]))
4373 {
4374 lastarg = i;
4375 goto fail_1;
4376 }
4377 }
4378 lastarg = argc;
4379 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004380
Victor Stinner8c62be82010-05-06 00:08:46 +00004381 envlist = parse_envlist(env, &envc);
4382 if (envlist == NULL)
4383 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004384
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004385#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004386 Py_BEGIN_ALLOW_THREADS
4387 spawnval = spawnve(mode, path, argvlist, envlist);
4388 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004389#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004390 if (mode == _OLD_P_OVERLAY)
4391 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00004392
Victor Stinner8c62be82010-05-06 00:08:46 +00004393 Py_BEGIN_ALLOW_THREADS
4394 spawnval = _spawnve(mode, path, argvlist, envlist);
4395 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004396#endif
Tim Peters25059d32001-12-07 20:35:43 +00004397
Victor Stinner8c62be82010-05-06 00:08:46 +00004398 if (spawnval == -1)
4399 (void) posix_error();
4400 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004401#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004402 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004403#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004404 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004405#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004406
Victor Stinner8c62be82010-05-06 00:08:46 +00004407 while (--envc >= 0)
4408 PyMem_DEL(envlist[envc]);
4409 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004410 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004411 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004412 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004413 Py_DECREF(opath);
4414 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00004415}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004416
4417/* OS/2 supports spawnvp & spawnvpe natively */
4418#if defined(PYOS_OS2)
4419PyDoc_STRVAR(posix_spawnvp__doc__,
4420"spawnvp(mode, file, args)\n\n\
4421Execute the program 'file' in a new process, using the environment\n\
4422search path to find the file.\n\
4423\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004424 mode: mode of process creation\n\
4425 file: executable file name\n\
4426 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004427
4428static PyObject *
4429posix_spawnvp(PyObject *self, PyObject *args)
4430{
Victor Stinner8c62be82010-05-06 00:08:46 +00004431 PyObject *opath;
4432 char *path;
4433 PyObject *argv;
4434 char **argvlist;
4435 int mode, i, argc;
4436 Py_intptr_t spawnval;
4437 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004438
Victor Stinner8c62be82010-05-06 00:08:46 +00004439 /* spawnvp has three arguments: (mode, path, argv), where
4440 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004441
Victor Stinner8c62be82010-05-06 00:08:46 +00004442 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
4443 PyUnicode_FSConverter,
4444 &opath, &argv))
4445 return NULL;
4446 path = PyBytes_AsString(opath);
4447 if (PyList_Check(argv)) {
4448 argc = PyList_Size(argv);
4449 getitem = PyList_GetItem;
4450 }
4451 else if (PyTuple_Check(argv)) {
4452 argc = PyTuple_Size(argv);
4453 getitem = PyTuple_GetItem;
4454 }
4455 else {
4456 PyErr_SetString(PyExc_TypeError,
4457 "spawnvp() arg 2 must be a tuple or list");
4458 Py_DECREF(opath);
4459 return NULL;
4460 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004461
Victor Stinner8c62be82010-05-06 00:08:46 +00004462 argvlist = PyMem_NEW(char *, argc+1);
4463 if (argvlist == NULL) {
4464 Py_DECREF(opath);
4465 return PyErr_NoMemory();
4466 }
4467 for (i = 0; i < argc; i++) {
4468 if (!fsconvert_strdup((*getitem)(argv, i),
4469 &argvlist[i])) {
4470 free_string_array(argvlist, i);
4471 PyErr_SetString(
4472 PyExc_TypeError,
4473 "spawnvp() arg 2 must contain only strings");
4474 Py_DECREF(opath);
4475 return NULL;
4476 }
4477 }
4478 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004479
Victor Stinner8c62be82010-05-06 00:08:46 +00004480 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004481#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004482 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004483#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004484 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004485#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004486 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004487
Victor Stinner8c62be82010-05-06 00:08:46 +00004488 free_string_array(argvlist, argc);
4489 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004490
Victor Stinner8c62be82010-05-06 00:08:46 +00004491 if (spawnval == -1)
4492 return posix_error();
4493 else
4494 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004495}
4496
4497
4498PyDoc_STRVAR(posix_spawnvpe__doc__,
4499"spawnvpe(mode, file, args, env)\n\n\
4500Execute the program 'file' in a new process, using the environment\n\
4501search path to find the file.\n\
4502\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004503 mode: mode of process creation\n\
4504 file: executable file name\n\
4505 args: tuple or list of arguments\n\
4506 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004507
4508static PyObject *
4509posix_spawnvpe(PyObject *self, PyObject *args)
4510{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02004511 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00004512 char *path;
4513 PyObject *argv, *env;
4514 char **argvlist;
4515 char **envlist;
4516 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004517 int mode;
4518 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004519 Py_intptr_t spawnval;
4520 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4521 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004522
Victor Stinner8c62be82010-05-06 00:08:46 +00004523 /* spawnvpe has four arguments: (mode, path, argv, env), where
4524 argv is a list or tuple of strings and env is a dictionary
4525 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004526
Victor Stinner8c62be82010-05-06 00:08:46 +00004527 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
4528 PyUnicode_FSConverter,
4529 &opath, &argv, &env))
4530 return NULL;
4531 path = PyBytes_AsString(opath);
4532 if (PyList_Check(argv)) {
4533 argc = PyList_Size(argv);
4534 getitem = PyList_GetItem;
4535 }
4536 else if (PyTuple_Check(argv)) {
4537 argc = PyTuple_Size(argv);
4538 getitem = PyTuple_GetItem;
4539 }
4540 else {
4541 PyErr_SetString(PyExc_TypeError,
4542 "spawnvpe() arg 2 must be a tuple or list");
4543 goto fail_0;
4544 }
4545 if (!PyMapping_Check(env)) {
4546 PyErr_SetString(PyExc_TypeError,
4547 "spawnvpe() arg 3 must be a mapping object");
4548 goto fail_0;
4549 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004550
Victor Stinner8c62be82010-05-06 00:08:46 +00004551 argvlist = PyMem_NEW(char *, argc+1);
4552 if (argvlist == NULL) {
4553 PyErr_NoMemory();
4554 goto fail_0;
4555 }
4556 for (i = 0; i < argc; i++) {
4557 if (!fsconvert_strdup((*getitem)(argv, i),
4558 &argvlist[i]))
4559 {
4560 lastarg = i;
4561 goto fail_1;
4562 }
4563 }
4564 lastarg = argc;
4565 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004566
Victor Stinner8c62be82010-05-06 00:08:46 +00004567 envlist = parse_envlist(env, &envc);
4568 if (envlist == NULL)
4569 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004570
Victor Stinner8c62be82010-05-06 00:08:46 +00004571 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004572#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004573 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004574#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004575 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004576#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004577 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004578
Victor Stinner8c62be82010-05-06 00:08:46 +00004579 if (spawnval == -1)
4580 (void) posix_error();
4581 else
4582 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004583
Victor Stinner8c62be82010-05-06 00:08:46 +00004584 while (--envc >= 0)
4585 PyMem_DEL(envlist[envc]);
4586 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004587 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004588 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004589 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004590 Py_DECREF(opath);
4591 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004592}
4593#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00004594#endif /* HAVE_SPAWNV */
4595
4596
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004597#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004598PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004599"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004600Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4601\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004602Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004603
4604static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004605posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004606{
Victor Stinner8c62be82010-05-06 00:08:46 +00004607 pid_t pid;
4608 int result = 0;
4609 _PyImport_AcquireLock();
4610 pid = fork1();
4611 if (pid == 0) {
4612 /* child: this clobbers and resets the import lock. */
4613 PyOS_AfterFork();
4614 } else {
4615 /* parent: release the import lock. */
4616 result = _PyImport_ReleaseLock();
4617 }
4618 if (pid == -1)
4619 return posix_error();
4620 if (result < 0) {
4621 /* Don't clobber the OSError if the fork failed. */
4622 PyErr_SetString(PyExc_RuntimeError,
4623 "not holding the import lock");
4624 return NULL;
4625 }
4626 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004627}
4628#endif
4629
4630
Guido van Rossumad0ee831995-03-01 10:34:45 +00004631#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004632PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004633"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004634Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004635Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004636
Barry Warsaw53699e91996-12-10 23:23:01 +00004637static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004638posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004639{
Victor Stinner8c62be82010-05-06 00:08:46 +00004640 pid_t pid;
4641 int result = 0;
4642 _PyImport_AcquireLock();
4643 pid = fork();
4644 if (pid == 0) {
4645 /* child: this clobbers and resets the import lock. */
4646 PyOS_AfterFork();
4647 } else {
4648 /* parent: release the import lock. */
4649 result = _PyImport_ReleaseLock();
4650 }
4651 if (pid == -1)
4652 return posix_error();
4653 if (result < 0) {
4654 /* Don't clobber the OSError if the fork failed. */
4655 PyErr_SetString(PyExc_RuntimeError,
4656 "not holding the import lock");
4657 return NULL;
4658 }
4659 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004660}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004661#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004662
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004663#ifdef HAVE_SCHED_H
4664
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004665#ifdef HAVE_SCHED_GET_PRIORITY_MAX
4666
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004667PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
4668"sched_get_priority_max(policy)\n\n\
4669Get the maximum scheduling priority for *policy*.");
4670
4671static PyObject *
4672posix_sched_get_priority_max(PyObject *self, PyObject *args)
4673{
4674 int policy, max;
4675
4676 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
4677 return NULL;
4678 max = sched_get_priority_max(policy);
4679 if (max < 0)
4680 return posix_error();
4681 return PyLong_FromLong(max);
4682}
4683
4684PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
4685"sched_get_priority_min(policy)\n\n\
4686Get the minimum scheduling priority for *policy*.");
4687
4688static PyObject *
4689posix_sched_get_priority_min(PyObject *self, PyObject *args)
4690{
4691 int policy, min;
4692
4693 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
4694 return NULL;
4695 min = sched_get_priority_min(policy);
4696 if (min < 0)
4697 return posix_error();
4698 return PyLong_FromLong(min);
4699}
4700
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004701#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
4702
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004703#ifdef HAVE_SCHED_SETSCHEDULER
4704
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004705PyDoc_STRVAR(posix_sched_getscheduler__doc__,
4706"sched_getscheduler(pid)\n\n\
4707Get the scheduling policy for the process with a PID of *pid*.\n\
4708Passing a PID of 0 returns the scheduling policy for the calling process.");
4709
4710static PyObject *
4711posix_sched_getscheduler(PyObject *self, PyObject *args)
4712{
4713 pid_t pid;
4714 int policy;
4715
4716 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
4717 return NULL;
4718 policy = sched_getscheduler(pid);
4719 if (policy < 0)
4720 return posix_error();
4721 return PyLong_FromLong(policy);
4722}
4723
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004724#endif
4725
4726#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
4727
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004728static PyObject *
4729sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4730{
4731 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05004732 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004733
4734 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
4735 return NULL;
4736 res = PyStructSequence_New(type);
4737 if (!res)
4738 return NULL;
4739 Py_INCREF(priority);
4740 PyStructSequence_SET_ITEM(res, 0, priority);
4741 return res;
4742}
4743
4744PyDoc_STRVAR(sched_param__doc__,
4745"sched_param(sched_priority): A scheduling parameter.\n\n\
4746Current has only one field: sched_priority");
4747
4748static PyStructSequence_Field sched_param_fields[] = {
4749 {"sched_priority", "the scheduling priority"},
4750 {0}
4751};
4752
4753static PyStructSequence_Desc sched_param_desc = {
4754 "sched_param", /* name */
4755 sched_param__doc__, /* doc */
4756 sched_param_fields,
4757 1
4758};
4759
4760static int
4761convert_sched_param(PyObject *param, struct sched_param *res)
4762{
4763 long priority;
4764
4765 if (Py_TYPE(param) != &SchedParamType) {
4766 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
4767 return 0;
4768 }
4769 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
4770 if (priority == -1 && PyErr_Occurred())
4771 return 0;
4772 if (priority > INT_MAX || priority < INT_MIN) {
4773 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
4774 return 0;
4775 }
4776 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
4777 return 1;
4778}
4779
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004780#endif
4781
4782#ifdef HAVE_SCHED_SETSCHEDULER
4783
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004784PyDoc_STRVAR(posix_sched_setscheduler__doc__,
4785"sched_setscheduler(pid, policy, param)\n\n\
4786Set the scheduling policy, *policy*, for *pid*.\n\
4787If *pid* is 0, the calling process is changed.\n\
4788*param* is an instance of sched_param.");
4789
4790static PyObject *
4791posix_sched_setscheduler(PyObject *self, PyObject *args)
4792{
4793 pid_t pid;
4794 int policy;
4795 struct sched_param param;
4796
4797 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
4798 &pid, &policy, &convert_sched_param, &param))
4799 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02004800
4801 /*
Jesus Cea54b01492011-09-10 01:53:19 +02004802 ** sched_setscheduler() returns 0 in Linux, but the previous
4803 ** scheduling policy under Solaris/Illumos, and others.
4804 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02004805 */
4806 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004807 return posix_error();
4808 Py_RETURN_NONE;
4809}
4810
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004811#endif
4812
4813#ifdef HAVE_SCHED_SETPARAM
4814
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004815PyDoc_STRVAR(posix_sched_getparam__doc__,
4816"sched_getparam(pid) -> sched_param\n\n\
4817Returns scheduling parameters for the process with *pid* as an instance of the\n\
4818sched_param class. A PID of 0 means the calling process.");
4819
4820static PyObject *
4821posix_sched_getparam(PyObject *self, PyObject *args)
4822{
4823 pid_t pid;
4824 struct sched_param param;
4825 PyObject *res, *priority;
4826
4827 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
4828 return NULL;
4829 if (sched_getparam(pid, &param))
4830 return posix_error();
4831 res = PyStructSequence_New(&SchedParamType);
4832 if (!res)
4833 return NULL;
4834 priority = PyLong_FromLong(param.sched_priority);
4835 if (!priority) {
4836 Py_DECREF(res);
4837 return NULL;
4838 }
4839 PyStructSequence_SET_ITEM(res, 0, priority);
4840 return res;
4841}
4842
4843PyDoc_STRVAR(posix_sched_setparam__doc__,
4844"sched_setparam(pid, param)\n\n\
4845Set scheduling parameters for a process with PID *pid*.\n\
4846A PID of 0 means the calling process.");
4847
4848static PyObject *
4849posix_sched_setparam(PyObject *self, PyObject *args)
4850{
4851 pid_t pid;
4852 struct sched_param param;
4853
4854 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
4855 &pid, &convert_sched_param, &param))
4856 return NULL;
4857 if (sched_setparam(pid, &param))
4858 return posix_error();
4859 Py_RETURN_NONE;
4860}
4861
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004862#endif
4863
4864#ifdef HAVE_SCHED_RR_GET_INTERVAL
4865
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004866PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
4867"sched_rr_get_interval(pid) -> float\n\n\
4868Return the round-robin quantum for the process with PID *pid* in seconds.");
4869
4870static PyObject *
4871posix_sched_rr_get_interval(PyObject *self, PyObject *args)
4872{
4873 pid_t pid;
4874 struct timespec interval;
4875
4876 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
4877 return NULL;
4878 if (sched_rr_get_interval(pid, &interval))
4879 return posix_error();
4880 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
4881}
4882
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004883#endif
4884
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004885PyDoc_STRVAR(posix_sched_yield__doc__,
4886"sched_yield()\n\n\
4887Voluntarily relinquish the CPU.");
4888
4889static PyObject *
4890posix_sched_yield(PyObject *self, PyObject *noargs)
4891{
4892 if (sched_yield())
4893 return posix_error();
4894 Py_RETURN_NONE;
4895}
4896
Benjamin Peterson2740af82011-08-02 17:41:34 -05004897#ifdef HAVE_SCHED_SETAFFINITY
4898
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004899typedef struct {
4900 PyObject_HEAD;
4901 Py_ssize_t size;
4902 int ncpus;
4903 cpu_set_t *set;
4904} Py_cpu_set;
4905
4906static PyTypeObject cpu_set_type;
4907
4908static void
4909cpu_set_dealloc(Py_cpu_set *set)
4910{
4911 assert(set->set);
4912 CPU_FREE(set->set);
4913 Py_TYPE(set)->tp_free(set);
4914}
4915
4916static Py_cpu_set *
4917make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
4918{
4919 Py_cpu_set *set;
4920
4921 if (size < 0) {
4922 PyErr_SetString(PyExc_ValueError, "negative size");
4923 return NULL;
4924 }
4925 set = (Py_cpu_set *)type->tp_alloc(type, 0);
4926 if (!set)
4927 return NULL;
4928 set->ncpus = size;
4929 set->size = CPU_ALLOC_SIZE(size);
4930 set->set = CPU_ALLOC(size);
4931 if (!set->set) {
4932 type->tp_free(set);
4933 PyErr_NoMemory();
4934 return NULL;
4935 }
4936 CPU_ZERO_S(set->size, set->set);
4937 return set;
4938}
4939
4940static PyObject *
4941cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4942{
4943 int size;
4944
4945 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
4946 !PyArg_ParseTuple(args, "i:cpu_set", &size))
4947 return NULL;
4948 return (PyObject *)make_new_cpu_set(type, size);
4949}
4950
4951static PyObject *
4952cpu_set_repr(Py_cpu_set *set)
4953{
4954 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02004955}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004956
4957static Py_ssize_t
4958cpu_set_len(Py_cpu_set *set)
4959{
4960 return set->ncpus;
4961}
4962
4963static int
4964_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
4965{
4966 int cpu;
4967 if (!PyArg_ParseTuple(args, requester, &cpu))
4968 return -1;
4969 if (cpu < 0) {
4970 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
4971 return -1;
4972 }
4973 if (cpu >= set->ncpus) {
4974 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
4975 return -1;
4976 }
4977 return cpu;
4978}
4979
4980PyDoc_STRVAR(cpu_set_set_doc,
4981"cpu_set.set(i)\n\n\
4982Add CPU *i* to the set.");
4983
4984static PyObject *
4985cpu_set_set(Py_cpu_set *set, PyObject *args)
4986{
4987 int cpu = _get_cpu(set, "i|set", args);
4988 if (cpu == -1)
4989 return NULL;
4990 CPU_SET_S(cpu, set->size, set->set);
4991 Py_RETURN_NONE;
4992}
4993
4994PyDoc_STRVAR(cpu_set_count_doc,
4995"cpu_set.count() -> int\n\n\
4996Return the number of CPUs active in the set.");
4997
4998static PyObject *
4999cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5000{
5001 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5002}
5003
5004PyDoc_STRVAR(cpu_set_clear_doc,
5005"cpu_set.clear(i)\n\n\
5006Remove CPU *i* from the set.");
5007
5008static PyObject *
5009cpu_set_clear(Py_cpu_set *set, PyObject *args)
5010{
5011 int cpu = _get_cpu(set, "i|clear", args);
5012 if (cpu == -1)
5013 return NULL;
5014 CPU_CLR_S(cpu, set->size, set->set);
5015 Py_RETURN_NONE;
5016}
5017
5018PyDoc_STRVAR(cpu_set_isset_doc,
5019"cpu_set.isset(i) -> bool\n\n\
5020Test if CPU *i* is in the set.");
5021
5022static PyObject *
5023cpu_set_isset(Py_cpu_set *set, PyObject *args)
5024{
5025 int cpu = _get_cpu(set, "i|isset", args);
5026 if (cpu == -1)
5027 return NULL;
5028 if (CPU_ISSET_S(cpu, set->size, set->set))
5029 Py_RETURN_TRUE;
5030 Py_RETURN_FALSE;
5031}
5032
5033PyDoc_STRVAR(cpu_set_zero_doc,
5034"cpu_set.zero()\n\n\
5035Clear the cpu_set.");
5036
5037static PyObject *
5038cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5039{
5040 CPU_ZERO_S(set->size, set->set);
5041 Py_RETURN_NONE;
5042}
5043
5044static PyObject *
5045cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5046{
5047 int eq;
5048
Brian Curtindfc80e32011-08-10 20:28:54 -05005049 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5050 Py_RETURN_NOTIMPLEMENTED;
5051
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005052 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5053 if ((op == Py_EQ) ? eq : !eq)
5054 Py_RETURN_TRUE;
5055 else
5056 Py_RETURN_FALSE;
5057}
5058
5059#define CPU_SET_BINOP(name, op) \
5060 static PyObject * \
5061 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5062 if (res) { \
5063 Py_INCREF(res); \
5064 } \
5065 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005066 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005067 if (!res) \
5068 return NULL; \
5069 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005070 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005071 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005072 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005073 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005074 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005075 op(res->size, res->set, left->set, right->set); \
5076 return (PyObject *)res; \
5077 } \
5078 static PyObject * \
5079 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5080 return do_cpu_set_##name(left, right, NULL); \
5081 } \
5082 static PyObject * \
5083 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5084 return do_cpu_set_##name(left, right, left); \
5085 } \
5086
5087CPU_SET_BINOP(and, CPU_AND_S)
5088CPU_SET_BINOP(or, CPU_OR_S)
5089CPU_SET_BINOP(xor, CPU_XOR_S)
5090#undef CPU_SET_BINOP
5091
5092PyDoc_STRVAR(cpu_set_doc,
5093"cpu_set(size)\n\n\
5094Create an empty mask of CPUs.");
5095
5096static PyNumberMethods cpu_set_as_number = {
5097 0, /*nb_add*/
5098 0, /*nb_subtract*/
5099 0, /*nb_multiply*/
5100 0, /*nb_remainder*/
5101 0, /*nb_divmod*/
5102 0, /*nb_power*/
5103 0, /*nb_negative*/
5104 0, /*nb_positive*/
5105 0, /*nb_absolute*/
5106 0, /*nb_bool*/
5107 0, /*nb_invert*/
5108 0, /*nb_lshift*/
5109 0, /*nb_rshift*/
5110 (binaryfunc)cpu_set_and, /*nb_and*/
5111 (binaryfunc)cpu_set_xor, /*nb_xor*/
5112 (binaryfunc)cpu_set_or, /*nb_or*/
5113 0, /*nb_int*/
5114 0, /*nb_reserved*/
5115 0, /*nb_float*/
5116 0, /*nb_inplace_add*/
5117 0, /*nb_inplace_subtract*/
5118 0, /*nb_inplace_multiply*/
5119 0, /*nb_inplace_remainder*/
5120 0, /*nb_inplace_power*/
5121 0, /*nb_inplace_lshift*/
5122 0, /*nb_inplace_rshift*/
5123 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5124 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5125 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5126};
5127
5128static PySequenceMethods cpu_set_as_sequence = {
5129 (lenfunc)cpu_set_len, /* sq_length */
5130};
5131
5132static PyMethodDef cpu_set_methods[] = {
5133 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5134 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5135 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5136 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5137 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5138 {NULL, NULL} /* sentinel */
5139};
5140
5141static PyTypeObject cpu_set_type = {
5142 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5143 "posix.cpu_set", /* tp_name */
5144 sizeof(Py_cpu_set), /* tp_basicsize */
5145 0, /* tp_itemsize */
5146 /* methods */
5147 (destructor)cpu_set_dealloc, /* tp_dealloc */
5148 0, /* tp_print */
5149 0, /* tp_getattr */
5150 0, /* tp_setattr */
5151 0, /* tp_reserved */
5152 (reprfunc)cpu_set_repr, /* tp_repr */
5153 &cpu_set_as_number, /* tp_as_number */
5154 &cpu_set_as_sequence, /* tp_as_sequence */
5155 0, /* tp_as_mapping */
5156 PyObject_HashNotImplemented, /* tp_hash */
5157 0, /* tp_call */
5158 0, /* tp_str */
5159 PyObject_GenericGetAttr, /* tp_getattro */
5160 0, /* tp_setattro */
5161 0, /* tp_as_buffer */
5162 Py_TPFLAGS_DEFAULT, /* tp_flags */
5163 cpu_set_doc, /* tp_doc */
5164 0, /* tp_traverse */
5165 0, /* tp_clear */
5166 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5167 0, /* tp_weaklistoffset */
5168 0, /* tp_iter */
5169 0, /* tp_iternext */
5170 cpu_set_methods, /* tp_methods */
5171 0, /* tp_members */
5172 0, /* tp_getset */
5173 0, /* tp_base */
5174 0, /* tp_dict */
5175 0, /* tp_descr_get */
5176 0, /* tp_descr_set */
5177 0, /* tp_dictoffset */
5178 0, /* tp_init */
5179 PyType_GenericAlloc, /* tp_alloc */
5180 cpu_set_new, /* tp_new */
5181 PyObject_Del, /* tp_free */
5182};
5183
5184PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5185"sched_setaffinity(pid, cpu_set)\n\n\
5186Set the affinity of the process with PID *pid* to *cpu_set*.");
5187
5188static PyObject *
5189posix_sched_setaffinity(PyObject *self, PyObject *args)
5190{
5191 pid_t pid;
5192 Py_cpu_set *cpu_set;
5193
Benjamin Petersona17a5d62011-08-09 16:49:13 -05005194 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005195 &pid, &cpu_set_type, &cpu_set))
5196 return NULL;
5197 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
5198 return posix_error();
5199 Py_RETURN_NONE;
5200}
5201
5202PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5203"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5204Return the affinity of the process with PID *pid*.\n\
5205The returned cpu_set will be of size *ncpus*.");
5206
5207static PyObject *
5208posix_sched_getaffinity(PyObject *self, PyObject *args)
5209{
5210 pid_t pid;
5211 int ncpus;
5212 Py_cpu_set *res;
5213
Benjamin Peterson7ac92142011-08-03 08:54:26 -05005214 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005215 &pid, &ncpus))
5216 return NULL;
5217 res = make_new_cpu_set(&cpu_set_type, ncpus);
5218 if (!res)
5219 return NULL;
5220 if (sched_getaffinity(pid, res->size, res->set)) {
5221 Py_DECREF(res);
5222 return posix_error();
5223 }
5224 return (PyObject *)res;
5225}
5226
Benjamin Peterson2740af82011-08-02 17:41:34 -05005227#endif /* HAVE_SCHED_SETAFFINITY */
5228
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005229#endif /* HAVE_SCHED_H */
5230
Neal Norwitzb59798b2003-03-21 01:43:31 +00005231/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005232/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5233#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005234#define DEV_PTY_FILE "/dev/ptc"
5235#define HAVE_DEV_PTMX
5236#else
5237#define DEV_PTY_FILE "/dev/ptmx"
5238#endif
5239
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005240#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005241#ifdef HAVE_PTY_H
5242#include <pty.h>
5243#else
5244#ifdef HAVE_LIBUTIL_H
5245#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005246#else
5247#ifdef HAVE_UTIL_H
5248#include <util.h>
5249#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005250#endif /* HAVE_LIBUTIL_H */
5251#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005252#ifdef HAVE_STROPTS_H
5253#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005254#endif
5255#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005256
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005257#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005258PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005259"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005260Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005261
5262static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005263posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005264{
Victor Stinner8c62be82010-05-06 00:08:46 +00005265 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005266#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005267 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005268#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005269#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005270 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005271#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005272 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005273#endif
5274#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005275
Thomas Wouters70c21a12000-07-14 14:28:33 +00005276#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005277 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5278 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005279#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005280 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5281 if (slave_name == NULL)
5282 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005283
Victor Stinner8c62be82010-05-06 00:08:46 +00005284 slave_fd = open(slave_name, O_RDWR);
5285 if (slave_fd < 0)
5286 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005287#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005288 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5289 if (master_fd < 0)
5290 return posix_error();
5291 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5292 /* change permission of slave */
5293 if (grantpt(master_fd) < 0) {
5294 PyOS_setsig(SIGCHLD, sig_saved);
5295 return posix_error();
5296 }
5297 /* unlock slave */
5298 if (unlockpt(master_fd) < 0) {
5299 PyOS_setsig(SIGCHLD, sig_saved);
5300 return posix_error();
5301 }
5302 PyOS_setsig(SIGCHLD, sig_saved);
5303 slave_name = ptsname(master_fd); /* get name of slave */
5304 if (slave_name == NULL)
5305 return posix_error();
5306 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5307 if (slave_fd < 0)
5308 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005309#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005310 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5311 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005312#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005313 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005314#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005315#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005316#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005317
Victor Stinner8c62be82010-05-06 00:08:46 +00005318 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005319
Fred Drake8cef4cf2000-06-28 16:40:38 +00005320}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005321#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005322
5323#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005324PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005325"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005326Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5327Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005328To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005329
5330static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005331posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005332{
Victor Stinner8c62be82010-05-06 00:08:46 +00005333 int master_fd = -1, result = 0;
5334 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005335
Victor Stinner8c62be82010-05-06 00:08:46 +00005336 _PyImport_AcquireLock();
5337 pid = forkpty(&master_fd, NULL, NULL, NULL);
5338 if (pid == 0) {
5339 /* child: this clobbers and resets the import lock. */
5340 PyOS_AfterFork();
5341 } else {
5342 /* parent: release the import lock. */
5343 result = _PyImport_ReleaseLock();
5344 }
5345 if (pid == -1)
5346 return posix_error();
5347 if (result < 0) {
5348 /* Don't clobber the OSError if the fork failed. */
5349 PyErr_SetString(PyExc_RuntimeError,
5350 "not holding the import lock");
5351 return NULL;
5352 }
5353 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005354}
5355#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005356
Ross Lagerwall7807c352011-03-17 20:20:30 +02005357
Guido van Rossumad0ee831995-03-01 10:34:45 +00005358#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005359PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005360"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005361Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005362
Barry Warsaw53699e91996-12-10 23:23:01 +00005363static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005364posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005365{
Victor Stinner8c62be82010-05-06 00:08:46 +00005366 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005367}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005368#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005369
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005370
Guido van Rossumad0ee831995-03-01 10:34:45 +00005371#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005372PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005373"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005374Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005375
Barry Warsaw53699e91996-12-10 23:23:01 +00005376static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005377posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005378{
Victor Stinner8c62be82010-05-06 00:08:46 +00005379 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005380}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005381#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005382
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005383
Guido van Rossumad0ee831995-03-01 10:34:45 +00005384#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005385PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005386"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005387Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005388
Barry Warsaw53699e91996-12-10 23:23:01 +00005389static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005390posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005391{
Victor Stinner8c62be82010-05-06 00:08:46 +00005392 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005393}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005394#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005395
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005396
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005397PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005398"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005399Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005400
Barry Warsaw53699e91996-12-10 23:23:01 +00005401static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005402posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005403{
Victor Stinner8c62be82010-05-06 00:08:46 +00005404 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005405}
5406
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005407#ifdef HAVE_GETGROUPLIST
5408PyDoc_STRVAR(posix_getgrouplist__doc__,
5409"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5410Returns a list of groups to which a user belongs.\n\n\
5411 user: username to lookup\n\
5412 group: base group id of the user");
5413
5414static PyObject *
5415posix_getgrouplist(PyObject *self, PyObject *args)
5416{
5417#ifdef NGROUPS_MAX
5418#define MAX_GROUPS NGROUPS_MAX
5419#else
5420 /* defined to be 16 on Solaris7, so this should be a small number */
5421#define MAX_GROUPS 64
5422#endif
5423
5424 const char *user;
5425 int i, ngroups;
5426 PyObject *list;
5427#ifdef __APPLE__
5428 int *groups, basegid;
5429#else
5430 gid_t *groups, basegid;
5431#endif
5432 ngroups = MAX_GROUPS;
5433
5434 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5435 return NULL;
5436
5437#ifdef __APPLE__
5438 groups = PyMem_Malloc(ngroups * sizeof(int));
5439#else
5440 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5441#endif
5442 if (groups == NULL)
5443 return PyErr_NoMemory();
5444
5445 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5446 PyMem_Del(groups);
5447 return posix_error();
5448 }
5449
5450 list = PyList_New(ngroups);
5451 if (list == NULL) {
5452 PyMem_Del(groups);
5453 return NULL;
5454 }
5455
5456 for (i = 0; i < ngroups; i++) {
5457 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5458 if (o == NULL) {
5459 Py_DECREF(list);
5460 PyMem_Del(groups);
5461 return NULL;
5462 }
5463 PyList_SET_ITEM(list, i, o);
5464 }
5465
5466 PyMem_Del(groups);
5467
5468 return list;
5469}
5470#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005471
Fred Drakec9680921999-12-13 16:37:25 +00005472#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005473PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005474"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005475Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005476
5477static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005478posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005479{
5480 PyObject *result = NULL;
5481
Fred Drakec9680921999-12-13 16:37:25 +00005482#ifdef NGROUPS_MAX
5483#define MAX_GROUPS NGROUPS_MAX
5484#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005485 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005486#define MAX_GROUPS 64
5487#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005488 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005489
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005490 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005491 * This is a helper variable to store the intermediate result when
5492 * that happens.
5493 *
5494 * To keep the code readable the OSX behaviour is unconditional,
5495 * according to the POSIX spec this should be safe on all unix-y
5496 * systems.
5497 */
5498 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005499 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005500
Victor Stinner8c62be82010-05-06 00:08:46 +00005501 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005502 if (n < 0) {
5503 if (errno == EINVAL) {
5504 n = getgroups(0, NULL);
5505 if (n == -1) {
5506 return posix_error();
5507 }
5508 if (n == 0) {
5509 /* Avoid malloc(0) */
5510 alt_grouplist = grouplist;
5511 } else {
5512 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5513 if (alt_grouplist == NULL) {
5514 errno = EINVAL;
5515 return posix_error();
5516 }
5517 n = getgroups(n, alt_grouplist);
5518 if (n == -1) {
5519 PyMem_Free(alt_grouplist);
5520 return posix_error();
5521 }
5522 }
5523 } else {
5524 return posix_error();
5525 }
5526 }
5527 result = PyList_New(n);
5528 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005529 int i;
5530 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005531 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005532 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005533 Py_DECREF(result);
5534 result = NULL;
5535 break;
Fred Drakec9680921999-12-13 16:37:25 +00005536 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005537 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005538 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005539 }
5540
5541 if (alt_grouplist != grouplist) {
5542 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005543 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005544
Fred Drakec9680921999-12-13 16:37:25 +00005545 return result;
5546}
5547#endif
5548
Antoine Pitroub7572f02009-12-02 20:46:48 +00005549#ifdef HAVE_INITGROUPS
5550PyDoc_STRVAR(posix_initgroups__doc__,
5551"initgroups(username, gid) -> None\n\n\
5552Call the system initgroups() to initialize the group access list with all of\n\
5553the groups of which the specified username is a member, plus the specified\n\
5554group id.");
5555
5556static PyObject *
5557posix_initgroups(PyObject *self, PyObject *args)
5558{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005559 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005560 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005561 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005562 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005563
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005564 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5565 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005566 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005567 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005568
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005569 res = initgroups(username, (gid_t) gid);
5570 Py_DECREF(oname);
5571 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005572 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005573
Victor Stinner8c62be82010-05-06 00:08:46 +00005574 Py_INCREF(Py_None);
5575 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005576}
5577#endif
5578
Martin v. Löwis606edc12002-06-13 21:09:11 +00005579#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005580PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005581"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005582Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005583
5584static PyObject *
5585posix_getpgid(PyObject *self, PyObject *args)
5586{
Victor Stinner8c62be82010-05-06 00:08:46 +00005587 pid_t pid, pgid;
5588 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5589 return NULL;
5590 pgid = getpgid(pid);
5591 if (pgid < 0)
5592 return posix_error();
5593 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005594}
5595#endif /* HAVE_GETPGID */
5596
5597
Guido van Rossumb6775db1994-08-01 11:34:53 +00005598#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005599PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005600"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005601Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005602
Barry Warsaw53699e91996-12-10 23:23:01 +00005603static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005604posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005605{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005606#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005607 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005608#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005609 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005610#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005611}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005612#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005613
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005614
Guido van Rossumb6775db1994-08-01 11:34:53 +00005615#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005616PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005617"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005618Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005619
Barry Warsaw53699e91996-12-10 23:23:01 +00005620static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005621posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005622{
Guido van Rossum64933891994-10-20 21:56:42 +00005623#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005624 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005625#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005626 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005627#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005628 return posix_error();
5629 Py_INCREF(Py_None);
5630 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005631}
5632
Guido van Rossumb6775db1994-08-01 11:34:53 +00005633#endif /* HAVE_SETPGRP */
5634
Guido van Rossumad0ee831995-03-01 10:34:45 +00005635#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005636
5637#ifdef MS_WINDOWS
5638#include <tlhelp32.h>
5639
5640static PyObject*
5641win32_getppid()
5642{
5643 HANDLE snapshot;
5644 pid_t mypid;
5645 PyObject* result = NULL;
5646 BOOL have_record;
5647 PROCESSENTRY32 pe;
5648
5649 mypid = getpid(); /* This function never fails */
5650
5651 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5652 if (snapshot == INVALID_HANDLE_VALUE)
5653 return PyErr_SetFromWindowsErr(GetLastError());
5654
5655 pe.dwSize = sizeof(pe);
5656 have_record = Process32First(snapshot, &pe);
5657 while (have_record) {
5658 if (mypid == (pid_t)pe.th32ProcessID) {
5659 /* We could cache the ulong value in a static variable. */
5660 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5661 break;
5662 }
5663
5664 have_record = Process32Next(snapshot, &pe);
5665 }
5666
5667 /* If our loop exits and our pid was not found (result will be NULL)
5668 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5669 * error anyway, so let's raise it. */
5670 if (!result)
5671 result = PyErr_SetFromWindowsErr(GetLastError());
5672
5673 CloseHandle(snapshot);
5674
5675 return result;
5676}
5677#endif /*MS_WINDOWS*/
5678
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005679PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005680"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005681Return the parent's process id. If the parent process has already exited,\n\
5682Windows machines will still return its id; others systems will return the id\n\
5683of the 'init' process (1).");
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_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005687{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005688#ifdef MS_WINDOWS
5689 return win32_getppid();
5690#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005691 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005692#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005693}
5694#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005696
Fred Drake12c6e2d1999-12-14 21:25:03 +00005697#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005698PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005699"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005700Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005701
5702static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005703posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005704{
Victor Stinner8c62be82010-05-06 00:08:46 +00005705 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005706#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005707 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02005708 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005709
5710 if (GetUserNameW(user_name, &num_chars)) {
5711 /* num_chars is the number of unicode chars plus null terminator */
5712 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005713 }
5714 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005715 result = PyErr_SetFromWindowsErr(GetLastError());
5716#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005717 char *name;
5718 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005719
Victor Stinner8c62be82010-05-06 00:08:46 +00005720 errno = 0;
5721 name = getlogin();
5722 if (name == NULL) {
5723 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005724 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005725 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005726 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005727 }
5728 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005729 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005730 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005731#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005732 return result;
5733}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005734#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005735
Guido van Rossumad0ee831995-03-01 10:34:45 +00005736#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005737PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005738"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005739Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005740
Barry Warsaw53699e91996-12-10 23:23:01 +00005741static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005742posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005743{
Victor Stinner8c62be82010-05-06 00:08:46 +00005744 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005745}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005746#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005747
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005748
Guido van Rossumad0ee831995-03-01 10:34:45 +00005749#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005750PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005751"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005752Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005753
Barry Warsaw53699e91996-12-10 23:23:01 +00005754static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005755posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005756{
Victor Stinner8c62be82010-05-06 00:08:46 +00005757 pid_t pid;
5758 int sig;
5759 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
5760 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005761#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005762 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
5763 APIRET rc;
5764 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005765 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005766
5767 } else if (sig == XCPT_SIGNAL_KILLPROC) {
5768 APIRET rc;
5769 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005770 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005771
5772 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005773 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005774#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005775 if (kill(pid, sig) == -1)
5776 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005777#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005778 Py_INCREF(Py_None);
5779 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00005780}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005781#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005782
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005783#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005784PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005785"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005786Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005787
5788static PyObject *
5789posix_killpg(PyObject *self, PyObject *args)
5790{
Victor Stinner8c62be82010-05-06 00:08:46 +00005791 int sig;
5792 pid_t pgid;
5793 /* XXX some man pages make the `pgid` parameter an int, others
5794 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
5795 take the same type. Moreover, pid_t is always at least as wide as
5796 int (else compilation of this module fails), which is safe. */
5797 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
5798 return NULL;
5799 if (killpg(pgid, sig) == -1)
5800 return posix_error();
5801 Py_INCREF(Py_None);
5802 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005803}
5804#endif
5805
Brian Curtineb24d742010-04-12 17:16:38 +00005806#ifdef MS_WINDOWS
5807PyDoc_STRVAR(win32_kill__doc__,
5808"kill(pid, sig)\n\n\
5809Kill a process with a signal.");
5810
5811static PyObject *
5812win32_kill(PyObject *self, PyObject *args)
5813{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00005814 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005815 DWORD pid, sig, err;
5816 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00005817
Victor Stinner8c62be82010-05-06 00:08:46 +00005818 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
5819 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00005820
Victor Stinner8c62be82010-05-06 00:08:46 +00005821 /* Console processes which share a common console can be sent CTRL+C or
5822 CTRL+BREAK events, provided they handle said events. */
5823 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
5824 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
5825 err = GetLastError();
5826 PyErr_SetFromWindowsErr(err);
5827 }
5828 else
5829 Py_RETURN_NONE;
5830 }
Brian Curtineb24d742010-04-12 17:16:38 +00005831
Victor Stinner8c62be82010-05-06 00:08:46 +00005832 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
5833 attempt to open and terminate the process. */
5834 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
5835 if (handle == NULL) {
5836 err = GetLastError();
5837 return PyErr_SetFromWindowsErr(err);
5838 }
Brian Curtineb24d742010-04-12 17:16:38 +00005839
Victor Stinner8c62be82010-05-06 00:08:46 +00005840 if (TerminateProcess(handle, sig) == 0) {
5841 err = GetLastError();
5842 result = PyErr_SetFromWindowsErr(err);
5843 } else {
5844 Py_INCREF(Py_None);
5845 result = Py_None;
5846 }
Brian Curtineb24d742010-04-12 17:16:38 +00005847
Victor Stinner8c62be82010-05-06 00:08:46 +00005848 CloseHandle(handle);
5849 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00005850}
5851#endif /* MS_WINDOWS */
5852
Guido van Rossumc0125471996-06-28 18:55:32 +00005853#ifdef HAVE_PLOCK
5854
5855#ifdef HAVE_SYS_LOCK_H
5856#include <sys/lock.h>
5857#endif
5858
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005859PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005860"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005861Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005862
Barry Warsaw53699e91996-12-10 23:23:01 +00005863static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005864posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00005865{
Victor Stinner8c62be82010-05-06 00:08:46 +00005866 int op;
5867 if (!PyArg_ParseTuple(args, "i:plock", &op))
5868 return NULL;
5869 if (plock(op) == -1)
5870 return posix_error();
5871 Py_INCREF(Py_None);
5872 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00005873}
5874#endif
5875
Guido van Rossumb6775db1994-08-01 11:34:53 +00005876#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005877PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005878"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005879Set the current process's user id.");
5880
Barry Warsaw53699e91996-12-10 23:23:01 +00005881static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005882posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005883{
Victor Stinner8c62be82010-05-06 00:08:46 +00005884 long uid_arg;
5885 uid_t uid;
5886 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5887 return NULL;
5888 uid = uid_arg;
5889 if (uid != uid_arg) {
5890 PyErr_SetString(PyExc_OverflowError, "user id too big");
5891 return NULL;
5892 }
5893 if (setuid(uid) < 0)
5894 return posix_error();
5895 Py_INCREF(Py_None);
5896 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005897}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005898#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005899
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005900
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005901#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005902PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005903"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005904Set the current process's effective user id.");
5905
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005906static PyObject *
5907posix_seteuid (PyObject *self, PyObject *args)
5908{
Victor Stinner8c62be82010-05-06 00:08:46 +00005909 long euid_arg;
5910 uid_t euid;
5911 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5912 return NULL;
5913 euid = euid_arg;
5914 if (euid != euid_arg) {
5915 PyErr_SetString(PyExc_OverflowError, "user id too big");
5916 return NULL;
5917 }
5918 if (seteuid(euid) < 0) {
5919 return posix_error();
5920 } else {
5921 Py_INCREF(Py_None);
5922 return Py_None;
5923 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005924}
5925#endif /* HAVE_SETEUID */
5926
5927#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005928PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005929"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005930Set the current process's effective group id.");
5931
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005932static PyObject *
5933posix_setegid (PyObject *self, PyObject *args)
5934{
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 long egid_arg;
5936 gid_t egid;
5937 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5938 return NULL;
5939 egid = egid_arg;
5940 if (egid != egid_arg) {
5941 PyErr_SetString(PyExc_OverflowError, "group id too big");
5942 return NULL;
5943 }
5944 if (setegid(egid) < 0) {
5945 return posix_error();
5946 } else {
5947 Py_INCREF(Py_None);
5948 return Py_None;
5949 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005950}
5951#endif /* HAVE_SETEGID */
5952
5953#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005954PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005955"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005956Set the current process's real and effective user ids.");
5957
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005958static PyObject *
5959posix_setreuid (PyObject *self, PyObject *args)
5960{
Victor Stinner8c62be82010-05-06 00:08:46 +00005961 long ruid_arg, euid_arg;
5962 uid_t ruid, euid;
5963 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5964 return NULL;
5965 if (ruid_arg == -1)
5966 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
5967 else
5968 ruid = ruid_arg; /* otherwise, assign from our long */
5969 if (euid_arg == -1)
5970 euid = (uid_t)-1;
5971 else
5972 euid = euid_arg;
5973 if ((euid_arg != -1 && euid != euid_arg) ||
5974 (ruid_arg != -1 && ruid != ruid_arg)) {
5975 PyErr_SetString(PyExc_OverflowError, "user id too big");
5976 return NULL;
5977 }
5978 if (setreuid(ruid, euid) < 0) {
5979 return posix_error();
5980 } else {
5981 Py_INCREF(Py_None);
5982 return Py_None;
5983 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005984}
5985#endif /* HAVE_SETREUID */
5986
5987#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005988PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005989"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005990Set the current process's real and effective group ids.");
5991
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005992static PyObject *
5993posix_setregid (PyObject *self, PyObject *args)
5994{
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 long rgid_arg, egid_arg;
5996 gid_t rgid, egid;
5997 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
5998 return NULL;
5999 if (rgid_arg == -1)
6000 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6001 else
6002 rgid = rgid_arg; /* otherwise, assign from our long */
6003 if (egid_arg == -1)
6004 egid = (gid_t)-1;
6005 else
6006 egid = egid_arg;
6007 if ((egid_arg != -1 && egid != egid_arg) ||
6008 (rgid_arg != -1 && rgid != rgid_arg)) {
6009 PyErr_SetString(PyExc_OverflowError, "group id too big");
6010 return NULL;
6011 }
6012 if (setregid(rgid, egid) < 0) {
6013 return posix_error();
6014 } else {
6015 Py_INCREF(Py_None);
6016 return Py_None;
6017 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006018}
6019#endif /* HAVE_SETREGID */
6020
Guido van Rossumb6775db1994-08-01 11:34:53 +00006021#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006022PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006023"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006024Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006025
Barry Warsaw53699e91996-12-10 23:23:01 +00006026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006027posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006028{
Victor Stinner8c62be82010-05-06 00:08:46 +00006029 long gid_arg;
6030 gid_t gid;
6031 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6032 return NULL;
6033 gid = gid_arg;
6034 if (gid != gid_arg) {
6035 PyErr_SetString(PyExc_OverflowError, "group id too big");
6036 return NULL;
6037 }
6038 if (setgid(gid) < 0)
6039 return posix_error();
6040 Py_INCREF(Py_None);
6041 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006042}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006043#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006044
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006045#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006046PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006047"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006048Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006049
6050static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006051posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006052{
Victor Stinner8c62be82010-05-06 00:08:46 +00006053 int i, len;
6054 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006055
Victor Stinner8c62be82010-05-06 00:08:46 +00006056 if (!PySequence_Check(groups)) {
6057 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6058 return NULL;
6059 }
6060 len = PySequence_Size(groups);
6061 if (len > MAX_GROUPS) {
6062 PyErr_SetString(PyExc_ValueError, "too many groups");
6063 return NULL;
6064 }
6065 for(i = 0; i < len; i++) {
6066 PyObject *elem;
6067 elem = PySequence_GetItem(groups, i);
6068 if (!elem)
6069 return NULL;
6070 if (!PyLong_Check(elem)) {
6071 PyErr_SetString(PyExc_TypeError,
6072 "groups must be integers");
6073 Py_DECREF(elem);
6074 return NULL;
6075 } else {
6076 unsigned long x = PyLong_AsUnsignedLong(elem);
6077 if (PyErr_Occurred()) {
6078 PyErr_SetString(PyExc_TypeError,
6079 "group id too big");
6080 Py_DECREF(elem);
6081 return NULL;
6082 }
6083 grouplist[i] = x;
6084 /* read back the value to see if it fitted in gid_t */
6085 if (grouplist[i] != x) {
6086 PyErr_SetString(PyExc_TypeError,
6087 "group id too big");
6088 Py_DECREF(elem);
6089 return NULL;
6090 }
6091 }
6092 Py_DECREF(elem);
6093 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006094
Victor Stinner8c62be82010-05-06 00:08:46 +00006095 if (setgroups(len, grouplist) < 0)
6096 return posix_error();
6097 Py_INCREF(Py_None);
6098 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006099}
6100#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006101
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006102#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6103static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00006104wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006105{
Victor Stinner8c62be82010-05-06 00:08:46 +00006106 PyObject *result;
6107 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006108 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006109
Victor Stinner8c62be82010-05-06 00:08:46 +00006110 if (pid == -1)
6111 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006112
Victor Stinner8c62be82010-05-06 00:08:46 +00006113 if (struct_rusage == NULL) {
6114 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6115 if (m == NULL)
6116 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006117 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006118 Py_DECREF(m);
6119 if (struct_rusage == NULL)
6120 return NULL;
6121 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006122
Victor Stinner8c62be82010-05-06 00:08:46 +00006123 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6124 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6125 if (!result)
6126 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006127
6128#ifndef doubletime
6129#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6130#endif
6131
Victor Stinner8c62be82010-05-06 00:08:46 +00006132 PyStructSequence_SET_ITEM(result, 0,
6133 PyFloat_FromDouble(doubletime(ru->ru_utime)));
6134 PyStructSequence_SET_ITEM(result, 1,
6135 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006136#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006137 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6138 SET_INT(result, 2, ru->ru_maxrss);
6139 SET_INT(result, 3, ru->ru_ixrss);
6140 SET_INT(result, 4, ru->ru_idrss);
6141 SET_INT(result, 5, ru->ru_isrss);
6142 SET_INT(result, 6, ru->ru_minflt);
6143 SET_INT(result, 7, ru->ru_majflt);
6144 SET_INT(result, 8, ru->ru_nswap);
6145 SET_INT(result, 9, ru->ru_inblock);
6146 SET_INT(result, 10, ru->ru_oublock);
6147 SET_INT(result, 11, ru->ru_msgsnd);
6148 SET_INT(result, 12, ru->ru_msgrcv);
6149 SET_INT(result, 13, ru->ru_nsignals);
6150 SET_INT(result, 14, ru->ru_nvcsw);
6151 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006152#undef SET_INT
6153
Victor Stinner8c62be82010-05-06 00:08:46 +00006154 if (PyErr_Occurred()) {
6155 Py_DECREF(result);
6156 return NULL;
6157 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006158
Victor Stinner8c62be82010-05-06 00:08:46 +00006159 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006160}
6161#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6162
6163#ifdef HAVE_WAIT3
6164PyDoc_STRVAR(posix_wait3__doc__,
6165"wait3(options) -> (pid, status, rusage)\n\n\
6166Wait for completion of a child process.");
6167
6168static PyObject *
6169posix_wait3(PyObject *self, PyObject *args)
6170{
Victor Stinner8c62be82010-05-06 00:08:46 +00006171 pid_t pid;
6172 int options;
6173 struct rusage ru;
6174 WAIT_TYPE status;
6175 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006176
Victor Stinner8c62be82010-05-06 00:08:46 +00006177 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6178 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006179
Victor Stinner8c62be82010-05-06 00:08:46 +00006180 Py_BEGIN_ALLOW_THREADS
6181 pid = wait3(&status, options, &ru);
6182 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006183
Victor Stinner8c62be82010-05-06 00:08:46 +00006184 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006185}
6186#endif /* HAVE_WAIT3 */
6187
6188#ifdef HAVE_WAIT4
6189PyDoc_STRVAR(posix_wait4__doc__,
6190"wait4(pid, options) -> (pid, status, rusage)\n\n\
6191Wait for completion of a given child process.");
6192
6193static PyObject *
6194posix_wait4(PyObject *self, PyObject *args)
6195{
Victor Stinner8c62be82010-05-06 00:08:46 +00006196 pid_t pid;
6197 int options;
6198 struct rusage ru;
6199 WAIT_TYPE status;
6200 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006201
Victor Stinner8c62be82010-05-06 00:08:46 +00006202 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
6203 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006204
Victor Stinner8c62be82010-05-06 00:08:46 +00006205 Py_BEGIN_ALLOW_THREADS
6206 pid = wait4(pid, &status, options, &ru);
6207 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006208
Victor Stinner8c62be82010-05-06 00:08:46 +00006209 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006210}
6211#endif /* HAVE_WAIT4 */
6212
Ross Lagerwall7807c352011-03-17 20:20:30 +02006213#if defined(HAVE_WAITID) && !defined(__APPLE__)
6214PyDoc_STRVAR(posix_waitid__doc__,
6215"waitid(idtype, id, options) -> waitid_result\n\n\
6216Wait for the completion of one or more child processes.\n\n\
6217idtype can be P_PID, P_PGID or P_ALL.\n\
6218id specifies the pid to wait on.\n\
6219options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6220or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6221Returns either waitid_result or None if WNOHANG is specified and there are\n\
6222no children in a waitable state.");
6223
6224static PyObject *
6225posix_waitid(PyObject *self, PyObject *args)
6226{
6227 PyObject *result;
6228 idtype_t idtype;
6229 id_t id;
6230 int options, res;
6231 siginfo_t si;
6232 si.si_pid = 0;
6233 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6234 return NULL;
6235 Py_BEGIN_ALLOW_THREADS
6236 res = waitid(idtype, id, &si, options);
6237 Py_END_ALLOW_THREADS
6238 if (res == -1)
6239 return posix_error();
6240
6241 if (si.si_pid == 0)
6242 Py_RETURN_NONE;
6243
6244 result = PyStructSequence_New(&WaitidResultType);
6245 if (!result)
6246 return NULL;
6247
6248 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6249 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6250 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6251 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6252 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6253 if (PyErr_Occurred()) {
6254 Py_DECREF(result);
6255 return NULL;
6256 }
6257
6258 return result;
6259}
6260#endif
6261
Guido van Rossumb6775db1994-08-01 11:34:53 +00006262#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006263PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006264"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006265Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006266
Barry Warsaw53699e91996-12-10 23:23:01 +00006267static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006268posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006269{
Victor Stinner8c62be82010-05-06 00:08:46 +00006270 pid_t pid;
6271 int options;
6272 WAIT_TYPE status;
6273 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006274
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6276 return NULL;
6277 Py_BEGIN_ALLOW_THREADS
6278 pid = waitpid(pid, &status, options);
6279 Py_END_ALLOW_THREADS
6280 if (pid == -1)
6281 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006282
Victor Stinner8c62be82010-05-06 00:08:46 +00006283 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006284}
6285
Tim Petersab034fa2002-02-01 11:27:43 +00006286#elif defined(HAVE_CWAIT)
6287
6288/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006289PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006290"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006291"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006292
6293static PyObject *
6294posix_waitpid(PyObject *self, PyObject *args)
6295{
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 Py_intptr_t pid;
6297 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006298
Victor Stinner8c62be82010-05-06 00:08:46 +00006299 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6300 return NULL;
6301 Py_BEGIN_ALLOW_THREADS
6302 pid = _cwait(&status, pid, options);
6303 Py_END_ALLOW_THREADS
6304 if (pid == -1)
6305 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006306
Victor Stinner8c62be82010-05-06 00:08:46 +00006307 /* shift the status left a byte so this is more like the POSIX waitpid */
6308 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006309}
6310#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006311
Guido van Rossumad0ee831995-03-01 10:34:45 +00006312#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006313PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006314"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006315Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006316
Barry Warsaw53699e91996-12-10 23:23:01 +00006317static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006318posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006319{
Victor Stinner8c62be82010-05-06 00:08:46 +00006320 pid_t pid;
6321 WAIT_TYPE status;
6322 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006323
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 Py_BEGIN_ALLOW_THREADS
6325 pid = wait(&status);
6326 Py_END_ALLOW_THREADS
6327 if (pid == -1)
6328 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006329
Victor Stinner8c62be82010-05-06 00:08:46 +00006330 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006331}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006332#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006333
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006334
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006335PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006336"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006337Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006338
Barry Warsaw53699e91996-12-10 23:23:01 +00006339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006340posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006341{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006342#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00006343 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006344#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006345#ifdef MS_WINDOWS
Brian Curtind25aef52011-06-13 15:16:04 -05006346 return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat",
Brian Curtind40e6f72010-07-08 21:39:08 +00006347 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006348#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006349 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006350#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006351#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006352}
6353
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006354
Guido van Rossumb6775db1994-08-01 11:34:53 +00006355#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006356PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006357"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006358Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006359
Barry Warsaw53699e91996-12-10 23:23:01 +00006360static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006361posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006362{
Victor Stinner8c62be82010-05-06 00:08:46 +00006363 PyObject* v;
6364 char buf[MAXPATHLEN];
6365 PyObject *opath;
6366 char *path;
6367 int n;
6368 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006369
Victor Stinner8c62be82010-05-06 00:08:46 +00006370 if (!PyArg_ParseTuple(args, "O&:readlink",
6371 PyUnicode_FSConverter, &opath))
6372 return NULL;
6373 path = PyBytes_AsString(opath);
6374 v = PySequence_GetItem(args, 0);
6375 if (v == NULL) {
6376 Py_DECREF(opath);
6377 return NULL;
6378 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00006379
Victor Stinner8c62be82010-05-06 00:08:46 +00006380 if (PyUnicode_Check(v)) {
6381 arg_is_unicode = 1;
6382 }
6383 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006384
Victor Stinner8c62be82010-05-06 00:08:46 +00006385 Py_BEGIN_ALLOW_THREADS
6386 n = readlink(path, buf, (int) sizeof buf);
6387 Py_END_ALLOW_THREADS
6388 if (n < 0)
6389 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006390
Victor Stinner8c62be82010-05-06 00:08:46 +00006391 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00006392 if (arg_is_unicode)
6393 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
6394 else
6395 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006396}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006397#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006398
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006399
Brian Curtin52173d42010-12-02 18:29:18 +00006400#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006401PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006402"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006403Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006404
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006406posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006407{
Victor Stinner8c62be82010-05-06 00:08:46 +00006408 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006409}
6410#endif /* HAVE_SYMLINK */
6411
Brian Curtind40e6f72010-07-08 21:39:08 +00006412#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6413
6414PyDoc_STRVAR(win_readlink__doc__,
6415"readlink(path) -> path\n\n\
6416Return a string representing the path to which the symbolic link points.");
6417
Brian Curtind40e6f72010-07-08 21:39:08 +00006418/* Windows readlink implementation */
6419static PyObject *
6420win_readlink(PyObject *self, PyObject *args)
6421{
6422 wchar_t *path;
6423 DWORD n_bytes_returned;
6424 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006425 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00006426 HANDLE reparse_point_handle;
6427
6428 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6429 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6430 wchar_t *print_name;
6431
6432 if (!PyArg_ParseTuple(args,
Victor Stinnereb5657a2011-09-30 01:44:27 +02006433 "U:readlink",
6434 &po))
6435 return NULL;
6436 path = PyUnicode_AsUnicode(po);
6437 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006438 return NULL;
6439
6440 /* First get a handle to the reparse point */
6441 Py_BEGIN_ALLOW_THREADS
6442 reparse_point_handle = CreateFileW(
6443 path,
6444 0,
6445 0,
6446 0,
6447 OPEN_EXISTING,
6448 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6449 0);
6450 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006451
Brian Curtind40e6f72010-07-08 21:39:08 +00006452 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006453 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006454
Brian Curtind40e6f72010-07-08 21:39:08 +00006455 Py_BEGIN_ALLOW_THREADS
6456 /* New call DeviceIoControl to read the reparse point */
6457 io_result = DeviceIoControl(
6458 reparse_point_handle,
6459 FSCTL_GET_REPARSE_POINT,
6460 0, 0, /* in buffer */
6461 target_buffer, sizeof(target_buffer),
6462 &n_bytes_returned,
6463 0 /* we're not using OVERLAPPED_IO */
6464 );
6465 CloseHandle(reparse_point_handle);
6466 Py_END_ALLOW_THREADS
6467
6468 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006469 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006470
6471 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6472 {
6473 PyErr_SetString(PyExc_ValueError,
6474 "not a symbolic link");
6475 return NULL;
6476 }
Brian Curtin74e45612010-07-09 15:58:59 +00006477 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6478 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6479
6480 result = PyUnicode_FromWideChar(print_name,
6481 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006482 return result;
6483}
6484
6485#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6486
Brian Curtin52173d42010-12-02 18:29:18 +00006487#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtind40e6f72010-07-08 21:39:08 +00006488
6489/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6490static int has_CreateSymbolicLinkW = 0;
6491static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
6492static int
6493check_CreateSymbolicLinkW()
6494{
6495 HINSTANCE hKernel32;
6496 /* only recheck */
6497 if (has_CreateSymbolicLinkW)
6498 return has_CreateSymbolicLinkW;
6499 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00006500 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6501 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00006502 if (Py_CreateSymbolicLinkW)
6503 has_CreateSymbolicLinkW = 1;
6504 return has_CreateSymbolicLinkW;
6505}
6506
6507PyDoc_STRVAR(win_symlink__doc__,
6508"symlink(src, dst, target_is_directory=False)\n\n\
6509Create a symbolic link pointing to src named dst.\n\
6510target_is_directory is required if the target is to be interpreted as\n\
6511a directory.\n\
6512This function requires Windows 6.0 or greater, and raises a\n\
6513NotImplementedError otherwise.");
6514
6515static PyObject *
6516win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
6517{
6518 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
6519 PyObject *src, *dest;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006520 wchar_t *wsrc, *wdest;
Brian Curtind40e6f72010-07-08 21:39:08 +00006521 int target_is_directory = 0;
6522 DWORD res;
6523 WIN32_FILE_ATTRIBUTE_DATA src_info;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006524
Brian Curtind40e6f72010-07-08 21:39:08 +00006525 if (!check_CreateSymbolicLinkW())
6526 {
6527 /* raise NotImplementedError */
6528 return PyErr_Format(PyExc_NotImplementedError,
6529 "CreateSymbolicLinkW not found");
6530 }
6531 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
6532 kwlist, &src, &dest, &target_is_directory))
6533 return NULL;
Brian Curtin3b4499c2010-12-28 14:31:47 +00006534
6535 if (win32_can_symlink == 0)
6536 return PyErr_Format(PyExc_OSError, "symbolic link privilege not held");
6537
Victor Stinnereb5657a2011-09-30 01:44:27 +02006538 if (!convert_to_unicode(&src))
6539 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00006540 if (!convert_to_unicode(&dest)) {
6541 Py_DECREF(src);
6542 return NULL;
6543 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006544
Victor Stinnereb5657a2011-09-30 01:44:27 +02006545 wsrc = PyUnicode_AsUnicode(src);
6546 if (wsrc == NULL)
6547 goto error;
6548 wdest = PyUnicode_AsUnicode(dest);
6549 if (wsrc == NULL)
6550 goto error;
6551
Brian Curtind40e6f72010-07-08 21:39:08 +00006552 /* if src is a directory, ensure target_is_directory==1 */
6553 if(
6554 GetFileAttributesExW(
Victor Stinnereb5657a2011-09-30 01:44:27 +02006555 wsrc, GetFileExInfoStandard, &src_info
Brian Curtind40e6f72010-07-08 21:39:08 +00006556 ))
6557 {
6558 target_is_directory = target_is_directory ||
6559 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
6560 }
6561
6562 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006563 res = Py_CreateSymbolicLinkW(wdest, wsrc, target_is_directory);
Brian Curtind40e6f72010-07-08 21:39:08 +00006564 Py_END_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006565
Brian Curtind40e6f72010-07-08 21:39:08 +00006566 Py_DECREF(src);
6567 Py_DECREF(dest);
6568 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006569 return win32_error_object("symlink", src);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006570
Brian Curtind40e6f72010-07-08 21:39:08 +00006571 Py_INCREF(Py_None);
6572 return Py_None;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006573
6574error:
6575 Py_DECREF(src);
6576 Py_DECREF(dest);
6577 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00006578}
Brian Curtin52173d42010-12-02 18:29:18 +00006579#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006580
6581#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006582#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6583static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006584system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006585{
6586 ULONG value = 0;
6587
6588 Py_BEGIN_ALLOW_THREADS
6589 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6590 Py_END_ALLOW_THREADS
6591
6592 return value;
6593}
6594
6595static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006596posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006597{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006598 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 return Py_BuildValue("ddddd",
6600 (double)0 /* t.tms_utime / HZ */,
6601 (double)0 /* t.tms_stime / HZ */,
6602 (double)0 /* t.tms_cutime / HZ */,
6603 (double)0 /* t.tms_cstime / HZ */,
6604 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006605}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006606#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00006607#define NEED_TICKS_PER_SECOND
6608static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006609static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006610posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006611{
Victor Stinner8c62be82010-05-06 00:08:46 +00006612 struct tms t;
6613 clock_t c;
6614 errno = 0;
6615 c = times(&t);
6616 if (c == (clock_t) -1)
6617 return posix_error();
6618 return Py_BuildValue("ddddd",
6619 (double)t.tms_utime / ticks_per_second,
6620 (double)t.tms_stime / ticks_per_second,
6621 (double)t.tms_cutime / ticks_per_second,
6622 (double)t.tms_cstime / ticks_per_second,
6623 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006624}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006625#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006626#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006627
6628
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006629#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006630#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006631static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006632posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006633{
Victor Stinner8c62be82010-05-06 00:08:46 +00006634 FILETIME create, exit, kernel, user;
6635 HANDLE hProc;
6636 hProc = GetCurrentProcess();
6637 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6638 /* The fields of a FILETIME structure are the hi and lo part
6639 of a 64-bit value expressed in 100 nanosecond units.
6640 1e7 is one second in such units; 1e-7 the inverse.
6641 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6642 */
6643 return Py_BuildValue(
6644 "ddddd",
6645 (double)(user.dwHighDateTime*429.4967296 +
6646 user.dwLowDateTime*1e-7),
6647 (double)(kernel.dwHighDateTime*429.4967296 +
6648 kernel.dwLowDateTime*1e-7),
6649 (double)0,
6650 (double)0,
6651 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006652}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006653#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006654
6655#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006656PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006657"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006658Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006659#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006660
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006661
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006662#ifdef HAVE_GETSID
6663PyDoc_STRVAR(posix_getsid__doc__,
6664"getsid(pid) -> sid\n\n\
6665Call the system call getsid().");
6666
6667static PyObject *
6668posix_getsid(PyObject *self, PyObject *args)
6669{
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 pid_t pid;
6671 int sid;
6672 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6673 return NULL;
6674 sid = getsid(pid);
6675 if (sid < 0)
6676 return posix_error();
6677 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006678}
6679#endif /* HAVE_GETSID */
6680
6681
Guido van Rossumb6775db1994-08-01 11:34:53 +00006682#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006683PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006684"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006685Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006686
Barry Warsaw53699e91996-12-10 23:23:01 +00006687static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006688posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006689{
Victor Stinner8c62be82010-05-06 00:08:46 +00006690 if (setsid() < 0)
6691 return posix_error();
6692 Py_INCREF(Py_None);
6693 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006694}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006695#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006696
Guido van Rossumb6775db1994-08-01 11:34:53 +00006697#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006698PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006699"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006700Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006701
Barry Warsaw53699e91996-12-10 23:23:01 +00006702static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006703posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006704{
Victor Stinner8c62be82010-05-06 00:08:46 +00006705 pid_t pid;
6706 int pgrp;
6707 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
6708 return NULL;
6709 if (setpgid(pid, pgrp) < 0)
6710 return posix_error();
6711 Py_INCREF(Py_None);
6712 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006713}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006714#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006715
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006716
Guido van Rossumb6775db1994-08-01 11:34:53 +00006717#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006718PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006719"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006720Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006721
Barry Warsaw53699e91996-12-10 23:23:01 +00006722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006723posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006724{
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 int fd;
6726 pid_t pgid;
6727 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6728 return NULL;
6729 pgid = tcgetpgrp(fd);
6730 if (pgid < 0)
6731 return posix_error();
6732 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006733}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006734#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006735
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006736
Guido van Rossumb6775db1994-08-01 11:34:53 +00006737#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006738PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006739"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006740Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006741
Barry Warsaw53699e91996-12-10 23:23:01 +00006742static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006743posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006744{
Victor Stinner8c62be82010-05-06 00:08:46 +00006745 int fd;
6746 pid_t pgid;
6747 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
6748 return NULL;
6749 if (tcsetpgrp(fd, pgid) < 0)
6750 return posix_error();
6751 Py_INCREF(Py_None);
6752 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006753}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006754#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006755
Guido van Rossum687dd131993-05-17 08:34:16 +00006756/* Functions acting on file descriptors */
6757
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006758PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006759"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006760Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006761
Barry Warsaw53699e91996-12-10 23:23:01 +00006762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006763posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006764{
Victor Stinner8c62be82010-05-06 00:08:46 +00006765 PyObject *ofile;
6766 char *file;
6767 int flag;
6768 int mode = 0777;
6769 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006770
6771#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006772 PyObject *po;
Victor Stinner26de69d2011-06-17 15:15:38 +02006773 if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02006774 wchar_t *wpath = PyUnicode_AsUnicode(po);
6775 if (wpath == NULL)
6776 return NULL;
6777
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006779 fd = _wopen(wpath, flag, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00006780 Py_END_ALLOW_THREADS
6781 if (fd < 0)
6782 return posix_error();
6783 return PyLong_FromLong((long)fd);
6784 }
6785 /* Drop the argument parsing error as narrow strings
6786 are also valid. */
6787 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006788#endif
6789
Victor Stinner26de69d2011-06-17 15:15:38 +02006790 if (!PyArg_ParseTuple(args, "O&i|i:open",
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 PyUnicode_FSConverter, &ofile,
6792 &flag, &mode))
6793 return NULL;
6794 file = PyBytes_AsString(ofile);
6795 Py_BEGIN_ALLOW_THREADS
6796 fd = open(file, flag, mode);
6797 Py_END_ALLOW_THREADS
6798 if (fd < 0)
6799 return posix_error_with_allocated_filename(ofile);
6800 Py_DECREF(ofile);
6801 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006802}
6803
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006804
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006805PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006806"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006807Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006808
Barry Warsaw53699e91996-12-10 23:23:01 +00006809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006810posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006811{
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 int fd, res;
6813 if (!PyArg_ParseTuple(args, "i:close", &fd))
6814 return NULL;
6815 if (!_PyVerify_fd(fd))
6816 return posix_error();
6817 Py_BEGIN_ALLOW_THREADS
6818 res = close(fd);
6819 Py_END_ALLOW_THREADS
6820 if (res < 0)
6821 return posix_error();
6822 Py_INCREF(Py_None);
6823 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006824}
6825
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006826
Victor Stinner8c62be82010-05-06 00:08:46 +00006827PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00006828"closerange(fd_low, fd_high)\n\n\
6829Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6830
6831static PyObject *
6832posix_closerange(PyObject *self, PyObject *args)
6833{
Victor Stinner8c62be82010-05-06 00:08:46 +00006834 int fd_from, fd_to, i;
6835 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6836 return NULL;
6837 Py_BEGIN_ALLOW_THREADS
6838 for (i = fd_from; i < fd_to; i++)
6839 if (_PyVerify_fd(i))
6840 close(i);
6841 Py_END_ALLOW_THREADS
6842 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00006843}
6844
6845
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006846PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006847"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006848Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006849
Barry Warsaw53699e91996-12-10 23:23:01 +00006850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006851posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006852{
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 int fd;
6854 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6855 return NULL;
6856 if (!_PyVerify_fd(fd))
6857 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006858 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 if (fd < 0)
6860 return posix_error();
6861 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006862}
6863
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006864
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006865PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006866"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006867Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006868
Barry Warsaw53699e91996-12-10 23:23:01 +00006869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006870posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006871{
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 int fd, fd2, res;
6873 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6874 return NULL;
6875 if (!_PyVerify_fd_dup2(fd, fd2))
6876 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 if (res < 0)
6879 return posix_error();
6880 Py_INCREF(Py_None);
6881 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006882}
6883
Ross Lagerwall7807c352011-03-17 20:20:30 +02006884#ifdef HAVE_LOCKF
6885PyDoc_STRVAR(posix_lockf__doc__,
6886"lockf(fd, cmd, len)\n\n\
6887Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
6888fd is an open file descriptor.\n\
6889cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
6890F_TEST.\n\
6891len specifies the section of the file to lock.");
6892
6893static PyObject *
6894posix_lockf(PyObject *self, PyObject *args)
6895{
6896 int fd, cmd, res;
6897 off_t len;
6898 if (!PyArg_ParseTuple(args, "iiO&:lockf",
6899 &fd, &cmd, _parse_off_t, &len))
6900 return NULL;
6901
6902 Py_BEGIN_ALLOW_THREADS
6903 res = lockf(fd, cmd, len);
6904 Py_END_ALLOW_THREADS
6905
6906 if (res < 0)
6907 return posix_error();
6908
6909 Py_RETURN_NONE;
6910}
6911#endif
6912
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006913
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006914PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006915"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006916Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006917
Barry Warsaw53699e91996-12-10 23:23:01 +00006918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006919posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006920{
Victor Stinner8c62be82010-05-06 00:08:46 +00006921 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006922#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00006923 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006924#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006926#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02006927 PyObject *posobj;
6928 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00006929 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006930#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6932 switch (how) {
6933 case 0: how = SEEK_SET; break;
6934 case 1: how = SEEK_CUR; break;
6935 case 2: how = SEEK_END; break;
6936 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006937#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006938
Ross Lagerwall8e749672011-03-17 21:54:07 +02006939#if !defined(HAVE_LARGEFILE_SUPPORT)
6940 pos = PyLong_AsLong(posobj);
6941#else
6942 pos = PyLong_AsLongLong(posobj);
6943#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 if (PyErr_Occurred())
6945 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006946
Victor Stinner8c62be82010-05-06 00:08:46 +00006947 if (!_PyVerify_fd(fd))
6948 return posix_error();
6949 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006950#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00006951 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006952#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006954#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 Py_END_ALLOW_THREADS
6956 if (res < 0)
6957 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006958
6959#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006960 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006961#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006962 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006963#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006964}
6965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006966
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006967PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006968"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006969Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006970
Barry Warsaw53699e91996-12-10 23:23:01 +00006971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006972posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006973{
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 int fd, size;
6975 Py_ssize_t n;
6976 PyObject *buffer;
6977 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6978 return NULL;
6979 if (size < 0) {
6980 errno = EINVAL;
6981 return posix_error();
6982 }
6983 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
6984 if (buffer == NULL)
6985 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00006986 if (!_PyVerify_fd(fd)) {
6987 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00006988 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00006989 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006990 Py_BEGIN_ALLOW_THREADS
6991 n = read(fd, PyBytes_AS_STRING(buffer), size);
6992 Py_END_ALLOW_THREADS
6993 if (n < 0) {
6994 Py_DECREF(buffer);
6995 return posix_error();
6996 }
6997 if (n != size)
6998 _PyBytes_Resize(&buffer, n);
6999 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007000}
7001
Ross Lagerwall7807c352011-03-17 20:20:30 +02007002#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7003 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007004static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007005iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7006{
7007 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007008 Py_ssize_t blen, total = 0;
7009
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007010 *iov = PyMem_New(struct iovec, cnt);
7011 if (*iov == NULL) {
7012 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007013 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007014 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007015
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007016 *buf = PyMem_New(Py_buffer, cnt);
7017 if (*buf == NULL) {
7018 PyMem_Del(*iov);
7019 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007020 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007021 }
7022
7023 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007024 PyObject *item = PySequence_GetItem(seq, i);
7025 if (item == NULL)
7026 goto fail;
7027 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7028 Py_DECREF(item);
7029 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007030 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007031 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007032 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007033 blen = (*buf)[i].len;
7034 (*iov)[i].iov_len = blen;
7035 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007036 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007037 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007038
7039fail:
7040 PyMem_Del(*iov);
7041 for (j = 0; j < i; j++) {
7042 PyBuffer_Release(&(*buf)[j]);
7043 }
7044 PyMem_Del(*buf);
7045 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007046}
7047
7048static void
7049iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7050{
7051 int i;
7052 PyMem_Del(iov);
7053 for (i = 0; i < cnt; i++) {
7054 PyBuffer_Release(&buf[i]);
7055 }
7056 PyMem_Del(buf);
7057}
7058#endif
7059
Ross Lagerwall7807c352011-03-17 20:20:30 +02007060#ifdef HAVE_READV
7061PyDoc_STRVAR(posix_readv__doc__,
7062"readv(fd, buffers) -> bytesread\n\n\
7063Read from a file descriptor into a number of writable buffers. buffers\n\
7064is an arbitrary sequence of writable buffers.\n\
7065Returns the total number of bytes read.");
7066
7067static PyObject *
7068posix_readv(PyObject *self, PyObject *args)
7069{
7070 int fd, cnt;
7071 Py_ssize_t n;
7072 PyObject *seq;
7073 struct iovec *iov;
7074 Py_buffer *buf;
7075
7076 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7077 return NULL;
7078 if (!PySequence_Check(seq)) {
7079 PyErr_SetString(PyExc_TypeError,
7080 "readv() arg 2 must be a sequence");
7081 return NULL;
7082 }
7083 cnt = PySequence_Size(seq);
7084
7085 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7086 return NULL;
7087
7088 Py_BEGIN_ALLOW_THREADS
7089 n = readv(fd, iov, cnt);
7090 Py_END_ALLOW_THREADS
7091
7092 iov_cleanup(iov, buf, cnt);
7093 return PyLong_FromSsize_t(n);
7094}
7095#endif
7096
7097#ifdef HAVE_PREAD
7098PyDoc_STRVAR(posix_pread__doc__,
7099"pread(fd, buffersize, offset) -> string\n\n\
7100Read from a file descriptor, fd, at a position of offset. It will read up\n\
7101to buffersize number of bytes. The file offset remains unchanged.");
7102
7103static PyObject *
7104posix_pread(PyObject *self, PyObject *args)
7105{
7106 int fd, size;
7107 off_t offset;
7108 Py_ssize_t n;
7109 PyObject *buffer;
7110 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7111 return NULL;
7112
7113 if (size < 0) {
7114 errno = EINVAL;
7115 return posix_error();
7116 }
7117 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7118 if (buffer == NULL)
7119 return NULL;
7120 if (!_PyVerify_fd(fd)) {
7121 Py_DECREF(buffer);
7122 return posix_error();
7123 }
7124 Py_BEGIN_ALLOW_THREADS
7125 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7126 Py_END_ALLOW_THREADS
7127 if (n < 0) {
7128 Py_DECREF(buffer);
7129 return posix_error();
7130 }
7131 if (n != size)
7132 _PyBytes_Resize(&buffer, n);
7133 return buffer;
7134}
7135#endif
7136
7137PyDoc_STRVAR(posix_write__doc__,
7138"write(fd, string) -> byteswritten\n\n\
7139Write a string to a file descriptor.");
7140
7141static PyObject *
7142posix_write(PyObject *self, PyObject *args)
7143{
7144 Py_buffer pbuf;
7145 int fd;
7146 Py_ssize_t size, len;
7147
7148 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7149 return NULL;
7150 if (!_PyVerify_fd(fd)) {
7151 PyBuffer_Release(&pbuf);
7152 return posix_error();
7153 }
7154 len = pbuf.len;
7155 Py_BEGIN_ALLOW_THREADS
7156#if defined(MS_WIN64) || defined(MS_WINDOWS)
7157 if (len > INT_MAX)
7158 len = INT_MAX;
7159 size = write(fd, pbuf.buf, (int)len);
7160#else
7161 size = write(fd, pbuf.buf, len);
7162#endif
7163 Py_END_ALLOW_THREADS
7164 PyBuffer_Release(&pbuf);
7165 if (size < 0)
7166 return posix_error();
7167 return PyLong_FromSsize_t(size);
7168}
7169
7170#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007171PyDoc_STRVAR(posix_sendfile__doc__,
7172"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7173sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7174 -> byteswritten\n\
7175Copy nbytes bytes from file descriptor in to file descriptor out.");
7176
7177static PyObject *
7178posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7179{
7180 int in, out;
7181 Py_ssize_t ret;
7182 off_t offset;
7183
7184#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7185#ifndef __APPLE__
7186 Py_ssize_t len;
7187#endif
7188 PyObject *headers = NULL, *trailers = NULL;
7189 Py_buffer *hbuf, *tbuf;
7190 off_t sbytes;
7191 struct sf_hdtr sf;
7192 int flags = 0;
7193 sf.headers = NULL;
7194 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007195 static char *keywords[] = {"out", "in",
7196 "offset", "count",
7197 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007198
7199#ifdef __APPLE__
7200 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007201 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007202#else
7203 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007204 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007205#endif
7206 &headers, &trailers, &flags))
7207 return NULL;
7208 if (headers != NULL) {
7209 if (!PySequence_Check(headers)) {
7210 PyErr_SetString(PyExc_TypeError,
7211 "sendfile() headers must be a sequence or None");
7212 return NULL;
7213 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007214 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007215 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007216 if (sf.hdr_cnt > 0 &&
7217 !(i = iov_setup(&(sf.headers), &hbuf,
7218 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007219 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007220#ifdef __APPLE__
7221 sbytes += i;
7222#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007223 }
7224 }
7225 if (trailers != NULL) {
7226 if (!PySequence_Check(trailers)) {
7227 PyErr_SetString(PyExc_TypeError,
7228 "sendfile() trailers must be a sequence or None");
7229 return NULL;
7230 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007231 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007232 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007233 if (sf.trl_cnt > 0 &&
7234 !(i = iov_setup(&(sf.trailers), &tbuf,
7235 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007236 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007237#ifdef __APPLE__
7238 sbytes += i;
7239#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007240 }
7241 }
7242
7243 Py_BEGIN_ALLOW_THREADS
7244#ifdef __APPLE__
7245 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7246#else
7247 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7248#endif
7249 Py_END_ALLOW_THREADS
7250
7251 if (sf.headers != NULL)
7252 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7253 if (sf.trailers != NULL)
7254 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7255
7256 if (ret < 0) {
7257 if ((errno == EAGAIN) || (errno == EBUSY)) {
7258 if (sbytes != 0) {
7259 // some data has been sent
7260 goto done;
7261 }
7262 else {
7263 // no data has been sent; upper application is supposed
7264 // to retry on EAGAIN or EBUSY
7265 return posix_error();
7266 }
7267 }
7268 return posix_error();
7269 }
7270 goto done;
7271
7272done:
7273 #if !defined(HAVE_LARGEFILE_SUPPORT)
7274 return Py_BuildValue("l", sbytes);
7275 #else
7276 return Py_BuildValue("L", sbytes);
7277 #endif
7278
7279#else
7280 Py_ssize_t count;
7281 PyObject *offobj;
7282 static char *keywords[] = {"out", "in",
7283 "offset", "count", NULL};
7284 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7285 keywords, &out, &in, &offobj, &count))
7286 return NULL;
7287#ifdef linux
7288 if (offobj == Py_None) {
7289 Py_BEGIN_ALLOW_THREADS
7290 ret = sendfile(out, in, NULL, count);
7291 Py_END_ALLOW_THREADS
7292 if (ret < 0)
7293 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007294 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007295 }
7296#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007297 if (!_parse_off_t(offobj, &offset))
7298 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007299 Py_BEGIN_ALLOW_THREADS
7300 ret = sendfile(out, in, &offset, count);
7301 Py_END_ALLOW_THREADS
7302 if (ret < 0)
7303 return posix_error();
7304 return Py_BuildValue("n", ret);
7305#endif
7306}
7307#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007308
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007309PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007310"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007311Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007312
Barry Warsaw53699e91996-12-10 23:23:01 +00007313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007314posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007315{
Victor Stinner8c62be82010-05-06 00:08:46 +00007316 int fd;
7317 STRUCT_STAT st;
7318 int res;
7319 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
7320 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007321#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007322 /* on OpenVMS we must ensure that all bytes are written to the file */
7323 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007324#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007325 if (!_PyVerify_fd(fd))
7326 return posix_error();
7327 Py_BEGIN_ALLOW_THREADS
7328 res = FSTAT(fd, &st);
7329 Py_END_ALLOW_THREADS
7330 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007331#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007332 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00007333#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007334 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007335#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007336 }
Tim Peters5aa91602002-01-30 05:46:57 +00007337
Victor Stinner8c62be82010-05-06 00:08:46 +00007338 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007339}
7340
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007341PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007342"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007343Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007344connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007345
7346static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007347posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007348{
Victor Stinner8c62be82010-05-06 00:08:46 +00007349 int fd;
7350 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7351 return NULL;
7352 if (!_PyVerify_fd(fd))
7353 return PyBool_FromLong(0);
7354 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007355}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007356
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007357#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007358PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007359"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007360Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007361
Barry Warsaw53699e91996-12-10 23:23:01 +00007362static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007363posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007364{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007365#if defined(PYOS_OS2)
7366 HFILE read, write;
7367 APIRET rc;
7368
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007369 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007370 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007371 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007372
7373 return Py_BuildValue("(ii)", read, write);
7374#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007375#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007376 int fds[2];
7377 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007378 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007379 if (res != 0)
7380 return posix_error();
7381 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007382#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007383 HANDLE read, write;
7384 int read_fd, write_fd;
7385 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007386 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007387 if (!ok)
7388 return win32_error("CreatePipe", NULL);
7389 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7390 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7391 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007392#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007393#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007394}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007395#endif /* HAVE_PIPE */
7396
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007397#ifdef HAVE_PIPE2
7398PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007399"pipe2(flags) -> (read_end, write_end)\n\n\
7400Create a pipe with flags set atomically.\n\
7401flags can be constructed by ORing together one or more of these values:\n\
7402O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007403");
7404
7405static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007406posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007407{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007408 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007409 int fds[2];
7410 int res;
7411
Charles-François Natali368f34b2011-06-06 19:49:47 +02007412 flags = PyLong_AsLong(arg);
7413 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007414 return NULL;
7415
7416 res = pipe2(fds, flags);
7417 if (res != 0)
7418 return posix_error();
7419 return Py_BuildValue("(ii)", fds[0], fds[1]);
7420}
7421#endif /* HAVE_PIPE2 */
7422
Ross Lagerwall7807c352011-03-17 20:20:30 +02007423#ifdef HAVE_WRITEV
7424PyDoc_STRVAR(posix_writev__doc__,
7425"writev(fd, buffers) -> byteswritten\n\n\
7426Write the contents of buffers to a file descriptor, where buffers is an\n\
7427arbitrary sequence of buffers.\n\
7428Returns the total bytes written.");
7429
7430static PyObject *
7431posix_writev(PyObject *self, PyObject *args)
7432{
7433 int fd, cnt;
7434 Py_ssize_t res;
7435 PyObject *seq;
7436 struct iovec *iov;
7437 Py_buffer *buf;
7438 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7439 return NULL;
7440 if (!PySequence_Check(seq)) {
7441 PyErr_SetString(PyExc_TypeError,
7442 "writev() arg 2 must be a sequence");
7443 return NULL;
7444 }
7445 cnt = PySequence_Size(seq);
7446
7447 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7448 return NULL;
7449 }
7450
7451 Py_BEGIN_ALLOW_THREADS
7452 res = writev(fd, iov, cnt);
7453 Py_END_ALLOW_THREADS
7454
7455 iov_cleanup(iov, buf, cnt);
7456 return PyLong_FromSsize_t(res);
7457}
7458#endif
7459
7460#ifdef HAVE_PWRITE
7461PyDoc_STRVAR(posix_pwrite__doc__,
7462"pwrite(fd, string, offset) -> byteswritten\n\n\
7463Write string to a file descriptor, fd, from offset, leaving the file\n\
7464offset unchanged.");
7465
7466static PyObject *
7467posix_pwrite(PyObject *self, PyObject *args)
7468{
7469 Py_buffer pbuf;
7470 int fd;
7471 off_t offset;
7472 Py_ssize_t size;
7473
7474 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7475 return NULL;
7476
7477 if (!_PyVerify_fd(fd)) {
7478 PyBuffer_Release(&pbuf);
7479 return posix_error();
7480 }
7481 Py_BEGIN_ALLOW_THREADS
7482 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7483 Py_END_ALLOW_THREADS
7484 PyBuffer_Release(&pbuf);
7485 if (size < 0)
7486 return posix_error();
7487 return PyLong_FromSsize_t(size);
7488}
7489#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007490
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007491#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007492PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007493"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007494Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007495
Barry Warsaw53699e91996-12-10 23:23:01 +00007496static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007497posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007498{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007499 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007500 char *filename;
7501 int mode = 0666;
7502 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007503 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
7504 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00007505 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007506 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007507 Py_BEGIN_ALLOW_THREADS
7508 res = mkfifo(filename, mode);
7509 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007510 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007511 if (res < 0)
7512 return posix_error();
7513 Py_INCREF(Py_None);
7514 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007515}
7516#endif
7517
7518
Neal Norwitz11690112002-07-30 01:08:28 +00007519#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007520PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007521"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007522Create a filesystem node (file, device special file or named pipe)\n\
7523named filename. mode specifies both the permissions to use and the\n\
7524type of node to be created, being combined (bitwise OR) with one of\n\
7525S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007526device defines the newly created device special file (probably using\n\
7527os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007528
7529
7530static PyObject *
7531posix_mknod(PyObject *self, PyObject *args)
7532{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007533 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007534 char *filename;
7535 int mode = 0600;
7536 int device = 0;
7537 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007538 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
7539 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00007540 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007541 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007542 Py_BEGIN_ALLOW_THREADS
7543 res = mknod(filename, mode, device);
7544 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007545 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007546 if (res < 0)
7547 return posix_error();
7548 Py_INCREF(Py_None);
7549 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007550}
7551#endif
7552
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007553#ifdef HAVE_DEVICE_MACROS
7554PyDoc_STRVAR(posix_major__doc__,
7555"major(device) -> major number\n\
7556Extracts a device major number from a raw device number.");
7557
7558static PyObject *
7559posix_major(PyObject *self, PyObject *args)
7560{
Victor Stinner8c62be82010-05-06 00:08:46 +00007561 int device;
7562 if (!PyArg_ParseTuple(args, "i:major", &device))
7563 return NULL;
7564 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007565}
7566
7567PyDoc_STRVAR(posix_minor__doc__,
7568"minor(device) -> minor number\n\
7569Extracts a device minor number from a raw device number.");
7570
7571static PyObject *
7572posix_minor(PyObject *self, PyObject *args)
7573{
Victor Stinner8c62be82010-05-06 00:08:46 +00007574 int device;
7575 if (!PyArg_ParseTuple(args, "i:minor", &device))
7576 return NULL;
7577 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007578}
7579
7580PyDoc_STRVAR(posix_makedev__doc__,
7581"makedev(major, minor) -> device number\n\
7582Composes a raw device number from the major and minor device numbers.");
7583
7584static PyObject *
7585posix_makedev(PyObject *self, PyObject *args)
7586{
Victor Stinner8c62be82010-05-06 00:08:46 +00007587 int major, minor;
7588 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7589 return NULL;
7590 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007591}
7592#endif /* device macros */
7593
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007594
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007595#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007596PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007597"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007598Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007599
Barry Warsaw53699e91996-12-10 23:23:01 +00007600static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007601posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007602{
Victor Stinner8c62be82010-05-06 00:08:46 +00007603 int fd;
7604 off_t length;
7605 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007606
Ross Lagerwall7807c352011-03-17 20:20:30 +02007607 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007608 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007609
Victor Stinner8c62be82010-05-06 00:08:46 +00007610 Py_BEGIN_ALLOW_THREADS
7611 res = ftruncate(fd, length);
7612 Py_END_ALLOW_THREADS
7613 if (res < 0)
7614 return posix_error();
7615 Py_INCREF(Py_None);
7616 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007617}
7618#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007619
Ross Lagerwall7807c352011-03-17 20:20:30 +02007620#ifdef HAVE_TRUNCATE
7621PyDoc_STRVAR(posix_truncate__doc__,
7622"truncate(path, length)\n\n\
7623Truncate the file given by path to length bytes.");
7624
7625static PyObject *
7626posix_truncate(PyObject *self, PyObject *args)
7627{
7628 PyObject *opath;
7629 const char *path;
7630 off_t length;
7631 int res;
7632
7633 if (!PyArg_ParseTuple(args, "O&O&:truncate",
7634 PyUnicode_FSConverter, &opath, _parse_off_t, &length))
7635 return NULL;
7636 path = PyBytes_AsString(opath);
7637
7638 Py_BEGIN_ALLOW_THREADS
7639 res = truncate(path, length);
7640 Py_END_ALLOW_THREADS
7641 Py_DECREF(opath);
7642 if (res < 0)
7643 return posix_error();
7644 Py_RETURN_NONE;
7645}
7646#endif
7647
7648#ifdef HAVE_POSIX_FALLOCATE
7649PyDoc_STRVAR(posix_posix_fallocate__doc__,
7650"posix_fallocate(fd, offset, len)\n\n\
7651Ensures that enough disk space is allocated for the file specified by fd\n\
7652starting from offset and continuing for len bytes.");
7653
7654static PyObject *
7655posix_posix_fallocate(PyObject *self, PyObject *args)
7656{
7657 off_t len, offset;
7658 int res, fd;
7659
7660 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
7661 &fd, _parse_off_t, &offset, _parse_off_t, &len))
7662 return NULL;
7663
7664 Py_BEGIN_ALLOW_THREADS
7665 res = posix_fallocate(fd, offset, len);
7666 Py_END_ALLOW_THREADS
7667 if (res != 0) {
7668 errno = res;
7669 return posix_error();
7670 }
7671 Py_RETURN_NONE;
7672}
7673#endif
7674
7675#ifdef HAVE_POSIX_FADVISE
7676PyDoc_STRVAR(posix_posix_fadvise__doc__,
7677"posix_fadvise(fd, offset, len, advice)\n\n\
7678Announces an intention to access data in a specific pattern thus allowing\n\
7679the kernel to make optimizations.\n\
7680The advice applies to the region of the file specified by fd starting at\n\
7681offset and continuing for len bytes.\n\
7682advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
7683POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
7684POSIX_FADV_DONTNEED.");
7685
7686static PyObject *
7687posix_posix_fadvise(PyObject *self, PyObject *args)
7688{
7689 off_t len, offset;
7690 int res, fd, advice;
7691
7692 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
7693 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
7694 return NULL;
7695
7696 Py_BEGIN_ALLOW_THREADS
7697 res = posix_fadvise(fd, offset, len, advice);
7698 Py_END_ALLOW_THREADS
7699 if (res != 0) {
7700 errno = res;
7701 return posix_error();
7702 }
7703 Py_RETURN_NONE;
7704}
7705#endif
7706
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007707#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007708PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007709"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007710Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007711
Fred Drake762e2061999-08-26 17:23:54 +00007712/* Save putenv() parameters as values here, so we can collect them when they
7713 * get re-set with another call for the same key. */
7714static PyObject *posix_putenv_garbage;
7715
Tim Peters5aa91602002-01-30 05:46:57 +00007716static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007717posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007718{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007719#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007720 wchar_t *s1, *s2;
7721 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007722#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007723 PyObject *os1, *os2;
7724 char *s1, *s2;
7725 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007726#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007727 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007729
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007730#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 if (!PyArg_ParseTuple(args,
7732 "uu:putenv",
7733 &s1, &s2))
7734 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00007735#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007736 if (!PyArg_ParseTuple(args,
7737 "O&O&:putenv",
7738 PyUnicode_FSConverter, &os1,
7739 PyUnicode_FSConverter, &os2))
7740 return NULL;
7741 s1 = PyBytes_AsString(os1);
7742 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00007743#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007744
7745#if defined(PYOS_OS2)
7746 if (stricmp(s1, "BEGINLIBPATH") == 0) {
7747 APIRET rc;
7748
Guido van Rossumd48f2521997-12-05 22:19:34 +00007749 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00007750 if (rc != NO_ERROR) {
7751 os2_error(rc);
7752 goto error;
7753 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007754
7755 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
7756 APIRET rc;
7757
Guido van Rossumd48f2521997-12-05 22:19:34 +00007758 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00007759 if (rc != NO_ERROR) {
7760 os2_error(rc);
7761 goto error;
7762 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007763 } else {
7764#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007765 /* XXX This can leak memory -- not easy to fix :-( */
7766 /* len includes space for a trailing \0; the size arg to
7767 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007768#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 len = wcslen(s1) + wcslen(s2) + 2;
7770 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007771#else
Victor Stinner84ae1182010-05-06 22:05:07 +00007772 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00007773 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007774#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007775 if (newstr == NULL) {
7776 PyErr_NoMemory();
7777 goto error;
7778 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007779#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007780 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02007781 if (newenv == NULL)
7782 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007783 _snwprintf(newenv, len, L"%s=%s", s1, s2);
7784 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007785 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007786 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007787 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007788#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007789 newenv = PyBytes_AS_STRING(newstr);
7790 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
7791 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007792 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007793 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007795#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007796
Victor Stinner8c62be82010-05-06 00:08:46 +00007797 /* Install the first arg and newstr in posix_putenv_garbage;
7798 * this will cause previous value to be collected. This has to
7799 * happen after the real putenv() call because the old value
7800 * was still accessible until then. */
7801 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00007802#ifdef MS_WINDOWS
7803 PyTuple_GET_ITEM(args, 0),
7804#else
7805 os1,
7806#endif
7807 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007808 /* really not much we can do; just leak */
7809 PyErr_Clear();
7810 }
7811 else {
7812 Py_DECREF(newstr);
7813 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007814
7815#if defined(PYOS_OS2)
7816 }
7817#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007818
Martin v. Löwis011e8422009-05-05 04:43:17 +00007819#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007820 Py_DECREF(os1);
7821 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00007822#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007823 Py_RETURN_NONE;
7824
7825error:
7826#ifndef MS_WINDOWS
7827 Py_DECREF(os1);
7828 Py_DECREF(os2);
7829#endif
7830 Py_XDECREF(newstr);
7831 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007832}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007833#endif /* putenv */
7834
Guido van Rossumc524d952001-10-19 01:31:59 +00007835#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007836PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007837"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007838Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007839
7840static PyObject *
7841posix_unsetenv(PyObject *self, PyObject *args)
7842{
Victor Stinner84ae1182010-05-06 22:05:07 +00007843#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007844 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00007845
Victor Stinner8c62be82010-05-06 00:08:46 +00007846 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7847 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00007848#else
7849 PyObject *os1;
7850 char *s1;
7851
7852 if (!PyArg_ParseTuple(args, "O&:unsetenv",
7853 PyUnicode_FSConverter, &os1))
7854 return NULL;
7855 s1 = PyBytes_AsString(os1);
7856#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007857
Victor Stinner8c62be82010-05-06 00:08:46 +00007858 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00007859
Victor Stinner8c62be82010-05-06 00:08:46 +00007860 /* Remove the key from posix_putenv_garbage;
7861 * this will cause it to be collected. This has to
7862 * happen after the real unsetenv() call because the
7863 * old value was still accessible until then.
7864 */
7865 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00007866#ifdef MS_WINDOWS
7867 PyTuple_GET_ITEM(args, 0)
7868#else
7869 os1
7870#endif
7871 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 /* really not much we can do; just leak */
7873 PyErr_Clear();
7874 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007875
Victor Stinner84ae1182010-05-06 22:05:07 +00007876#ifndef MS_WINDOWS
7877 Py_DECREF(os1);
7878#endif
7879 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00007880}
7881#endif /* unsetenv */
7882
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007883PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007884"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007885Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007886
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007887static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007888posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007889{
Victor Stinner8c62be82010-05-06 00:08:46 +00007890 int code;
7891 char *message;
7892 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7893 return NULL;
7894 message = strerror(code);
7895 if (message == NULL) {
7896 PyErr_SetString(PyExc_ValueError,
7897 "strerror() argument out of range");
7898 return NULL;
7899 }
7900 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007901}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007902
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007903
Guido van Rossumc9641791998-08-04 15:26:23 +00007904#ifdef HAVE_SYS_WAIT_H
7905
Fred Drake106c1a02002-04-23 15:58:02 +00007906#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007907PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007908"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007909Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007910
7911static PyObject *
7912posix_WCOREDUMP(PyObject *self, PyObject *args)
7913{
Victor Stinner8c62be82010-05-06 00:08:46 +00007914 WAIT_TYPE status;
7915 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007916
Victor Stinner8c62be82010-05-06 00:08:46 +00007917 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7918 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007919
Victor Stinner8c62be82010-05-06 00:08:46 +00007920 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007921}
7922#endif /* WCOREDUMP */
7923
7924#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007925PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007926"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007927Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007928job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007929
7930static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007931posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007932{
Victor Stinner8c62be82010-05-06 00:08:46 +00007933 WAIT_TYPE status;
7934 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007935
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7937 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007938
Victor Stinner8c62be82010-05-06 00:08:46 +00007939 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007940}
7941#endif /* WIFCONTINUED */
7942
Guido van Rossumc9641791998-08-04 15:26:23 +00007943#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007944PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007945"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007946Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007947
7948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007949posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007950{
Victor Stinner8c62be82010-05-06 00:08:46 +00007951 WAIT_TYPE status;
7952 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007953
Victor Stinner8c62be82010-05-06 00:08:46 +00007954 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7955 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007956
Victor Stinner8c62be82010-05-06 00:08:46 +00007957 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007958}
7959#endif /* WIFSTOPPED */
7960
7961#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007962PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007963"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007964Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007965
7966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007967posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007968{
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 WAIT_TYPE status;
7970 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007971
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7973 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007974
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007976}
7977#endif /* WIFSIGNALED */
7978
7979#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007980PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007981"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007982Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007983system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007984
7985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007986posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007987{
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 WAIT_TYPE status;
7989 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007990
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7992 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007993
Victor Stinner8c62be82010-05-06 00:08:46 +00007994 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007995}
7996#endif /* WIFEXITED */
7997
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007998#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007999PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008000"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008001Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008002
8003static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008004posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008005{
Victor Stinner8c62be82010-05-06 00:08:46 +00008006 WAIT_TYPE status;
8007 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008008
Victor Stinner8c62be82010-05-06 00:08:46 +00008009 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8010 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008011
Victor Stinner8c62be82010-05-06 00:08:46 +00008012 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008013}
8014#endif /* WEXITSTATUS */
8015
8016#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008017PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008018"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008019Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008020value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008021
8022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008023posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008024{
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 WAIT_TYPE status;
8026 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008027
Victor Stinner8c62be82010-05-06 00:08:46 +00008028 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8029 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008030
Victor Stinner8c62be82010-05-06 00:08:46 +00008031 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008032}
8033#endif /* WTERMSIG */
8034
8035#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008036PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008037"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008038Return the signal that stopped the process that provided\n\
8039the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008040
8041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008042posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008043{
Victor Stinner8c62be82010-05-06 00:08:46 +00008044 WAIT_TYPE status;
8045 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008046
Victor Stinner8c62be82010-05-06 00:08:46 +00008047 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8048 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008049
Victor Stinner8c62be82010-05-06 00:08:46 +00008050 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008051}
8052#endif /* WSTOPSIG */
8053
8054#endif /* HAVE_SYS_WAIT_H */
8055
8056
Thomas Wouters477c8d52006-05-27 19:21:47 +00008057#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008058#ifdef _SCO_DS
8059/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8060 needed definitions in sys/statvfs.h */
8061#define _SVID3
8062#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008063#include <sys/statvfs.h>
8064
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008065static PyObject*
8066_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008067 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8068 if (v == NULL)
8069 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008070
8071#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008072 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8073 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8074 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8075 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8076 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8077 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8078 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8079 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8080 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8081 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008082#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008083 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8084 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8085 PyStructSequence_SET_ITEM(v, 2,
8086 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8087 PyStructSequence_SET_ITEM(v, 3,
8088 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8089 PyStructSequence_SET_ITEM(v, 4,
8090 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8091 PyStructSequence_SET_ITEM(v, 5,
8092 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8093 PyStructSequence_SET_ITEM(v, 6,
8094 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8095 PyStructSequence_SET_ITEM(v, 7,
8096 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8097 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8098 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008099#endif
8100
Victor Stinner8c62be82010-05-06 00:08:46 +00008101 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008102}
8103
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008104PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008105"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008106Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008107
8108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008109posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008110{
Victor Stinner8c62be82010-05-06 00:08:46 +00008111 int fd, res;
8112 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008113
Victor Stinner8c62be82010-05-06 00:08:46 +00008114 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8115 return NULL;
8116 Py_BEGIN_ALLOW_THREADS
8117 res = fstatvfs(fd, &st);
8118 Py_END_ALLOW_THREADS
8119 if (res != 0)
8120 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008121
Victor Stinner8c62be82010-05-06 00:08:46 +00008122 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008123}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008124#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008125
8126
Thomas Wouters477c8d52006-05-27 19:21:47 +00008127#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008128#include <sys/statvfs.h>
8129
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008130PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008131"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008132Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008133
8134static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008135posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008136{
Victor Stinner6fa67772011-09-20 04:04:33 +02008137 PyObject *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008138 int res;
8139 struct statvfs st;
Victor Stinner6fa67772011-09-20 04:04:33 +02008140 if (!PyArg_ParseTuple(args, "O&:statvfs", PyUnicode_FSConverter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00008141 return NULL;
8142 Py_BEGIN_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008143 res = statvfs(PyBytes_AS_STRING(path), &st);
Victor Stinner8c62be82010-05-06 00:08:46 +00008144 Py_END_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008145 if (res != 0) {
8146 posix_error_with_filename(PyBytes_AS_STRING(path));
8147 Py_DECREF(path);
8148 return NULL;
8149 }
8150 Py_DECREF(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008151
Victor Stinner8c62be82010-05-06 00:08:46 +00008152 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008153}
8154#endif /* HAVE_STATVFS */
8155
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008156#ifdef MS_WINDOWS
8157PyDoc_STRVAR(win32__getdiskusage__doc__,
8158"_getdiskusage(path) -> (total, free)\n\n\
8159Return disk usage statistics about the given path as (total, free) tuple.");
8160
8161static PyObject *
8162win32__getdiskusage(PyObject *self, PyObject *args)
8163{
8164 BOOL retval;
8165 ULARGE_INTEGER _, total, free;
8166 LPCTSTR path;
8167
8168 if (! PyArg_ParseTuple(args, "s", &path))
8169 return NULL;
8170
8171 Py_BEGIN_ALLOW_THREADS
8172 retval = GetDiskFreeSpaceEx(path, &_, &total, &free);
8173 Py_END_ALLOW_THREADS
8174 if (retval == 0)
8175 return PyErr_SetFromWindowsErr(0);
8176
8177 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8178}
8179#endif
8180
8181
Fred Drakec9680921999-12-13 16:37:25 +00008182/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8183 * It maps strings representing configuration variable names to
8184 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008185 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008186 * rarely-used constants. There are three separate tables that use
8187 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008188 *
8189 * This code is always included, even if none of the interfaces that
8190 * need it are included. The #if hackery needed to avoid it would be
8191 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008192 */
8193struct constdef {
8194 char *name;
8195 long value;
8196};
8197
Fred Drake12c6e2d1999-12-14 21:25:03 +00008198static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008199conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008200 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008201{
Christian Heimes217cfd12007-12-02 14:31:20 +00008202 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008203 *valuep = PyLong_AS_LONG(arg);
8204 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008205 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008206 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008207 /* look up the value in the table using a binary search */
8208 size_t lo = 0;
8209 size_t mid;
8210 size_t hi = tablesize;
8211 int cmp;
8212 const char *confname;
8213 if (!PyUnicode_Check(arg)) {
8214 PyErr_SetString(PyExc_TypeError,
8215 "configuration names must be strings or integers");
8216 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008217 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008218 confname = _PyUnicode_AsString(arg);
8219 if (confname == NULL)
8220 return 0;
8221 while (lo < hi) {
8222 mid = (lo + hi) / 2;
8223 cmp = strcmp(confname, table[mid].name);
8224 if (cmp < 0)
8225 hi = mid;
8226 else if (cmp > 0)
8227 lo = mid + 1;
8228 else {
8229 *valuep = table[mid].value;
8230 return 1;
8231 }
8232 }
8233 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8234 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008235 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008236}
8237
8238
8239#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8240static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008241#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008242 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008243#endif
8244#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008245 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008246#endif
Fred Drakec9680921999-12-13 16:37:25 +00008247#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008248 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008249#endif
8250#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008251 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008252#endif
8253#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008254 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008255#endif
8256#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008257 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008258#endif
8259#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008260 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008261#endif
8262#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008263 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008264#endif
8265#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008266 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008267#endif
8268#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008269 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008270#endif
8271#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008272 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008273#endif
8274#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008275 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008276#endif
8277#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008278 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008279#endif
8280#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008281 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008282#endif
8283#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008284 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008285#endif
8286#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008287 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008288#endif
8289#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008290 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008291#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008292#ifdef _PC_ACL_ENABLED
8293 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8294#endif
8295#ifdef _PC_MIN_HOLE_SIZE
8296 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8297#endif
8298#ifdef _PC_ALLOC_SIZE_MIN
8299 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8300#endif
8301#ifdef _PC_REC_INCR_XFER_SIZE
8302 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8303#endif
8304#ifdef _PC_REC_MAX_XFER_SIZE
8305 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8306#endif
8307#ifdef _PC_REC_MIN_XFER_SIZE
8308 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8309#endif
8310#ifdef _PC_REC_XFER_ALIGN
8311 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8312#endif
8313#ifdef _PC_SYMLINK_MAX
8314 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8315#endif
8316#ifdef _PC_XATTR_ENABLED
8317 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8318#endif
8319#ifdef _PC_XATTR_EXISTS
8320 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8321#endif
8322#ifdef _PC_TIMESTAMP_RESOLUTION
8323 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8324#endif
Fred Drakec9680921999-12-13 16:37:25 +00008325};
8326
Fred Drakec9680921999-12-13 16:37:25 +00008327static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008328conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008329{
8330 return conv_confname(arg, valuep, posix_constants_pathconf,
8331 sizeof(posix_constants_pathconf)
8332 / sizeof(struct constdef));
8333}
8334#endif
8335
8336#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008337PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008338"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008339Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008340If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008341
8342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008343posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008344{
8345 PyObject *result = NULL;
8346 int name, fd;
8347
Fred Drake12c6e2d1999-12-14 21:25:03 +00008348 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8349 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008350 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008351
Stefan Krah0e803b32010-11-26 16:16:47 +00008352 errno = 0;
8353 limit = fpathconf(fd, name);
8354 if (limit == -1 && errno != 0)
8355 posix_error();
8356 else
8357 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008358 }
8359 return result;
8360}
8361#endif
8362
8363
8364#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008365PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008366"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008367Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008368If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008369
8370static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008371posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008372{
8373 PyObject *result = NULL;
8374 int name;
8375 char *path;
8376
8377 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
8378 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008379 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008380
Victor Stinner8c62be82010-05-06 00:08:46 +00008381 errno = 0;
8382 limit = pathconf(path, name);
8383 if (limit == -1 && errno != 0) {
8384 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008385 /* could be a path or name problem */
8386 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008387 else
Stefan Krah99439262010-11-26 12:58:05 +00008388 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008389 }
8390 else
8391 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008392 }
8393 return result;
8394}
8395#endif
8396
8397#ifdef HAVE_CONFSTR
8398static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008399#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008400 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008401#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008402#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008403 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008404#endif
8405#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008406 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008407#endif
Fred Draked86ed291999-12-15 15:34:33 +00008408#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008410#endif
8411#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008412 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008413#endif
8414#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008415 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008416#endif
8417#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008419#endif
Fred Drakec9680921999-12-13 16:37:25 +00008420#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008421 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008422#endif
8423#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008424 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008425#endif
8426#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008427 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008428#endif
8429#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008430 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008431#endif
8432#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008433 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008434#endif
8435#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008436 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008437#endif
8438#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008439 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008440#endif
8441#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008442 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008443#endif
Fred Draked86ed291999-12-15 15:34:33 +00008444#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008445 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008446#endif
Fred Drakec9680921999-12-13 16:37:25 +00008447#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008448 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008449#endif
Fred Draked86ed291999-12-15 15:34:33 +00008450#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008451 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008452#endif
8453#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008454 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008455#endif
8456#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008457 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008458#endif
8459#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008460 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008461#endif
Fred Drakec9680921999-12-13 16:37:25 +00008462#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008463 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008464#endif
8465#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008466 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008467#endif
8468#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008469 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008470#endif
8471#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008472 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008473#endif
8474#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008475 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008476#endif
8477#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008478 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008479#endif
8480#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008481 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008482#endif
8483#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008484 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008485#endif
8486#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008487 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008488#endif
8489#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008490 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008491#endif
8492#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008493 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008494#endif
8495#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008496 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008497#endif
8498#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008499 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008500#endif
8501#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008502 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008503#endif
8504#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008505 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008506#endif
8507#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008508 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008509#endif
Fred Draked86ed291999-12-15 15:34:33 +00008510#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008511 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008512#endif
8513#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008514 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008515#endif
8516#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008517 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008518#endif
8519#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008520 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008521#endif
8522#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008523 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008524#endif
8525#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008526 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008527#endif
8528#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008529 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008530#endif
8531#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008532 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008533#endif
8534#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008535 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008536#endif
8537#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008538 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008539#endif
8540#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008541 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008542#endif
8543#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008544 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008545#endif
8546#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008547 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008548#endif
Fred Drakec9680921999-12-13 16:37:25 +00008549};
8550
8551static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008552conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008553{
8554 return conv_confname(arg, valuep, posix_constants_confstr,
8555 sizeof(posix_constants_confstr)
8556 / sizeof(struct constdef));
8557}
8558
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008559PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008560"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008561Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008562
8563static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008564posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008565{
8566 PyObject *result = NULL;
8567 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008568 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008569 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008570
Victor Stinnercb043522010-09-10 23:49:04 +00008571 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8572 return NULL;
8573
8574 errno = 0;
8575 len = confstr(name, buffer, sizeof(buffer));
8576 if (len == 0) {
8577 if (errno) {
8578 posix_error();
8579 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008580 }
8581 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008582 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008583 }
8584 }
Victor Stinnercb043522010-09-10 23:49:04 +00008585
8586 if ((unsigned int)len >= sizeof(buffer)) {
8587 char *buf = PyMem_Malloc(len);
8588 if (buf == NULL)
8589 return PyErr_NoMemory();
8590 confstr(name, buf, len);
8591 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8592 PyMem_Free(buf);
8593 }
8594 else
8595 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008596 return result;
8597}
8598#endif
8599
8600
8601#ifdef HAVE_SYSCONF
8602static struct constdef posix_constants_sysconf[] = {
8603#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008604 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008605#endif
8606#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008607 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008608#endif
8609#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008610 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008611#endif
8612#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008613 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008614#endif
8615#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008616 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008617#endif
8618#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00008619 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008620#endif
8621#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00008622 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008623#endif
8624#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008625 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008626#endif
8627#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008628 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008629#endif
8630#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008631 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008632#endif
Fred Draked86ed291999-12-15 15:34:33 +00008633#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008634 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008635#endif
8636#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00008637 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008638#endif
Fred Drakec9680921999-12-13 16:37:25 +00008639#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008640 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008641#endif
Fred Drakec9680921999-12-13 16:37:25 +00008642#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008643 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008644#endif
8645#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008646 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008647#endif
8648#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008649 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008650#endif
8651#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008652 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008653#endif
8654#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008655 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008656#endif
Fred Draked86ed291999-12-15 15:34:33 +00008657#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008658 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008659#endif
Fred Drakec9680921999-12-13 16:37:25 +00008660#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008661 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008662#endif
8663#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008664 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008665#endif
8666#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008667 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008668#endif
8669#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008670 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008671#endif
8672#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008673 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008674#endif
Fred Draked86ed291999-12-15 15:34:33 +00008675#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00008676 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008677#endif
Fred Drakec9680921999-12-13 16:37:25 +00008678#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008679 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008680#endif
8681#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008682 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008683#endif
8684#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008685 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008686#endif
8687#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008688 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008689#endif
8690#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008691 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008692#endif
8693#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008695#endif
8696#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008697 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008698#endif
8699#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008700 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008701#endif
8702#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008703 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008704#endif
8705#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008707#endif
8708#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008709 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008710#endif
8711#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008712 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008713#endif
8714#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008715 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008716#endif
8717#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008718 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008719#endif
8720#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008721 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008722#endif
8723#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008724 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008725#endif
8726#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008727 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008728#endif
8729#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008730 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008731#endif
8732#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008733 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008734#endif
8735#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008736 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008737#endif
8738#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008739 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008740#endif
8741#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008742 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008743#endif
8744#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008745 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008746#endif
Fred Draked86ed291999-12-15 15:34:33 +00008747#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00008748 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008749#endif
Fred Drakec9680921999-12-13 16:37:25 +00008750#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008751 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008752#endif
8753#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008754 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008755#endif
8756#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008757 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008758#endif
Fred Draked86ed291999-12-15 15:34:33 +00008759#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008760 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008761#endif
Fred Drakec9680921999-12-13 16:37:25 +00008762#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00008763 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008764#endif
Fred Draked86ed291999-12-15 15:34:33 +00008765#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00008766 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008767#endif
8768#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00008769 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008770#endif
Fred Drakec9680921999-12-13 16:37:25 +00008771#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008772 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008773#endif
8774#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008775 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008776#endif
8777#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008778 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008779#endif
8780#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008781 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008782#endif
Fred Draked86ed291999-12-15 15:34:33 +00008783#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00008784 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008785#endif
Fred Drakec9680921999-12-13 16:37:25 +00008786#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00008787 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008788#endif
8789#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00008790 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008791#endif
8792#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008793 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008794#endif
8795#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008796 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008797#endif
8798#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008799 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008800#endif
8801#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00008802 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008803#endif
8804#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00008805 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008806#endif
Fred Draked86ed291999-12-15 15:34:33 +00008807#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00008808 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008809#endif
Fred Drakec9680921999-12-13 16:37:25 +00008810#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008811 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008812#endif
8813#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008814 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008815#endif
Fred Draked86ed291999-12-15 15:34:33 +00008816#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008817 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008818#endif
Fred Drakec9680921999-12-13 16:37:25 +00008819#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008820 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008821#endif
8822#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008823 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008824#endif
8825#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008826 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008827#endif
8828#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008829 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008830#endif
8831#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008832 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008833#endif
8834#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008835 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008836#endif
8837#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008838 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008839#endif
8840#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008841 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008842#endif
8843#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008844 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008845#endif
Fred Draked86ed291999-12-15 15:34:33 +00008846#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008847 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008848#endif
8849#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008850 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008851#endif
Fred Drakec9680921999-12-13 16:37:25 +00008852#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00008853 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008854#endif
8855#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008856 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008857#endif
8858#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008860#endif
8861#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008862 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008863#endif
8864#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008865 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008866#endif
8867#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008868 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008869#endif
8870#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00008871 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008872#endif
8873#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00008874 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008875#endif
8876#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008877 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008878#endif
8879#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008880 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008881#endif
8882#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00008883 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008884#endif
8885#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008886 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008887#endif
8888#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008889 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008890#endif
8891#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00008892 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008893#endif
8894#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00008895 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008896#endif
8897#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00008898 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008899#endif
8900#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00008901 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008902#endif
8903#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008904 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008905#endif
8906#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008907 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008908#endif
8909#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00008910 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008911#endif
8912#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008913 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008914#endif
8915#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008916 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008917#endif
8918#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00008919 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008920#endif
8921#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008922 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008923#endif
8924#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008925 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008926#endif
8927#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008928 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008929#endif
8930#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00008931 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008932#endif
8933#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008934 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008935#endif
8936#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008937 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008938#endif
8939#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008940 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008941#endif
8942#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008943 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008944#endif
8945#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008946 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008947#endif
8948#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008949 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008950#endif
8951#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008952 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008953#endif
8954#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008955 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008956#endif
Fred Draked86ed291999-12-15 15:34:33 +00008957#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00008958 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008959#endif
Fred Drakec9680921999-12-13 16:37:25 +00008960#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00008961 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008962#endif
8963#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008964 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008965#endif
8966#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00008967 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008968#endif
8969#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008970 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008971#endif
8972#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008973 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008974#endif
8975#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00008976 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008977#endif
8978#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00008979 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008980#endif
8981#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008982 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008983#endif
8984#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00008985 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008986#endif
8987#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008988 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008989#endif
8990#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008991 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008992#endif
8993#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008994 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008995#endif
8996#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008997 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008998#endif
8999#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009000 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009001#endif
9002#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009003 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009004#endif
9005#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009006 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009007#endif
9008#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009009 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009010#endif
9011#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009012 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009013#endif
9014#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009015 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009016#endif
9017#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009018 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009019#endif
9020#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009021 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009022#endif
9023#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009024 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009025#endif
9026#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009027 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009028#endif
9029#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009030 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009031#endif
9032#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009033 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009034#endif
9035#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009036 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009037#endif
9038#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009039 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009040#endif
9041#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009042 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009043#endif
9044#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009045 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009046#endif
9047#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009048 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009049#endif
9050#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009051 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009052#endif
9053#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009054 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009055#endif
9056#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009057 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009058#endif
9059#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009060 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009061#endif
9062#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009063 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009064#endif
9065#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009067#endif
9068#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009070#endif
9071#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009072 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009073#endif
9074#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009075 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009076#endif
9077#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009078 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009079#endif
9080#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009082#endif
9083#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009084 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009085#endif
9086#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009088#endif
9089#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009090 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009091#endif
9092#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009093 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009094#endif
9095};
9096
9097static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009098conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009099{
9100 return conv_confname(arg, valuep, posix_constants_sysconf,
9101 sizeof(posix_constants_sysconf)
9102 / sizeof(struct constdef));
9103}
9104
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009105PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009106"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009107Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009108
9109static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009110posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009111{
9112 PyObject *result = NULL;
9113 int name;
9114
9115 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9116 int value;
9117
9118 errno = 0;
9119 value = sysconf(name);
9120 if (value == -1 && errno != 0)
9121 posix_error();
9122 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009123 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009124 }
9125 return result;
9126}
9127#endif
9128
9129
Fred Drakebec628d1999-12-15 18:31:10 +00009130/* This code is used to ensure that the tables of configuration value names
9131 * are in sorted order as required by conv_confname(), and also to build the
9132 * the exported dictionaries that are used to publish information about the
9133 * names available on the host platform.
9134 *
9135 * Sorting the table at runtime ensures that the table is properly ordered
9136 * when used, even for platforms we're not able to test on. It also makes
9137 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009138 */
Fred Drakebec628d1999-12-15 18:31:10 +00009139
9140static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009141cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009142{
9143 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009144 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009145 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009147
9148 return strcmp(c1->name, c2->name);
9149}
9150
9151static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009152setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009153 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009154{
Fred Drakebec628d1999-12-15 18:31:10 +00009155 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009156 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009157
9158 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9159 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009160 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009161 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009162
Barry Warsaw3155db32000-04-13 15:20:40 +00009163 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009164 PyObject *o = PyLong_FromLong(table[i].value);
9165 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9166 Py_XDECREF(o);
9167 Py_DECREF(d);
9168 return -1;
9169 }
9170 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009171 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009172 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009173}
9174
Fred Drakebec628d1999-12-15 18:31:10 +00009175/* Return -1 on failure, 0 on success. */
9176static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009177setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009178{
9179#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009180 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009181 sizeof(posix_constants_pathconf)
9182 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009183 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009184 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009185#endif
9186#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009187 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009188 sizeof(posix_constants_confstr)
9189 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009190 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009191 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009192#endif
9193#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009194 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009195 sizeof(posix_constants_sysconf)
9196 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009197 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009198 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009199#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009200 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009201}
Fred Draked86ed291999-12-15 15:34:33 +00009202
9203
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009204PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009205"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009206Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009207in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009208
9209static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009210posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009211{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009212 abort();
9213 /*NOTREACHED*/
9214 Py_FatalError("abort() called from Python code didn't abort!");
9215 return NULL;
9216}
Fred Drakebec628d1999-12-15 18:31:10 +00009217
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009218#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009219PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009220"startfile(filepath [, operation]) - Start a file with its associated\n\
9221application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009222\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009223When \"operation\" is not specified or \"open\", this acts like\n\
9224double-clicking the file in Explorer, or giving the file name as an\n\
9225argument to the DOS \"start\" command: the file is opened with whatever\n\
9226application (if any) its extension is associated.\n\
9227When another \"operation\" is given, it specifies what should be done with\n\
9228the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009229\n\
9230startfile returns as soon as the associated application is launched.\n\
9231There is no option to wait for the application to close, and no way\n\
9232to retrieve the application's exit status.\n\
9233\n\
9234The filepath is relative to the current directory. If you want to use\n\
9235an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009236the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009237
9238static PyObject *
9239win32_startfile(PyObject *self, PyObject *args)
9240{
Victor Stinner8c62be82010-05-06 00:08:46 +00009241 PyObject *ofilepath;
9242 char *filepath;
9243 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009244 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009245 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009246
Victor Stinnereb5657a2011-09-30 01:44:27 +02009247 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009248 if (!PyArg_ParseTuple(args, "U|s:startfile",
9249 &unipath, &operation)) {
9250 PyErr_Clear();
9251 goto normal;
9252 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009253
Victor Stinner8c62be82010-05-06 00:08:46 +00009254 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009255 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009256 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009257 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009258 PyErr_Clear();
9259 operation = NULL;
9260 goto normal;
9261 }
9262 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009263
Victor Stinnereb5657a2011-09-30 01:44:27 +02009264 wpath = PyUnicode_AsUnicode(unipath);
9265 if (wpath == NULL)
9266 goto normal;
9267 if (uoperation) {
9268 woperation = PyUnicode_AsUnicode(uoperation);
9269 if (woperation == NULL)
9270 goto normal;
9271 }
9272 else
9273 woperation = NULL;
9274
Victor Stinner8c62be82010-05-06 00:08:46 +00009275 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009276 rc = ShellExecuteW((HWND)0, woperation, wpath,
9277 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009278 Py_END_ALLOW_THREADS
9279
Victor Stinnereb5657a2011-09-30 01:44:27 +02009280 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009281 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009282 win32_error_object("startfile", unipath);
9283 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009284 }
9285 Py_INCREF(Py_None);
9286 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009287
9288normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009289 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9290 PyUnicode_FSConverter, &ofilepath,
9291 &operation))
9292 return NULL;
9293 filepath = PyBytes_AsString(ofilepath);
9294 Py_BEGIN_ALLOW_THREADS
9295 rc = ShellExecute((HWND)0, operation, filepath,
9296 NULL, NULL, SW_SHOWNORMAL);
9297 Py_END_ALLOW_THREADS
9298 if (rc <= (HINSTANCE)32) {
9299 PyObject *errval = win32_error("startfile", filepath);
9300 Py_DECREF(ofilepath);
9301 return errval;
9302 }
9303 Py_DECREF(ofilepath);
9304 Py_INCREF(Py_None);
9305 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009306}
9307#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009308
Martin v. Löwis438b5342002-12-27 10:16:42 +00009309#ifdef HAVE_GETLOADAVG
9310PyDoc_STRVAR(posix_getloadavg__doc__,
9311"getloadavg() -> (float, float, float)\n\n\
9312Return the number of processes in the system run queue averaged over\n\
9313the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9314was unobtainable");
9315
9316static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009317posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009318{
9319 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009320 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009321 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9322 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009323 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009324 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009325}
9326#endif
9327
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009328#ifdef MS_WINDOWS
9329
9330PyDoc_STRVAR(win32_urandom__doc__,
9331"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009332Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009333
9334typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
9335 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
9336 DWORD dwFlags );
9337typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
9338 BYTE *pbBuffer );
9339
9340static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00009341/* This handle is never explicitly released. Instead, the operating
9342 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009343static HCRYPTPROV hCryptProv = 0;
9344
Tim Peters4ad82172004-08-30 17:02:04 +00009345static PyObject*
9346win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009347{
Victor Stinner8c62be82010-05-06 00:08:46 +00009348 int howMany;
9349 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009350
Victor Stinner8c62be82010-05-06 00:08:46 +00009351 /* Read arguments */
9352 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9353 return NULL;
9354 if (howMany < 0)
9355 return PyErr_Format(PyExc_ValueError,
9356 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009357
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 if (hCryptProv == 0) {
9359 HINSTANCE hAdvAPI32 = NULL;
9360 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009361
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 /* Obtain handle to the DLL containing CryptoAPI
9363 This should not fail */
9364 hAdvAPI32 = GetModuleHandle("advapi32.dll");
9365 if(hAdvAPI32 == NULL)
9366 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009367
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 /* Obtain pointers to the CryptoAPI functions
9369 This will fail on some early versions of Win95 */
9370 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
9371 hAdvAPI32,
9372 "CryptAcquireContextA");
9373 if (pCryptAcquireContext == NULL)
9374 return PyErr_Format(PyExc_NotImplementedError,
9375 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009376
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
9378 hAdvAPI32, "CryptGenRandom");
9379 if (pCryptGenRandom == NULL)
9380 return PyErr_Format(PyExc_NotImplementedError,
9381 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009382
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 /* Acquire context */
9384 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
9385 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
9386 return win32_error("CryptAcquireContext", NULL);
9387 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009388
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 /* Allocate bytes */
9390 result = PyBytes_FromStringAndSize(NULL, howMany);
9391 if (result != NULL) {
9392 /* Get random data */
9393 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
9394 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
9395 PyBytes_AS_STRING(result))) {
9396 Py_DECREF(result);
9397 return win32_error("CryptGenRandom", NULL);
9398 }
9399 }
9400 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009401}
9402#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009403
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009404PyDoc_STRVAR(device_encoding__doc__,
9405"device_encoding(fd) -> str\n\n\
9406Return a string describing the encoding of the device\n\
9407if the output is a terminal; else return None.");
9408
9409static PyObject *
9410device_encoding(PyObject *self, PyObject *args)
9411{
Victor Stinner8c62be82010-05-06 00:08:46 +00009412 int fd;
Victor Stinner7870bdf2011-05-23 18:12:52 +02009413#if defined(MS_WINDOWS) || defined(MS_WIN64)
9414 UINT cp;
9415#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009416 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9417 return NULL;
9418 if (!_PyVerify_fd(fd) || !isatty(fd)) {
9419 Py_INCREF(Py_None);
9420 return Py_None;
9421 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009422#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner7870bdf2011-05-23 18:12:52 +02009423 if (fd == 0)
9424 cp = GetConsoleCP();
9425 else if (fd == 1 || fd == 2)
9426 cp = GetConsoleOutputCP();
9427 else
9428 cp = 0;
9429 /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application
9430 has no console */
9431 if (cp != 0)
9432 return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009433#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00009434 {
9435 char *codeset = nl_langinfo(CODESET);
9436 if (codeset != NULL && codeset[0] != 0)
9437 return PyUnicode_FromString(codeset);
9438 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009439#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009440 Py_INCREF(Py_None);
9441 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009442}
9443
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009444#ifdef __VMS
9445/* Use openssl random routine */
9446#include <openssl/rand.h>
9447PyDoc_STRVAR(vms_urandom__doc__,
9448"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009449Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009450
9451static PyObject*
9452vms_urandom(PyObject *self, PyObject *args)
9453{
Victor Stinner8c62be82010-05-06 00:08:46 +00009454 int howMany;
9455 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009456
Victor Stinner8c62be82010-05-06 00:08:46 +00009457 /* Read arguments */
9458 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9459 return NULL;
9460 if (howMany < 0)
9461 return PyErr_Format(PyExc_ValueError,
9462 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009463
Victor Stinner8c62be82010-05-06 00:08:46 +00009464 /* Allocate bytes */
9465 result = PyBytes_FromStringAndSize(NULL, howMany);
9466 if (result != NULL) {
9467 /* Get random data */
9468 if (RAND_pseudo_bytes((unsigned char*)
9469 PyBytes_AS_STRING(result),
9470 howMany) < 0) {
9471 Py_DECREF(result);
9472 return PyErr_Format(PyExc_ValueError,
9473 "RAND_pseudo_bytes");
9474 }
9475 }
9476 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009477}
9478#endif
9479
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009480#ifdef HAVE_SETRESUID
9481PyDoc_STRVAR(posix_setresuid__doc__,
9482"setresuid(ruid, euid, suid)\n\n\
9483Set the current process's real, effective, and saved user ids.");
9484
9485static PyObject*
9486posix_setresuid (PyObject *self, PyObject *args)
9487{
Victor Stinner8c62be82010-05-06 00:08:46 +00009488 /* We assume uid_t is no larger than a long. */
9489 long ruid, euid, suid;
9490 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9491 return NULL;
9492 if (setresuid(ruid, euid, suid) < 0)
9493 return posix_error();
9494 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009495}
9496#endif
9497
9498#ifdef HAVE_SETRESGID
9499PyDoc_STRVAR(posix_setresgid__doc__,
9500"setresgid(rgid, egid, sgid)\n\n\
9501Set the current process's real, effective, and saved group ids.");
9502
9503static PyObject*
9504posix_setresgid (PyObject *self, PyObject *args)
9505{
Victor Stinner8c62be82010-05-06 00:08:46 +00009506 /* We assume uid_t is no larger than a long. */
9507 long rgid, egid, sgid;
9508 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9509 return NULL;
9510 if (setresgid(rgid, egid, sgid) < 0)
9511 return posix_error();
9512 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009513}
9514#endif
9515
9516#ifdef HAVE_GETRESUID
9517PyDoc_STRVAR(posix_getresuid__doc__,
9518"getresuid() -> (ruid, euid, suid)\n\n\
9519Get tuple of the current process's real, effective, and saved user ids.");
9520
9521static PyObject*
9522posix_getresuid (PyObject *self, PyObject *noargs)
9523{
Victor Stinner8c62be82010-05-06 00:08:46 +00009524 uid_t ruid, euid, suid;
9525 long l_ruid, l_euid, l_suid;
9526 if (getresuid(&ruid, &euid, &suid) < 0)
9527 return posix_error();
9528 /* Force the values into long's as we don't know the size of uid_t. */
9529 l_ruid = ruid;
9530 l_euid = euid;
9531 l_suid = suid;
9532 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009533}
9534#endif
9535
9536#ifdef HAVE_GETRESGID
9537PyDoc_STRVAR(posix_getresgid__doc__,
9538"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009539Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009540
9541static PyObject*
9542posix_getresgid (PyObject *self, PyObject *noargs)
9543{
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 uid_t rgid, egid, sgid;
9545 long l_rgid, l_egid, l_sgid;
9546 if (getresgid(&rgid, &egid, &sgid) < 0)
9547 return posix_error();
9548 /* Force the values into long's as we don't know the size of uid_t. */
9549 l_rgid = rgid;
9550 l_egid = egid;
9551 l_sgid = sgid;
9552 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009553}
9554#endif
9555
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009556/* Posix *at family of functions:
9557 faccessat, fchmodat, fchownat, fstatat, futimesat,
9558 linkat, mkdirat, mknodat, openat, readlinkat, renameat, symlinkat,
9559 unlinkat, utimensat, mkfifoat */
9560
9561#ifdef HAVE_FACCESSAT
9562PyDoc_STRVAR(posix_faccessat__doc__,
9563"faccessat(dirfd, path, mode, flags=0) -> True if granted, False otherwise\n\n\
9564Like access() but if path is relative, it is taken as relative to dirfd.\n\
9565flags is optional and can be constructed by ORing together zero or more\n\
9566of these values: AT_SYMLINK_NOFOLLOW, AT_EACCESS.\n\
9567If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9568is interpreted relative to the current working directory.");
9569
9570static PyObject *
9571posix_faccessat(PyObject *self, PyObject *args)
9572{
9573 PyObject *opath;
9574 char *path;
9575 int mode;
9576 int res;
9577 int dirfd, flags = 0;
9578 if (!PyArg_ParseTuple(args, "iO&i|i:faccessat",
9579 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9580 return NULL;
9581 path = PyBytes_AsString(opath);
9582 Py_BEGIN_ALLOW_THREADS
9583 res = faccessat(dirfd, path, mode, flags);
9584 Py_END_ALLOW_THREADS
9585 Py_DECREF(opath);
9586 return PyBool_FromLong(res == 0);
9587}
9588#endif
9589
9590#ifdef HAVE_FCHMODAT
9591PyDoc_STRVAR(posix_fchmodat__doc__,
9592"fchmodat(dirfd, path, mode, flags=0)\n\n\
9593Like chmod() but if path is relative, it is taken as relative to dirfd.\n\
9594flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9595If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9596is interpreted relative to the current working directory.");
9597
9598static PyObject *
9599posix_fchmodat(PyObject *self, PyObject *args)
9600{
9601 int dirfd, mode, res;
9602 int flags = 0;
9603 PyObject *opath;
9604 char *path;
9605
9606 if (!PyArg_ParseTuple(args, "iO&i|i:fchmodat",
9607 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9608 return NULL;
9609
9610 path = PyBytes_AsString(opath);
9611
9612 Py_BEGIN_ALLOW_THREADS
9613 res = fchmodat(dirfd, path, mode, flags);
9614 Py_END_ALLOW_THREADS
9615 Py_DECREF(opath);
9616 if (res < 0)
9617 return posix_error();
9618 Py_RETURN_NONE;
9619}
9620#endif /* HAVE_FCHMODAT */
9621
9622#ifdef HAVE_FCHOWNAT
9623PyDoc_STRVAR(posix_fchownat__doc__,
9624"fchownat(dirfd, path, uid, gid, flags=0)\n\n\
9625Like chown() but if path is relative, it is taken as relative to dirfd.\n\
9626flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9627If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9628is interpreted relative to the current working directory.");
9629
9630static PyObject *
9631posix_fchownat(PyObject *self, PyObject *args)
9632{
9633 PyObject *opath;
9634 int dirfd, res;
9635 long uid, gid;
9636 int flags = 0;
9637 char *path;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009638
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009639 if (!PyArg_ParseTuple(args, "iO&ll|i:fchownat",
9640 &dirfd, PyUnicode_FSConverter, &opath, &uid, &gid, &flags))
9641 return NULL;
9642
9643 path = PyBytes_AsString(opath);
9644
9645 Py_BEGIN_ALLOW_THREADS
9646 res = fchownat(dirfd, path, (uid_t) uid, (gid_t) gid, flags);
9647 Py_END_ALLOW_THREADS
9648 Py_DECREF(opath);
9649 if (res < 0)
9650 return posix_error();
9651 Py_RETURN_NONE;
9652}
9653#endif /* HAVE_FCHOWNAT */
9654
9655#ifdef HAVE_FSTATAT
9656PyDoc_STRVAR(posix_fstatat__doc__,
9657"fstatat(dirfd, path, flags=0) -> stat result\n\n\
9658Like stat() but if path is relative, it is taken as relative to dirfd.\n\
9659flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9660If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9661is interpreted relative to the current working directory.");
9662
9663static PyObject *
9664posix_fstatat(PyObject *self, PyObject *args)
9665{
9666 PyObject *opath;
9667 char *path;
9668 STRUCT_STAT st;
9669 int dirfd, res, flags = 0;
9670
9671 if (!PyArg_ParseTuple(args, "iO&|i:fstatat",
9672 &dirfd, PyUnicode_FSConverter, &opath, &flags))
9673 return NULL;
9674 path = PyBytes_AsString(opath);
9675
9676 Py_BEGIN_ALLOW_THREADS
9677 res = fstatat(dirfd, path, &st, flags);
9678 Py_END_ALLOW_THREADS
9679 Py_DECREF(opath);
9680 if (res != 0)
9681 return posix_error();
9682
9683 return _pystat_fromstructstat(&st);
9684}
9685#endif
9686
9687#ifdef HAVE_FUTIMESAT
9688PyDoc_STRVAR(posix_futimesat__doc__,
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009689"futimesat(dirfd, path[, (atime, mtime)])\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009690Like utime() but if path is relative, it is taken as relative to dirfd.\n\
9691If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9692is interpreted relative to the current working directory.");
9693
9694static PyObject *
9695posix_futimesat(PyObject *self, PyObject *args)
9696{
9697 PyObject *opath;
9698 char *path;
9699 int res, dirfd;
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009700 PyObject* arg = Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009701 time_t atime, mtime;
9702 long ausec, musec;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009703
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009704 if (!PyArg_ParseTuple(args, "iO&|O:futimesat",
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009705 &dirfd, PyUnicode_FSConverter, &opath, &arg))
9706 return NULL;
9707 path = PyBytes_AsString(opath);
9708 if (arg == Py_None) {
9709 /* optional time values not given */
9710 Py_BEGIN_ALLOW_THREADS
9711 res = futimesat(dirfd, path, NULL);
9712 Py_END_ALLOW_THREADS
9713 }
9714 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
9715 PyErr_SetString(PyExc_TypeError,
9716 "futimesat() arg 3 must be a tuple (atime, mtime)");
9717 Py_DECREF(opath);
9718 return NULL;
9719 }
9720 else {
9721 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009722 &atime, &ausec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009723 Py_DECREF(opath);
9724 return NULL;
9725 }
9726 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009727 &mtime, &musec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009728 Py_DECREF(opath);
9729 return NULL;
9730 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009731
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009732 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009733 {
9734#ifdef HAVE_UTIMENSAT
9735 struct timespec buf[2];
9736 buf[0].tv_sec = atime;
9737 buf[0].tv_nsec = ausec;
9738 buf[1].tv_sec = mtime;
9739 buf[1].tv_nsec = musec;
9740 res = utimensat(dirfd, path, buf, 0);
9741#else
9742 struct timeval buf[2];
9743 buf[0].tv_sec = atime;
9744 buf[0].tv_usec = ausec;
9745 buf[1].tv_sec = mtime;
9746 buf[1].tv_usec = musec;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009747 res = futimesat(dirfd, path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009748#endif
9749 }
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009750 Py_END_ALLOW_THREADS
9751 }
9752 Py_DECREF(opath);
9753 if (res < 0) {
9754 return posix_error();
9755 }
9756 Py_RETURN_NONE;
9757}
9758#endif
9759
9760#ifdef HAVE_LINKAT
9761PyDoc_STRVAR(posix_linkat__doc__,
9762"linkat(srcfd, srcpath, dstfd, dstpath, flags=0)\n\n\
9763Like link() but if srcpath is relative, it is taken as relative to srcfd\n\
9764and if dstpath is relative, it is taken as relative to dstfd.\n\
9765flags is optional and may be 0 or AT_SYMLINK_FOLLOW.\n\
9766If srcpath is relative and srcfd is the special value AT_FDCWD, then\n\
9767srcpath is interpreted relative to the current working directory. This\n\
9768also applies for dstpath.");
9769
9770static PyObject *
9771posix_linkat(PyObject *self, PyObject *args)
9772{
9773 PyObject *osrc, *odst;
9774 char *src, *dst;
9775 int res, srcfd, dstfd;
9776 int flags = 0;
9777
9778 if (!PyArg_ParseTuple(args, "iO&iO&|i:linkat",
9779 &srcfd, PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst, &flags))
9780 return NULL;
9781 src = PyBytes_AsString(osrc);
9782 dst = PyBytes_AsString(odst);
9783 Py_BEGIN_ALLOW_THREADS
9784 res = linkat(srcfd, src, dstfd, dst, flags);
9785 Py_END_ALLOW_THREADS
9786 Py_DECREF(osrc);
9787 Py_DECREF(odst);
9788 if (res < 0)
9789 return posix_error();
9790 Py_RETURN_NONE;
9791}
9792#endif /* HAVE_LINKAT */
9793
9794#ifdef HAVE_MKDIRAT
9795PyDoc_STRVAR(posix_mkdirat__doc__,
9796"mkdirat(dirfd, path, mode=0o777)\n\n\
9797Like mkdir() but if path is relative, it is taken as relative to dirfd.\n\
9798If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9799is interpreted relative to the current working directory.");
9800
9801static PyObject *
9802posix_mkdirat(PyObject *self, PyObject *args)
9803{
9804 int res, dirfd;
9805 PyObject *opath;
9806 char *path;
9807 int mode = 0777;
9808
9809 if (!PyArg_ParseTuple(args, "iO&|i:mkdirat",
9810 &dirfd, PyUnicode_FSConverter, &opath, &mode))
9811 return NULL;
9812 path = PyBytes_AsString(opath);
9813 Py_BEGIN_ALLOW_THREADS
9814 res = mkdirat(dirfd, path, mode);
9815 Py_END_ALLOW_THREADS
9816 Py_DECREF(opath);
9817 if (res < 0)
9818 return posix_error();
9819 Py_RETURN_NONE;
9820}
9821#endif
9822
9823#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
9824PyDoc_STRVAR(posix_mknodat__doc__,
9825"mknodat(dirfd, path, mode=0o600, device=0)\n\n\
9826Like mknod() but if path is relative, it is taken as relative to dirfd.\n\
9827If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9828is interpreted relative to the current working directory.");
9829
9830static PyObject *
9831posix_mknodat(PyObject *self, PyObject *args)
9832{
9833 PyObject *opath;
9834 char *filename;
9835 int mode = 0600;
9836 int device = 0;
9837 int res, dirfd;
9838 if (!PyArg_ParseTuple(args, "iO&|ii:mknodat", &dirfd,
9839 PyUnicode_FSConverter, &opath, &mode, &device))
9840 return NULL;
9841 filename = PyBytes_AS_STRING(opath);
9842 Py_BEGIN_ALLOW_THREADS
9843 res = mknodat(dirfd, filename, mode, device);
9844 Py_END_ALLOW_THREADS
9845 Py_DECREF(opath);
9846 if (res < 0)
9847 return posix_error();
9848 Py_RETURN_NONE;
9849}
9850#endif
9851
9852#ifdef HAVE_OPENAT
9853PyDoc_STRVAR(posix_openat__doc__,
9854"openat(dirfd, path, flag, mode=0o777) -> fd\n\n\
9855Like open() but if path is relative, it is taken as relative to dirfd.\n\
9856If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9857is interpreted relative to the current working directory.");
9858
9859static PyObject *
9860posix_openat(PyObject *self, PyObject *args)
9861{
9862 PyObject *ofile;
9863 char *file;
9864 int flag, dirfd, fd;
9865 int mode = 0777;
9866
9867 if (!PyArg_ParseTuple(args, "iO&i|i:openat",
9868 &dirfd, PyUnicode_FSConverter, &ofile,
9869 &flag, &mode))
9870 return NULL;
9871 file = PyBytes_AsString(ofile);
9872 Py_BEGIN_ALLOW_THREADS
9873 fd = openat(dirfd, file, flag, mode);
9874 Py_END_ALLOW_THREADS
9875 Py_DECREF(ofile);
9876 if (fd < 0)
9877 return posix_error();
9878 return PyLong_FromLong((long)fd);
9879}
9880#endif
9881
9882#ifdef HAVE_READLINKAT
9883PyDoc_STRVAR(posix_readlinkat__doc__,
9884"readlinkat(dirfd, path) -> path\n\n\
9885Like readlink() but if path is relative, it is taken as relative to dirfd.\n\
9886If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9887is interpreted relative to the current working directory.");
9888
9889static PyObject *
9890posix_readlinkat(PyObject *self, PyObject *args)
9891{
9892 PyObject *v, *opath;
9893 char buf[MAXPATHLEN];
9894 char *path;
9895 int n, dirfd;
9896 int arg_is_unicode = 0;
9897
9898 if (!PyArg_ParseTuple(args, "iO&:readlinkat",
9899 &dirfd, PyUnicode_FSConverter, &opath))
9900 return NULL;
9901 path = PyBytes_AsString(opath);
9902 v = PySequence_GetItem(args, 1);
9903 if (v == NULL) {
9904 Py_DECREF(opath);
9905 return NULL;
9906 }
9907
9908 if (PyUnicode_Check(v)) {
9909 arg_is_unicode = 1;
9910 }
9911 Py_DECREF(v);
9912
9913 Py_BEGIN_ALLOW_THREADS
9914 n = readlinkat(dirfd, path, buf, (int) sizeof buf);
9915 Py_END_ALLOW_THREADS
9916 Py_DECREF(opath);
9917 if (n < 0)
9918 return posix_error();
9919
9920 if (arg_is_unicode)
9921 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
9922 else
9923 return PyBytes_FromStringAndSize(buf, n);
9924}
9925#endif /* HAVE_READLINKAT */
9926
9927#ifdef HAVE_RENAMEAT
9928PyDoc_STRVAR(posix_renameat__doc__,
9929"renameat(olddirfd, oldpath, newdirfd, newpath)\n\n\
9930Like rename() but if oldpath is relative, it is taken as relative to\n\
9931olddirfd and if newpath is relative, it is taken as relative to newdirfd.\n\
9932If oldpath is relative and olddirfd is the special value AT_FDCWD, then\n\
9933oldpath is interpreted relative to the current working directory. This\n\
9934also applies for newpath.");
9935
9936static PyObject *
9937posix_renameat(PyObject *self, PyObject *args)
9938{
9939 int res;
9940 PyObject *opathold, *opathnew;
9941 char *opath, *npath;
9942 int oldfd, newfd;
9943
9944 if (!PyArg_ParseTuple(args, "iO&iO&:renameat",
9945 &oldfd, PyUnicode_FSConverter, &opathold, &newfd, PyUnicode_FSConverter, &opathnew))
9946 return NULL;
9947 opath = PyBytes_AsString(opathold);
9948 npath = PyBytes_AsString(opathnew);
9949 Py_BEGIN_ALLOW_THREADS
9950 res = renameat(oldfd, opath, newfd, npath);
9951 Py_END_ALLOW_THREADS
9952 Py_DECREF(opathold);
9953 Py_DECREF(opathnew);
9954 if (res < 0)
9955 return posix_error();
9956 Py_RETURN_NONE;
9957}
9958#endif
9959
9960#if HAVE_SYMLINKAT
9961PyDoc_STRVAR(posix_symlinkat__doc__,
9962"symlinkat(src, dstfd, dst)\n\n\
9963Like symlink() but if dst is relative, it is taken as relative to dstfd.\n\
9964If dst is relative and dstfd is the special value AT_FDCWD, then dst\n\
9965is interpreted relative to the current working directory.");
9966
9967static PyObject *
9968posix_symlinkat(PyObject *self, PyObject *args)
9969{
9970 int res, dstfd;
9971 PyObject *osrc, *odst;
9972 char *src, *dst;
9973
9974 if (!PyArg_ParseTuple(args, "O&iO&:symlinkat",
9975 PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst))
9976 return NULL;
9977 src = PyBytes_AsString(osrc);
9978 dst = PyBytes_AsString(odst);
9979 Py_BEGIN_ALLOW_THREADS
9980 res = symlinkat(src, dstfd, dst);
9981 Py_END_ALLOW_THREADS
9982 Py_DECREF(osrc);
9983 Py_DECREF(odst);
9984 if (res < 0)
9985 return posix_error();
9986 Py_RETURN_NONE;
9987}
9988#endif /* HAVE_SYMLINKAT */
9989
9990#ifdef HAVE_UNLINKAT
9991PyDoc_STRVAR(posix_unlinkat__doc__,
9992"unlinkat(dirfd, path, flags=0)\n\n\
9993Like unlink() but if path is relative, it is taken as relative to dirfd.\n\
9994flags is optional and may be 0 or AT_REMOVEDIR. If AT_REMOVEDIR is\n\
9995specified, unlinkat() behaves like rmdir().\n\
9996If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9997is interpreted relative to the current working directory.");
9998
9999static PyObject *
10000posix_unlinkat(PyObject *self, PyObject *args)
10001{
10002 int dirfd, res, flags = 0;
10003 PyObject *opath;
10004 char *path;
10005
10006 if (!PyArg_ParseTuple(args, "iO&|i:unlinkat",
10007 &dirfd, PyUnicode_FSConverter, &opath, &flags))
10008 return NULL;
10009 path = PyBytes_AsString(opath);
10010 Py_BEGIN_ALLOW_THREADS
10011 res = unlinkat(dirfd, path, flags);
10012 Py_END_ALLOW_THREADS
10013 Py_DECREF(opath);
10014 if (res < 0)
10015 return posix_error();
10016 Py_RETURN_NONE;
10017}
10018#endif
10019
10020#ifdef HAVE_UTIMENSAT
10021PyDoc_STRVAR(posix_utimensat__doc__,
10022"utimensat(dirfd, path, (atime_sec, atime_nsec),\n\
10023 (mtime_sec, mtime_nsec), flags)\n\
10024utimensat(dirfd, path, None, None, flags)\n\n\
10025Updates the timestamps of a file with nanosecond precision. If path is\n\
10026relative, it is taken as relative to dirfd.\n\
10027The second form sets atime and mtime to the current time.\n\
10028flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
10029If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10030is interpreted relative to the current working directory.\n\
10031If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
10032current time.\n\
10033If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
10034
10035static PyObject *
10036posix_utimensat(PyObject *self, PyObject *args)
10037{
10038 PyObject *opath;
10039 char *path;
10040 int res, dirfd, flags = 0;
10041 PyObject *atime, *mtime;
10042
10043 struct timespec buf[2];
10044
10045 if (!PyArg_ParseTuple(args, "iO&OO|i:utimensat",
10046 &dirfd, PyUnicode_FSConverter, &opath, &atime, &mtime, &flags))
10047 return NULL;
10048 path = PyBytes_AsString(opath);
10049 if (atime == Py_None && mtime == Py_None) {
10050 /* optional time values not given */
10051 Py_BEGIN_ALLOW_THREADS
10052 res = utimensat(dirfd, path, NULL, flags);
10053 Py_END_ALLOW_THREADS
10054 }
10055 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
10056 PyErr_SetString(PyExc_TypeError,
10057 "utimensat() arg 3 must be a tuple (atime_sec, atime_nsec)");
10058 Py_DECREF(opath);
10059 return NULL;
10060 }
10061 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
10062 PyErr_SetString(PyExc_TypeError,
10063 "utimensat() arg 4 must be a tuple (mtime_sec, mtime_nsec)");
10064 Py_DECREF(opath);
10065 return NULL;
10066 }
10067 else {
10068 if (!PyArg_ParseTuple(atime, "ll:utimensat",
10069 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
10070 Py_DECREF(opath);
10071 return NULL;
10072 }
10073 if (!PyArg_ParseTuple(mtime, "ll:utimensat",
10074 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
10075 Py_DECREF(opath);
10076 return NULL;
10077 }
10078 Py_BEGIN_ALLOW_THREADS
10079 res = utimensat(dirfd, path, buf, flags);
10080 Py_END_ALLOW_THREADS
10081 }
10082 Py_DECREF(opath);
10083 if (res < 0) {
10084 return posix_error();
10085 }
10086 Py_RETURN_NONE;
10087}
10088#endif
10089
10090#ifdef HAVE_MKFIFOAT
10091PyDoc_STRVAR(posix_mkfifoat__doc__,
10092"mkfifoat(dirfd, path, mode=0o666)\n\n\
10093Like mkfifo() but if path is relative, it is taken as relative to dirfd.\n\
10094If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10095is interpreted relative to the current working directory.");
10096
10097static PyObject *
10098posix_mkfifoat(PyObject *self, PyObject *args)
10099{
10100 PyObject *opath;
10101 char *filename;
10102 int mode = 0666;
10103 int res, dirfd;
10104 if (!PyArg_ParseTuple(args, "iO&|i:mkfifoat",
10105 &dirfd, PyUnicode_FSConverter, &opath, &mode))
10106 return NULL;
10107 filename = PyBytes_AS_STRING(opath);
10108 Py_BEGIN_ALLOW_THREADS
10109 res = mkfifoat(dirfd, filename, mode);
10110 Py_END_ALLOW_THREADS
10111 Py_DECREF(opath);
10112 if (res < 0)
10113 return posix_error();
10114 Py_RETURN_NONE;
10115}
10116#endif
10117
Benjamin Peterson9428d532011-09-14 11:45:52 -040010118#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010119
10120static int
10121try_getxattr(const char *path, const char *name,
10122 ssize_t (*get)(const char *, const char *, void *, size_t),
10123 Py_ssize_t buf_size, PyObject **res)
10124{
10125 PyObject *value;
10126 Py_ssize_t len;
10127
10128 assert(buf_size <= XATTR_SIZE_MAX);
10129 value = PyBytes_FromStringAndSize(NULL, buf_size);
10130 if (!value)
10131 return 0;
10132 Py_BEGIN_ALLOW_THREADS;
10133 len = get(path, name, PyBytes_AS_STRING(value), buf_size);
10134 Py_END_ALLOW_THREADS;
10135 if (len < 0) {
10136 Py_DECREF(value);
10137 if (errno == ERANGE) {
10138 value = NULL;
10139 }
10140 else {
10141 posix_error();
10142 return 0;
10143 }
10144 }
10145 else if (len != buf_size) {
10146 /* Can only shrink. */
10147 _PyBytes_Resize(&value, len);
10148 }
10149 *res = value;
10150 return 1;
10151}
10152
10153static PyObject *
10154getxattr_common(const char *path, PyObject *name_obj,
10155 ssize_t (*get)(const char *, const char *, void *, size_t))
10156{
10157 PyObject *value;
10158 const char *name = PyBytes_AS_STRING(name_obj);
10159
10160 /* Try a small value first. */
10161 if (!try_getxattr(path, name, get, 128, &value))
10162 return NULL;
10163 if (value)
10164 return value;
10165 /* Now the maximum possible one. */
10166 if (!try_getxattr(path, name, get, XATTR_SIZE_MAX, &value))
10167 return NULL;
10168 assert(value);
10169 return value;
10170}
10171
10172PyDoc_STRVAR(posix_getxattr__doc__,
10173"getxattr(path, attr) -> value\n\n\
10174Return the value of extended attribute *name* on *path*.");
10175
10176static PyObject *
10177posix_getxattr(PyObject *self, PyObject *args)
10178{
10179 PyObject *path, *res, *name;
10180
10181 if (!PyArg_ParseTuple(args, "O&O&:getxattr", PyUnicode_FSConverter, &path,
10182 PyUnicode_FSConverter, &name))
10183 return NULL;
10184 res = getxattr_common(PyBytes_AS_STRING(path), name, getxattr);
10185 Py_DECREF(path);
10186 Py_DECREF(name);
10187 return res;
10188}
10189
10190PyDoc_STRVAR(posix_lgetxattr__doc__,
10191"lgetxattr(path, attr) -> value\n\n\
10192Like getxattr but don't follow symlinks.");
10193
10194static PyObject *
10195posix_lgetxattr(PyObject *self, PyObject *args)
10196{
10197 PyObject *path, *res, *name;
10198
10199 if (!PyArg_ParseTuple(args, "O&O&:lgetxattr", PyUnicode_FSConverter, &path,
10200 PyUnicode_FSConverter, &name))
10201 return NULL;
10202 res = getxattr_common(PyBytes_AS_STRING(path), name, lgetxattr);
10203 Py_DECREF(path);
10204 Py_DECREF(name);
10205 return res;
10206}
10207
10208static ssize_t
10209wrap_fgetxattr(const char *path, const char *name, void *value, size_t size)
10210{
10211 /* Hack to share code. */
10212 return fgetxattr((int)(Py_uintptr_t)path, name, value, size);
10213}
10214
10215PyDoc_STRVAR(posix_fgetxattr__doc__,
10216"fgetxattr(fd, attr) -> value\n\n\
10217Like getxattr but operate on a fd instead of a path.");
10218
10219static PyObject *
10220posix_fgetxattr(PyObject *self, PyObject *args)
10221{
10222 PyObject *res, *name;
10223 int fd;
10224
10225 if (!PyArg_ParseTuple(args, "iO&:fgetxattr", &fd, PyUnicode_FSConverter, &name))
10226 return NULL;
10227 res = getxattr_common((const char *)(Py_uintptr_t)fd, name, wrap_fgetxattr);
10228 Py_DECREF(name);
10229 return res;
10230}
10231
10232PyDoc_STRVAR(posix_setxattr__doc__,
10233"setxattr(path, attr, value, flags=0)\n\n\
10234Set extended attribute *attr* on *path* to *value*.");
10235
10236static PyObject *
10237posix_setxattr(PyObject *self, PyObject *args)
10238{
10239 PyObject *path, *name;
10240 Py_buffer data;
10241 int flags = 0, err;
10242
10243 if (!PyArg_ParseTuple(args, "O&O&y*|i:setxattr", PyUnicode_FSConverter,
10244 &path, PyUnicode_FSConverter, &name, &data, &flags))
10245 return NULL;
10246 Py_BEGIN_ALLOW_THREADS;
10247 err = setxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10248 data.buf, data.len, flags);
10249 Py_END_ALLOW_THREADS;
10250 Py_DECREF(path);
10251 Py_DECREF(name);
10252 PyBuffer_Release(&data);
10253 if (err)
10254 return posix_error();
10255 Py_RETURN_NONE;
10256}
10257
10258PyDoc_STRVAR(posix_lsetxattr__doc__,
10259"lsetxattr(path, attr, value, flags=0)\n\n\
10260Like setxattr but don't follow symlinks.");
10261
10262static PyObject *
10263posix_lsetxattr(PyObject *self, PyObject *args)
10264{
10265 PyObject *path, *name;
10266 Py_buffer data;
10267 int flags = 0, err;
10268
10269 if (!PyArg_ParseTuple(args, "O&O&y*|i:lsetxattr", PyUnicode_FSConverter,
10270 &path, PyUnicode_FSConverter, &name, &data, &flags))
10271 return NULL;
10272 Py_BEGIN_ALLOW_THREADS;
10273 err = lsetxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10274 data.buf, data.len, flags);
10275 Py_END_ALLOW_THREADS;
10276 Py_DECREF(path);
10277 Py_DECREF(name);
10278 PyBuffer_Release(&data);
10279 if (err)
10280 return posix_error();
10281 Py_RETURN_NONE;
10282}
10283
10284PyDoc_STRVAR(posix_fsetxattr__doc__,
10285"fsetxattr(fd, attr, value, flags=0)\n\n\
10286Like setxattr but operates on *fd* instead of a path.");
10287
10288static PyObject *
10289posix_fsetxattr(PyObject *self, PyObject *args)
10290{
10291 Py_buffer data;
10292 const char *name;
10293 int fd, flags = 0, err;
10294
10295 if (!PyArg_ParseTuple(args, "iO&y*|i:fsetxattr", &fd, PyUnicode_FSConverter,
10296 &name, &data, &flags))
10297 return NULL;
10298 Py_BEGIN_ALLOW_THREADS;
10299 err = fsetxattr(fd, PyBytes_AS_STRING(name), data.buf, data.len, flags);
10300 Py_END_ALLOW_THREADS;
10301 Py_DECREF(name);
10302 PyBuffer_Release(&data);
10303 if (err)
10304 return posix_error();
10305 Py_RETURN_NONE;
10306}
10307
10308PyDoc_STRVAR(posix_removexattr__doc__,
10309"removexattr(path, attr)\n\n\
10310Remove extended attribute *attr* on *path*.");
10311
10312static PyObject *
10313posix_removexattr(PyObject *self, PyObject *args)
10314{
10315 PyObject *path, *name;
10316 int err;
10317
10318 if (!PyArg_ParseTuple(args, "O&O&:removexattr", PyUnicode_FSConverter, &path,
10319 PyUnicode_FSConverter, &name))
10320 return NULL;
10321 Py_BEGIN_ALLOW_THREADS;
10322 err = removexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10323 Py_END_ALLOW_THREADS;
10324 Py_DECREF(path);
10325 Py_DECREF(name);
10326 if (err)
10327 return posix_error();
10328 Py_RETURN_NONE;
10329}
10330
10331PyDoc_STRVAR(posix_lremovexattr__doc__,
10332"lremovexattr(path, attr)\n\n\
10333Like removexattr but don't follow symlinks.");
10334
10335static PyObject *
10336posix_lremovexattr(PyObject *self, PyObject *args)
10337{
10338 PyObject *path, *name;
10339 int err;
10340
10341 if (!PyArg_ParseTuple(args, "O&O&:lremovexattr", PyUnicode_FSConverter, &path,
10342 PyUnicode_FSConverter, &name))
10343 return NULL;
10344 Py_BEGIN_ALLOW_THREADS;
10345 err = lremovexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10346 Py_END_ALLOW_THREADS;
10347 Py_DECREF(path);
10348 Py_DECREF(name);
10349 if (err)
10350 return posix_error();
10351 Py_RETURN_NONE;
10352}
10353
10354PyDoc_STRVAR(posix_fremovexattr__doc__,
10355"fremovexattr(fd, attr)\n\n\
10356Like removexattr but operates on a file descriptor.");
10357
10358static PyObject *
10359posix_fremovexattr(PyObject *self, PyObject *args)
10360{
10361 PyObject *name;
10362 int fd, err;
10363
10364 if (!PyArg_ParseTuple(args, "iO&:fremovexattr", &fd,
10365 PyUnicode_FSConverter, &name))
10366 return NULL;
10367 Py_BEGIN_ALLOW_THREADS;
10368 err = fremovexattr(fd, PyBytes_AS_STRING(name));
10369 Py_END_ALLOW_THREADS;
10370 Py_DECREF(name);
10371 if (err)
10372 return posix_error();
10373 Py_RETURN_NONE;
10374}
10375
10376static Py_ssize_t
10377try_listxattr(const char *path, ssize_t (*list)(const char *, char *, size_t),
10378 Py_ssize_t buf_size, char **buf)
10379{
10380 Py_ssize_t len;
10381
10382 *buf = PyMem_MALLOC(buf_size);
10383 if (!*buf) {
10384 PyErr_NoMemory();
10385 return -1;
10386 }
10387 Py_BEGIN_ALLOW_THREADS;
10388 len = list(path, *buf, buf_size);
10389 Py_END_ALLOW_THREADS;
10390 if (len < 0) {
10391 PyMem_FREE(*buf);
10392 if (errno != ERANGE)
10393 posix_error();
10394 return -1;
10395 }
10396 return len;
10397}
10398
10399static PyObject *
10400listxattr_common(const char *path, ssize_t (*list)(const char *, char *, size_t))
10401{
10402 PyObject *res, *attr;
10403 Py_ssize_t len, err, start, i;
10404 char *buf;
10405
10406 len = try_listxattr(path, list, 256, &buf);
10407 if (len < 0) {
10408 if (PyErr_Occurred())
10409 return NULL;
10410 len = try_listxattr(path, list, XATTR_LIST_MAX, &buf);
10411 if (len < 0)
10412 return NULL;
10413 }
10414 res = PyList_New(0);
10415 if (!res) {
10416 PyMem_FREE(buf);
10417 return NULL;
10418 }
10419 for (start = i = 0; i < len; i++) {
10420 if (!buf[i]) {
10421 attr = PyUnicode_DecodeFSDefaultAndSize(&buf[start], i - start);
10422 if (!attr) {
10423 Py_DECREF(res);
10424 PyMem_FREE(buf);
10425 return NULL;
10426 }
10427 err = PyList_Append(res, attr);
10428 Py_DECREF(attr);
10429 if (err) {
10430 Py_DECREF(res);
10431 PyMem_FREE(buf);
10432 return NULL;
10433 }
10434 start = i + 1;
10435 }
10436 }
10437 PyMem_FREE(buf);
10438 return res;
10439}
10440
10441PyDoc_STRVAR(posix_listxattr__doc__,
10442"listxattr(path)\n\n\
10443Return a list of extended attributes on *path*.");
10444
10445static PyObject *
10446posix_listxattr(PyObject *self, PyObject *args)
10447{
10448 PyObject *path, *res;
10449
10450 if (!PyArg_ParseTuple(args, "O&:listxattr", PyUnicode_FSConverter, &path))
10451 return NULL;
10452 res = listxattr_common(PyBytes_AS_STRING(path), listxattr);
10453 Py_DECREF(path);
10454 return res;
10455}
10456
10457PyDoc_STRVAR(posix_llistxattr__doc__,
10458"llistxattr(path)\n\n\
10459Like listxattr but don't follow symlinks..");
10460
10461static PyObject *
10462posix_llistxattr(PyObject *self, PyObject *args)
10463{
10464 PyObject *path, *res;
10465
10466 if (!PyArg_ParseTuple(args, "O&:llistxattr", PyUnicode_FSConverter, &path))
10467 return NULL;
10468 res = listxattr_common(PyBytes_AS_STRING(path), llistxattr);
10469 Py_DECREF(path);
10470 return res;
10471}
10472
10473static ssize_t
10474wrap_flistxattr(const char *path, char *buf, size_t len)
10475{
10476 /* Hack to share code. */
10477 return flistxattr((int)(Py_uintptr_t)path, buf, len);
10478}
10479
10480PyDoc_STRVAR(posix_flistxattr__doc__,
10481"flistxattr(path)\n\n\
10482Like flistxattr but operates on a file descriptor.");
10483
10484static PyObject *
10485posix_flistxattr(PyObject *self, PyObject *args)
10486{
10487 long fd;
10488
10489 if (!PyArg_ParseTuple(args, "i:flistxattr", &fd))
10490 return NULL;
10491 return listxattr_common((const char *)(Py_uintptr_t)fd, wrap_flistxattr);
10492}
10493
Benjamin Peterson9428d532011-09-14 11:45:52 -040010494#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010495
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010496static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010498#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010500#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010501 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010502#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010504#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010506#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010507 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010508#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010509#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010510 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010511#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010512#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010513 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010514#endif /* HAVE_LCHMOD */
10515#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010516 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010517#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010518#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010519 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010520#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010521#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010522 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010523#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010524#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010525 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010526#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010527#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010529#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +000010530#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010531 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10532 METH_NOARGS, posix_getcwd__doc__},
10533 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10534 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +000010535#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010536#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010537 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010538#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010540#ifdef HAVE_FDOPENDIR
10541 {"fdlistdir", posix_fdlistdir, METH_VARARGS, posix_fdlistdir__doc__},
10542#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
10544 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010545#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010546 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010547#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010548#ifdef HAVE_GETPRIORITY
10549 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10550#endif /* HAVE_GETPRIORITY */
10551#ifdef HAVE_SETPRIORITY
10552 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10553#endif /* HAVE_SETPRIORITY */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010554#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010555 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010556#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010557#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010558 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010559#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010560 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
10561 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
10562 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010563 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Brian Curtin52173d42010-12-02 18:29:18 +000010564#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010566#endif /* HAVE_SYMLINK */
Brian Curtin52173d42010-12-02 18:29:18 +000010567#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010568 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
Brian Curtin52173d42010-12-02 18:29:18 +000010569 win_symlink__doc__},
10570#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010571#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010572 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010573#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010574 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010575#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010576 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010577#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
10579 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
10580 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010581#ifdef HAVE_FUTIMES
10582 {"futimes", posix_futimes, METH_VARARGS, posix_futimes__doc__},
10583#endif
10584#ifdef HAVE_LUTIMES
10585 {"lutimes", posix_lutimes, METH_VARARGS, posix_lutimes__doc__},
10586#endif
10587#ifdef HAVE_FUTIMENS
10588 {"futimens", posix_futimens, METH_VARARGS, posix_futimens__doc__},
10589#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010590#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010591 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010592#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010593 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010594#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
10596 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010597#endif /* HAVE_EXECV */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010598#ifdef HAVE_FEXECVE
10599 {"fexecve", posix_fexecve, METH_VARARGS, posix_fexecve__doc__},
10600#endif
Guido van Rossuma1065681999-01-25 23:20:23 +000010601#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010602 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10603 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010604#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10606 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010607#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010608#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010609#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010610 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010611#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010612#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010613 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010614#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010615#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010616#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010617 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10618 {"sched_get_priority_min", posix_sched_get_priority_min, METH_VARARGS, posix_sched_get_priority_min__doc__},
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010619#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010620#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010621 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010622#endif
10623#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010624 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010625#endif
10626#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010627 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010628#endif
10629#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010630 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010631#endif
10632#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010633 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010634#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010635 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010636#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010637 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10638 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10639#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010640#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010641#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010642 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010643#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010644#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010645 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010646#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010647#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010649#endif /* HAVE_GETEGID */
10650#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010651 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010652#endif /* HAVE_GETEUID */
10653#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010654 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010655#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010656#ifdef HAVE_GETGROUPLIST
10657 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10658#endif
Fred Drakec9680921999-12-13 16:37:25 +000010659#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010660 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010661#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010662 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010663#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010664 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010665#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010666#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010667 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010668#endif /* HAVE_GETPPID */
10669#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010670 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010671#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010672#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010673 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010674#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010675#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010676 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010677#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010678#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010680#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010681#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010682 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010683#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010684#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10686 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +000010687 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010688#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010689#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010691#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010692#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010694#endif /* HAVE_SETEUID */
10695#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010697#endif /* HAVE_SETEGID */
10698#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010700#endif /* HAVE_SETREUID */
10701#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010703#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010704#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010706#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010707#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010709#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010710#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010712#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010713#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010715#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010716#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010718#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010719#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010721#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010722#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010724#endif /* HAVE_WAIT3 */
10725#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +000010726 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010727#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010728#if defined(HAVE_WAITID) && !defined(__APPLE__)
10729 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10730#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010731#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010732 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010733#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010734#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010736#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010737#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010739#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010740#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010741 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010742#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010743#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010744 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010745#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010746#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010748#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +000010749 {"open", posix_open, METH_VARARGS, posix_open__doc__},
10750 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10751 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10752 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10753 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10754 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010755#ifdef HAVE_LOCKF
10756 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10757#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010758 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10759 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010760#ifdef HAVE_READV
10761 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10762#endif
10763#ifdef HAVE_PREAD
10764 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10765#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010766 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010767#ifdef HAVE_WRITEV
10768 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10769#endif
10770#ifdef HAVE_PWRITE
10771 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10772#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010773#ifdef HAVE_SENDFILE
10774 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10775 posix_sendfile__doc__},
10776#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010777 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
10778 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010779#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010780 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010781#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010782#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010783 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010784#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010785#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +000010786 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010787#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010788#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +000010789 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010790#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010791#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010792 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10793 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10794 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010795#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010796#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010797 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010798#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010799#ifdef HAVE_TRUNCATE
10800 {"truncate", posix_truncate, METH_VARARGS, posix_truncate__doc__},
10801#endif
10802#ifdef HAVE_POSIX_FALLOCATE
10803 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10804#endif
10805#ifdef HAVE_POSIX_FADVISE
10806 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10807#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010808#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010809 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010810#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010811#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010812 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010813#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010815#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010817#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010818#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010819 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010820#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010821#ifdef HAVE_SYNC
10822 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10823#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010824#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010825 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010826#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010827#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010828#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010829 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010830#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010831#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010832 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010833#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010834#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010835 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010836#endif /* WIFSTOPPED */
10837#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010838 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010839#endif /* WIFSIGNALED */
10840#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010841 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010842#endif /* WIFEXITED */
10843#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010844 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010845#endif /* WEXITSTATUS */
10846#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010847 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010848#endif /* WTERMSIG */
10849#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010851#endif /* WSTOPSIG */
10852#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010853#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010855#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010856#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010857 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010858#endif
Fred Drakec9680921999-12-13 16:37:25 +000010859#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010860 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010861#endif
10862#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010863 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010864#endif
10865#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010866 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010867#endif
10868#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010869 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010870#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010871 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010872#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010874 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000010875 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010876 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010877 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010878#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010879#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010880 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010881#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +000010882 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010883 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +000010884 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010885 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +000010886 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010887 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010888#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010889 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010890#endif
10891#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010892 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010893#endif
10894#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010895 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010896#endif
10897#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010898 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010899#endif
10900
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010901/* posix *at family of functions */
10902#ifdef HAVE_FACCESSAT
10903 {"faccessat", posix_faccessat, METH_VARARGS, posix_faccessat__doc__},
10904#endif
10905#ifdef HAVE_FCHMODAT
10906 {"fchmodat", posix_fchmodat, METH_VARARGS, posix_fchmodat__doc__},
10907#endif /* HAVE_FCHMODAT */
10908#ifdef HAVE_FCHOWNAT
10909 {"fchownat", posix_fchownat, METH_VARARGS, posix_fchownat__doc__},
10910#endif /* HAVE_FCHOWNAT */
10911#ifdef HAVE_FSTATAT
10912 {"fstatat", posix_fstatat, METH_VARARGS, posix_fstatat__doc__},
10913#endif
10914#ifdef HAVE_FUTIMESAT
10915 {"futimesat", posix_futimesat, METH_VARARGS, posix_futimesat__doc__},
10916#endif
10917#ifdef HAVE_LINKAT
10918 {"linkat", posix_linkat, METH_VARARGS, posix_linkat__doc__},
10919#endif /* HAVE_LINKAT */
10920#ifdef HAVE_MKDIRAT
10921 {"mkdirat", posix_mkdirat, METH_VARARGS, posix_mkdirat__doc__},
10922#endif
10923#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
10924 {"mknodat", posix_mknodat, METH_VARARGS, posix_mknodat__doc__},
10925#endif
10926#ifdef HAVE_OPENAT
10927 {"openat", posix_openat, METH_VARARGS, posix_openat__doc__},
10928#endif
10929#ifdef HAVE_READLINKAT
10930 {"readlinkat", posix_readlinkat, METH_VARARGS, posix_readlinkat__doc__},
10931#endif /* HAVE_READLINKAT */
10932#ifdef HAVE_RENAMEAT
10933 {"renameat", posix_renameat, METH_VARARGS, posix_renameat__doc__},
10934#endif
10935#if HAVE_SYMLINKAT
10936 {"symlinkat", posix_symlinkat, METH_VARARGS, posix_symlinkat__doc__},
10937#endif /* HAVE_SYMLINKAT */
10938#ifdef HAVE_UNLINKAT
10939 {"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__},
10940#endif
10941#ifdef HAVE_UTIMENSAT
10942 {"utimensat", posix_utimensat, METH_VARARGS, posix_utimensat__doc__},
10943#endif
10944#ifdef HAVE_MKFIFOAT
10945 {"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__},
10946#endif
Benjamin Peterson9428d532011-09-14 11:45:52 -040010947#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010948 {"setxattr", posix_setxattr, METH_VARARGS, posix_setxattr__doc__},
10949 {"lsetxattr", posix_lsetxattr, METH_VARARGS, posix_lsetxattr__doc__},
10950 {"fsetxattr", posix_fsetxattr, METH_VARARGS, posix_fsetxattr__doc__},
10951 {"getxattr", posix_getxattr, METH_VARARGS, posix_getxattr__doc__},
10952 {"lgetxattr", posix_lgetxattr, METH_VARARGS, posix_lgetxattr__doc__},
10953 {"fgetxattr", posix_fgetxattr, METH_VARARGS, posix_fgetxattr__doc__},
10954 {"removexattr", posix_removexattr, METH_VARARGS, posix_removexattr__doc__},
10955 {"lremovexattr", posix_lremovexattr, METH_VARARGS, posix_lremovexattr__doc__},
10956 {"fremovexattr", posix_fremovexattr, METH_VARARGS, posix_fremovexattr__doc__},
10957 {"listxattr", posix_listxattr, METH_VARARGS, posix_listxattr__doc__},
10958 {"llistxattr", posix_llistxattr, METH_VARARGS, posix_llistxattr__doc__},
10959 {"flistxattr", posix_flistxattr, METH_VARARGS, posix_flistxattr__doc__},
10960#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010961 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010962};
10963
10964
Barry Warsaw4a342091996-12-19 23:50:02 +000010965static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010966ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000010967{
Victor Stinner8c62be82010-05-06 00:08:46 +000010968 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000010969}
10970
Guido van Rossumd48f2521997-12-05 22:19:34 +000010971#if defined(PYOS_OS2)
10972/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000010973static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000010974{
10975 APIRET rc;
10976 ULONG values[QSV_MAX+1];
10977 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000010978 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000010979
10980 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000010981 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000010982 Py_END_ALLOW_THREADS
10983
10984 if (rc != NO_ERROR) {
10985 os2_error(rc);
10986 return -1;
10987 }
10988
Fred Drake4d1e64b2002-04-15 19:40:07 +000010989 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
10990 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
10991 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
10992 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
10993 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
10994 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
10995 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000010996
10997 switch (values[QSV_VERSION_MINOR]) {
10998 case 0: ver = "2.00"; break;
10999 case 10: ver = "2.10"; break;
11000 case 11: ver = "2.11"; break;
11001 case 30: ver = "3.00"; break;
11002 case 40: ver = "4.00"; break;
11003 case 50: ver = "5.00"; break;
11004 default:
Tim Peters885d4572001-11-28 20:27:42 +000011005 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011006 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011007 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011008 ver = &tmp[0];
11009 }
11010
11011 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011012 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011013 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011014
11015 /* Add Indicator of Which Drive was Used to Boot the System */
11016 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11017 tmp[1] = ':';
11018 tmp[2] = '\0';
11019
Fred Drake4d1e64b2002-04-15 19:40:07 +000011020 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011021}
11022#endif
11023
Brian Curtin52173d42010-12-02 18:29:18 +000011024#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011025static int
Brian Curtin52173d42010-12-02 18:29:18 +000011026enable_symlink()
11027{
11028 HANDLE tok;
11029 TOKEN_PRIVILEGES tok_priv;
11030 LUID luid;
11031 int meth_idx = 0;
11032
11033 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011034 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011035
11036 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011037 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011038
11039 tok_priv.PrivilegeCount = 1;
11040 tok_priv.Privileges[0].Luid = luid;
11041 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11042
11043 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11044 sizeof(TOKEN_PRIVILEGES),
11045 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011046 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011047
Brian Curtin3b4499c2010-12-28 14:31:47 +000011048 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11049 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011050}
11051#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11052
Barry Warsaw4a342091996-12-19 23:50:02 +000011053static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011054all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011055{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011056#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011057 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011058#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011059#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011060 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011061#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011062#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011063 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011064#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011065#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011066 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011067#endif
Fred Drakec9680921999-12-13 16:37:25 +000011068#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011069 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011070#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011071#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011072 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011073#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011074#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011075 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011076#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011077#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011078 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011079#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011080#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011081 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011082#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011083#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011084 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011085#endif
11086#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011087 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011088#endif
11089#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011090 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011091#endif
11092#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011093 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011094#endif
11095#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011096 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011097#endif
11098#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011099 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011100#endif
11101#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011102 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011103#endif
11104#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011105 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011106#endif
11107#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011108 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011109#endif
11110#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011111 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011112#endif
11113#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011114 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011115#endif
11116#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011117 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011118#endif
11119#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011120 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011121#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011122#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011123 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011124#endif
11125#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011126 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011127#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011128#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011129 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011130#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011131#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011132 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011133#endif
11134#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011135 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011136#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011137#ifdef PRIO_PROCESS
11138 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11139#endif
11140#ifdef PRIO_PGRP
11141 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11142#endif
11143#ifdef PRIO_USER
11144 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11145#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011146#ifdef O_CLOEXEC
11147 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11148#endif
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011149/* posix - constants for *at functions */
11150#ifdef AT_SYMLINK_NOFOLLOW
11151 if (ins(d, "AT_SYMLINK_NOFOLLOW", (long)AT_SYMLINK_NOFOLLOW)) return -1;
11152#endif
11153#ifdef AT_EACCESS
11154 if (ins(d, "AT_EACCESS", (long)AT_EACCESS)) return -1;
11155#endif
11156#ifdef AT_FDCWD
11157 if (ins(d, "AT_FDCWD", (long)AT_FDCWD)) return -1;
11158#endif
11159#ifdef AT_REMOVEDIR
11160 if (ins(d, "AT_REMOVEDIR", (long)AT_REMOVEDIR)) return -1;
11161#endif
11162#ifdef AT_SYMLINK_FOLLOW
11163 if (ins(d, "AT_SYMLINK_FOLLOW", (long)AT_SYMLINK_FOLLOW)) return -1;
11164#endif
11165#ifdef UTIME_NOW
11166 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11167#endif
11168#ifdef UTIME_OMIT
11169 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11170#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011171
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011172
Tim Peters5aa91602002-01-30 05:46:57 +000011173/* MS Windows */
11174#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011175 /* Don't inherit in child processes. */
11176 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011177#endif
11178#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011179 /* Optimize for short life (keep in memory). */
11180 /* MS forgot to define this one with a non-underscore form too. */
11181 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011182#endif
11183#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011184 /* Automatically delete when last handle is closed. */
11185 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011186#endif
11187#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011188 /* Optimize for random access. */
11189 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011190#endif
11191#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011192 /* Optimize for sequential access. */
11193 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011194#endif
11195
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011196/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011197#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011198 /* Send a SIGIO signal whenever input or output
11199 becomes available on file descriptor */
11200 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011201#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011202#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011203 /* Direct disk access. */
11204 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011205#endif
11206#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011207 /* Must be a directory. */
11208 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011209#endif
11210#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011211 /* Do not follow links. */
11212 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011213#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011214#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011215 /* Do not update the access time. */
11216 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011217#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011218
Victor Stinner8c62be82010-05-06 00:08:46 +000011219 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011220#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011221 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011222#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011223#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011224 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011225#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011226#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011227 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011228#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011229#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011230 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011231#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011232#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011233 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011234#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011235#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011236 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011237#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011238#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011239 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011240#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011241#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011242 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011243#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011244#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011245 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011246#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011247#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011248 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011249#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011250#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011252#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011253#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011254 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011255#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011256#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011257 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011258#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011259#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011260 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011261#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011262#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011263 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011264#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011265#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011266 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011267#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011268#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011269 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011270#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011271
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011272 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011273#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011274 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011275#endif /* ST_RDONLY */
11276#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011277 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011278#endif /* ST_NOSUID */
11279
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011280 /* FreeBSD sendfile() constants */
11281#ifdef SF_NODISKIO
11282 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11283#endif
11284#ifdef SF_MNOWAIT
11285 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11286#endif
11287#ifdef SF_SYNC
11288 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11289#endif
11290
Ross Lagerwall7807c352011-03-17 20:20:30 +020011291 /* constants for posix_fadvise */
11292#ifdef POSIX_FADV_NORMAL
11293 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11294#endif
11295#ifdef POSIX_FADV_SEQUENTIAL
11296 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11297#endif
11298#ifdef POSIX_FADV_RANDOM
11299 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11300#endif
11301#ifdef POSIX_FADV_NOREUSE
11302 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11303#endif
11304#ifdef POSIX_FADV_WILLNEED
11305 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11306#endif
11307#ifdef POSIX_FADV_DONTNEED
11308 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11309#endif
11310
11311 /* constants for waitid */
11312#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11313 if (ins(d, "P_PID", (long)P_PID)) return -1;
11314 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11315 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11316#endif
11317#ifdef WEXITED
11318 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11319#endif
11320#ifdef WNOWAIT
11321 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11322#endif
11323#ifdef WSTOPPED
11324 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11325#endif
11326#ifdef CLD_EXITED
11327 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11328#endif
11329#ifdef CLD_DUMPED
11330 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11331#endif
11332#ifdef CLD_TRAPPED
11333 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11334#endif
11335#ifdef CLD_CONTINUED
11336 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11337#endif
11338
11339 /* constants for lockf */
11340#ifdef F_LOCK
11341 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11342#endif
11343#ifdef F_TLOCK
11344 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11345#endif
11346#ifdef F_ULOCK
11347 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11348#endif
11349#ifdef F_TEST
11350 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11351#endif
11352
11353 /* constants for futimens */
11354#ifdef UTIME_NOW
11355 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11356#endif
11357#ifdef UTIME_OMIT
11358 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11359#endif
11360
Guido van Rossum246bc171999-02-01 23:54:31 +000011361#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011362#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011363 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11364 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11365 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11366 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11367 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11368 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11369 if (ins(d, "P_PM", (long)P_PM)) return -1;
11370 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11371 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11372 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11373 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11374 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11375 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11376 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11377 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11378 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11379 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11380 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11381 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11382 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011383#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011384 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11385 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11386 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11387 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11388 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011389#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011390#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011391
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011392#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011393 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011394 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11395 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11396#ifdef SCHED_SPORADIC
11397 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11398#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011399#ifdef SCHED_BATCH
11400 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11401#endif
11402#ifdef SCHED_IDLE
11403 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11404#endif
11405#ifdef SCHED_RESET_ON_FORK
11406 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11407#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011408#ifdef SCHED_SYS
11409 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11410#endif
11411#ifdef SCHED_IA
11412 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11413#endif
11414#ifdef SCHED_FSS
11415 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11416#endif
11417#ifdef SCHED_FX
11418 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11419#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011420#endif
11421
Benjamin Peterson9428d532011-09-14 11:45:52 -040011422#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011423 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11424 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11425 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11426#endif
11427
Victor Stinner8b905bd2011-10-25 13:34:04 +020011428#ifdef RTLD_LAZY
11429 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11430#endif
11431#ifdef RTLD_NOW
11432 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11433#endif
11434#ifdef RTLD_GLOBAL
11435 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11436#endif
11437#ifdef RTLD_LOCAL
11438 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11439#endif
11440#ifdef RTLD_NODELETE
11441 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11442#endif
11443#ifdef RTLD_NOLOAD
11444 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11445#endif
11446#ifdef RTLD_DEEPBIND
11447 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11448#endif
11449
Guido van Rossumd48f2521997-12-05 22:19:34 +000011450#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011451 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011452#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011453 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011454}
11455
11456
Tim Peters5aa91602002-01-30 05:46:57 +000011457#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011458#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011459#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011460
11461#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011462#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011463#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011464
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011465#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011466#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011467#define MODNAME "posix"
11468#endif
11469
Martin v. Löwis1a214512008-06-11 05:26:20 +000011470static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011471 PyModuleDef_HEAD_INIT,
11472 MODNAME,
11473 posix__doc__,
11474 -1,
11475 posix_methods,
11476 NULL,
11477 NULL,
11478 NULL,
11479 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011480};
11481
11482
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011483PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011484INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011485{
Victor Stinner8c62be82010-05-06 00:08:46 +000011486 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +000011487
Brian Curtin52173d42010-12-02 18:29:18 +000011488#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011489 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011490#endif
11491
Victor Stinner8c62be82010-05-06 00:08:46 +000011492 m = PyModule_Create(&posixmodule);
11493 if (m == NULL)
11494 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011495
Victor Stinner8c62be82010-05-06 00:08:46 +000011496 /* Initialize environ dictionary */
11497 v = convertenviron();
11498 Py_XINCREF(v);
11499 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11500 return NULL;
11501 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011502
Victor Stinner8c62be82010-05-06 00:08:46 +000011503 if (all_ins(m))
11504 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011505
Victor Stinner8c62be82010-05-06 00:08:46 +000011506 if (setup_confname_tables(m))
11507 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011508
Victor Stinner8c62be82010-05-06 00:08:46 +000011509 Py_INCREF(PyExc_OSError);
11510 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011511
Benjamin Peterson2740af82011-08-02 17:41:34 -050011512#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011513 if (PyType_Ready(&cpu_set_type) < 0)
11514 return NULL;
11515 Py_INCREF(&cpu_set_type);
11516 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011517#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011518
Guido van Rossumb3d39562000-01-31 18:41:26 +000011519#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011520 if (posix_putenv_garbage == NULL)
11521 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011522#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011523
Victor Stinner8c62be82010-05-06 00:08:46 +000011524 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011525#if defined(HAVE_WAITID) && !defined(__APPLE__)
11526 waitid_result_desc.name = MODNAME ".waitid_result";
11527 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11528#endif
11529
Victor Stinner8c62be82010-05-06 00:08:46 +000011530 stat_result_desc.name = MODNAME ".stat_result";
11531 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11532 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11533 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11534 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11535 structseq_new = StatResultType.tp_new;
11536 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011537
Victor Stinner8c62be82010-05-06 00:08:46 +000011538 statvfs_result_desc.name = MODNAME ".statvfs_result";
11539 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011540#ifdef NEED_TICKS_PER_SECOND
11541# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011542 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011543# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011544 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011545# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011547# endif
11548#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011549
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011550#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011551 sched_param_desc.name = MODNAME ".sched_param";
11552 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11553 SchedParamType.tp_new = sched_param_new;
11554#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011556#if defined(HAVE_WAITID) && !defined(__APPLE__)
11557 Py_INCREF((PyObject*) &WaitidResultType);
11558 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11559#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011560 Py_INCREF((PyObject*) &StatResultType);
11561 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11562 Py_INCREF((PyObject*) &StatVFSResultType);
11563 PyModule_AddObject(m, "statvfs_result",
11564 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011565
11566#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011567 Py_INCREF(&SchedParamType);
11568 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011569#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011570 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011571
11572#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011573 /*
11574 * Step 2 of weak-linking support on Mac OS X.
11575 *
11576 * The code below removes functions that are not available on the
11577 * currently active platform.
11578 *
11579 * This block allow one to use a python binary that was build on
11580 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
11581 * OSX 10.4.
11582 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011583#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011584 if (fstatvfs == NULL) {
11585 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11586 return NULL;
11587 }
11588 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011589#endif /* HAVE_FSTATVFS */
11590
11591#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011592 if (statvfs == NULL) {
11593 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11594 return NULL;
11595 }
11596 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011597#endif /* HAVE_STATVFS */
11598
11599# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011600 if (lchown == NULL) {
11601 if (PyObject_DelAttrString(m, "lchown") == -1) {
11602 return NULL;
11603 }
11604 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011605#endif /* HAVE_LCHOWN */
11606
11607
11608#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +000011609 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011610
Guido van Rossumb6775db1994-08-01 11:34:53 +000011611}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011612
11613#ifdef __cplusplus
11614}
11615#endif