blob: f4476b7d5eff43bf728157b73748b73c5ac44cb4 [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__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003537"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003538utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003539Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003540second form is used, set the access and modified times to the 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
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 PyObject *arg;
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
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 if (PyArg_ParseTuple(args, "UO|: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
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 if (!PyArg_ParseTuple(args, "O&O:utime",
3575 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
3592 if (arg == Py_None) {
3593 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;
3636 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003637
Victor Stinner8c62be82010-05-06 00:08:46 +00003638 if (!PyArg_ParseTuple(args, "O&O:utime",
3639 PyUnicode_FSConverter, &opath, &arg))
3640 return NULL;
3641 path = PyBytes_AsString(opath);
3642 if (arg == Py_None) {
3643 /* 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__,
3709"futimes(fd, (atime, mtime))\n\
3710futimes(fd, None)\n\n\
3711Set the access and modified time of the file specified by the file\n\
3712descriptor fd to the given values. If the second form is used, set the\n\
3713access and modified times to the current time.");
3714
3715static PyObject *
3716posix_futimes(PyObject *self, PyObject *args)
3717{
3718 int res, fd;
3719 PyObject* arg;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003720 time_t atime, mtime;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003721 long ausec, musec;
3722
3723 if (!PyArg_ParseTuple(args, "iO:futimes", &fd, &arg))
3724 return NULL;
3725
3726 if (arg == Py_None) {
3727 /* optional time values not given */
3728 Py_BEGIN_ALLOW_THREADS
3729 res = futimes(fd, NULL);
3730 Py_END_ALLOW_THREADS
3731 }
3732 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3733 PyErr_SetString(PyExc_TypeError,
3734 "futimes() arg 2 must be a tuple (atime, mtime)");
3735 return NULL;
3736 }
3737 else {
3738 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003739 &atime, &ausec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003740 return NULL;
3741 }
3742 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003743 &mtime, &musec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003744 return NULL;
3745 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003746 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003747 {
3748#ifdef HAVE_FUTIMENS
3749 struct timespec buf[2];
3750 buf[0].tv_sec = atime;
3751 buf[0].tv_nsec = ausec;
3752 buf[1].tv_sec = mtime;
3753 buf[1].tv_nsec = musec;
3754 res = futimens(fd, buf);
3755#else
3756 struct timeval buf[2];
3757 buf[0].tv_sec = atime;
3758 buf[0].tv_usec = ausec;
3759 buf[1].tv_sec = mtime;
3760 buf[1].tv_usec = musec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003761 res = futimes(fd, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003762#endif
3763 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003764 Py_END_ALLOW_THREADS
3765 }
3766 if (res < 0)
3767 return posix_error();
3768 Py_RETURN_NONE;
3769}
3770#endif
3771
3772#ifdef HAVE_LUTIMES
3773PyDoc_STRVAR(posix_lutimes__doc__,
3774"lutimes(path, (atime, mtime))\n\
3775lutimes(path, None)\n\n\
3776Like utime(), but if path is a symbolic link, it is not dereferenced.");
3777
3778static PyObject *
3779posix_lutimes(PyObject *self, PyObject *args)
3780{
3781 PyObject *opath, *arg;
3782 const char *path;
3783 int res;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003784 time_t atime, mtime;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003785 long ausec, musec;
3786
3787 if (!PyArg_ParseTuple(args, "O&O:lutimes",
3788 PyUnicode_FSConverter, &opath, &arg))
3789 return NULL;
3790 path = PyBytes_AsString(opath);
3791 if (arg == Py_None) {
3792 /* optional time values not given */
3793 Py_BEGIN_ALLOW_THREADS
3794 res = lutimes(path, NULL);
3795 Py_END_ALLOW_THREADS
3796 }
3797 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3798 PyErr_SetString(PyExc_TypeError,
3799 "lutimes() arg 2 must be a tuple (atime, mtime)");
3800 Py_DECREF(opath);
3801 return NULL;
3802 }
3803 else {
3804 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003805 &atime, &ausec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003806 Py_DECREF(opath);
3807 return NULL;
3808 }
3809 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003810 &mtime, &musec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003811 Py_DECREF(opath);
3812 return NULL;
3813 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003814 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003815 {
3816#ifdef HAVE_UTIMENSAT
3817 struct timespec buf[2];
3818 buf[0].tv_sec = atime;
3819 buf[0].tv_nsec = ausec;
3820 buf[1].tv_sec = mtime;
3821 buf[1].tv_nsec = musec;
3822 res = utimensat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
3823#else
3824 struct timeval buf[2];
3825 buf[0].tv_sec = atime;
3826 buf[0].tv_usec = ausec;
3827 buf[1].tv_sec = mtime;
3828 buf[1].tv_usec = musec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003829 res = lutimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003830#endif
3831 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003832 Py_END_ALLOW_THREADS
3833 }
3834 Py_DECREF(opath);
3835 if (res < 0)
3836 return posix_error();
3837 Py_RETURN_NONE;
3838}
3839#endif
3840
3841#ifdef HAVE_FUTIMENS
3842PyDoc_STRVAR(posix_futimens__doc__,
3843"futimens(fd, (atime_sec, atime_nsec), (mtime_sec, mtime_nsec))\n\
3844futimens(fd, None, None)\n\n\
3845Updates the timestamps of a file specified by the file descriptor fd, with\n\
3846nanosecond precision.\n\
3847The second form sets atime and mtime to the current time.\n\
3848If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
3849current time.\n\
3850If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
3851
3852static PyObject *
3853posix_futimens(PyObject *self, PyObject *args)
3854{
3855 int res, fd;
3856 PyObject *atime, *mtime;
3857 struct timespec buf[2];
3858
3859 if (!PyArg_ParseTuple(args, "iOO:futimens",
3860 &fd, &atime, &mtime))
3861 return NULL;
3862 if (atime == Py_None && mtime == Py_None) {
3863 /* optional time values not given */
3864 Py_BEGIN_ALLOW_THREADS
3865 res = futimens(fd, NULL);
3866 Py_END_ALLOW_THREADS
3867 }
3868 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
3869 PyErr_SetString(PyExc_TypeError,
3870 "futimens() arg 2 must be a tuple (atime_sec, atime_nsec)");
3871 return NULL;
3872 }
3873 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
3874 PyErr_SetString(PyExc_TypeError,
3875 "futimens() arg 3 must be a tuple (mtime_sec, mtime_nsec)");
3876 return NULL;
3877 }
3878 else {
3879 if (!PyArg_ParseTuple(atime, "ll:futimens",
3880 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
3881 return NULL;
3882 }
3883 if (!PyArg_ParseTuple(mtime, "ll:futimens",
3884 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
3885 return NULL;
3886 }
3887 Py_BEGIN_ALLOW_THREADS
3888 res = futimens(fd, buf);
3889 Py_END_ALLOW_THREADS
3890 }
3891 if (res < 0)
3892 return posix_error();
3893 Py_RETURN_NONE;
3894}
3895#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003896
Guido van Rossum3b066191991-06-04 19:40:25 +00003897/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003898
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003899PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003900"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003901Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003902
Barry Warsaw53699e91996-12-10 23:23:01 +00003903static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003904posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003905{
Victor Stinner8c62be82010-05-06 00:08:46 +00003906 int sts;
3907 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3908 return NULL;
3909 _exit(sts);
3910 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003911}
3912
Martin v. Löwis114619e2002-10-07 06:44:21 +00003913#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3914static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003915free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003916{
Victor Stinner8c62be82010-05-06 00:08:46 +00003917 Py_ssize_t i;
3918 for (i = 0; i < count; i++)
3919 PyMem_Free(array[i]);
3920 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003921}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003922
Antoine Pitrou69f71142009-05-24 21:25:49 +00003923static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003924int fsconvert_strdup(PyObject *o, char**out)
3925{
Victor Stinner8c62be82010-05-06 00:08:46 +00003926 PyObject *bytes;
3927 Py_ssize_t size;
3928 if (!PyUnicode_FSConverter(o, &bytes))
3929 return 0;
3930 size = PyBytes_GET_SIZE(bytes);
3931 *out = PyMem_Malloc(size+1);
3932 if (!*out)
3933 return 0;
3934 memcpy(*out, PyBytes_AsString(bytes), size+1);
3935 Py_DECREF(bytes);
3936 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003937}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003938#endif
3939
Ross Lagerwall7807c352011-03-17 20:20:30 +02003940#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00003941static char**
3942parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3943{
Victor Stinner8c62be82010-05-06 00:08:46 +00003944 char **envlist;
3945 Py_ssize_t i, pos, envc;
3946 PyObject *keys=NULL, *vals=NULL;
3947 PyObject *key, *val, *key2, *val2;
3948 char *p, *k, *v;
3949 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003950
Victor Stinner8c62be82010-05-06 00:08:46 +00003951 i = PyMapping_Size(env);
3952 if (i < 0)
3953 return NULL;
3954 envlist = PyMem_NEW(char *, i + 1);
3955 if (envlist == NULL) {
3956 PyErr_NoMemory();
3957 return NULL;
3958 }
3959 envc = 0;
3960 keys = PyMapping_Keys(env);
3961 vals = PyMapping_Values(env);
3962 if (!keys || !vals)
3963 goto error;
3964 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3965 PyErr_Format(PyExc_TypeError,
3966 "env.keys() or env.values() is not a list");
3967 goto error;
3968 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003969
Victor Stinner8c62be82010-05-06 00:08:46 +00003970 for (pos = 0; pos < i; pos++) {
3971 key = PyList_GetItem(keys, pos);
3972 val = PyList_GetItem(vals, pos);
3973 if (!key || !val)
3974 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003975
Victor Stinner8c62be82010-05-06 00:08:46 +00003976 if (PyUnicode_FSConverter(key, &key2) == 0)
3977 goto error;
3978 if (PyUnicode_FSConverter(val, &val2) == 0) {
3979 Py_DECREF(key2);
3980 goto error;
3981 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003982
3983#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003984 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3985 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003986#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003987 k = PyBytes_AsString(key2);
3988 v = PyBytes_AsString(val2);
3989 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003990
Victor Stinner8c62be82010-05-06 00:08:46 +00003991 p = PyMem_NEW(char, len);
3992 if (p == NULL) {
3993 PyErr_NoMemory();
3994 Py_DECREF(key2);
3995 Py_DECREF(val2);
3996 goto error;
3997 }
3998 PyOS_snprintf(p, len, "%s=%s", k, v);
3999 envlist[envc++] = p;
4000 Py_DECREF(key2);
4001 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004002#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004003 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004004#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004005 }
4006 Py_DECREF(vals);
4007 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004008
Victor Stinner8c62be82010-05-06 00:08:46 +00004009 envlist[envc] = 0;
4010 *envc_ptr = envc;
4011 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004012
4013error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004014 Py_XDECREF(keys);
4015 Py_XDECREF(vals);
4016 while (--envc >= 0)
4017 PyMem_DEL(envlist[envc]);
4018 PyMem_DEL(envlist);
4019 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004020}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004021
Ross Lagerwall7807c352011-03-17 20:20:30 +02004022static char**
4023parse_arglist(PyObject* argv, Py_ssize_t *argc)
4024{
4025 int i;
4026 char **argvlist = PyMem_NEW(char *, *argc+1);
4027 if (argvlist == NULL) {
4028 PyErr_NoMemory();
4029 return NULL;
4030 }
4031 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004032 PyObject* item = PySequence_ITEM(argv, i);
4033 if (item == NULL)
4034 goto fail;
4035 if (!fsconvert_strdup(item, &argvlist[i])) {
4036 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004037 goto fail;
4038 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004039 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004040 }
4041 argvlist[*argc] = NULL;
4042 return argvlist;
4043fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004044 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004045 free_string_array(argvlist, *argc);
4046 return NULL;
4047}
4048#endif
4049
4050#ifdef HAVE_EXECV
4051PyDoc_STRVAR(posix_execv__doc__,
4052"execv(path, args)\n\n\
4053Execute an executable path with arguments, replacing current process.\n\
4054\n\
4055 path: path of executable file\n\
4056 args: tuple or list of strings");
4057
4058static PyObject *
4059posix_execv(PyObject *self, PyObject *args)
4060{
4061 PyObject *opath;
4062 char *path;
4063 PyObject *argv;
4064 char **argvlist;
4065 Py_ssize_t argc;
4066
4067 /* execv has two arguments: (path, argv), where
4068 argv is a list or tuple of strings. */
4069
4070 if (!PyArg_ParseTuple(args, "O&O:execv",
4071 PyUnicode_FSConverter,
4072 &opath, &argv))
4073 return NULL;
4074 path = PyBytes_AsString(opath);
4075 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4076 PyErr_SetString(PyExc_TypeError,
4077 "execv() arg 2 must be a tuple or list");
4078 Py_DECREF(opath);
4079 return NULL;
4080 }
4081 argc = PySequence_Size(argv);
4082 if (argc < 1) {
4083 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4084 Py_DECREF(opath);
4085 return NULL;
4086 }
4087
4088 argvlist = parse_arglist(argv, &argc);
4089 if (argvlist == NULL) {
4090 Py_DECREF(opath);
4091 return NULL;
4092 }
4093
4094 execv(path, argvlist);
4095
4096 /* If we get here it's definitely an error */
4097
4098 free_string_array(argvlist, argc);
4099 Py_DECREF(opath);
4100 return posix_error();
4101}
4102
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004103PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004104"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004105Execute a path with arguments and environment, replacing current process.\n\
4106\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004107 path: path of executable file\n\
4108 args: tuple or list of arguments\n\
4109 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004110
Barry Warsaw53699e91996-12-10 23:23:01 +00004111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004112posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004113{
Victor Stinner8c62be82010-05-06 00:08:46 +00004114 PyObject *opath;
4115 char *path;
4116 PyObject *argv, *env;
4117 char **argvlist;
4118 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004119 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004120
Victor Stinner8c62be82010-05-06 00:08:46 +00004121 /* execve has three arguments: (path, argv, env), where
4122 argv is a list or tuple of strings and env is a dictionary
4123 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004124
Victor Stinner8c62be82010-05-06 00:08:46 +00004125 if (!PyArg_ParseTuple(args, "O&OO:execve",
4126 PyUnicode_FSConverter,
4127 &opath, &argv, &env))
4128 return NULL;
4129 path = PyBytes_AsString(opath);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004130 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004131 PyErr_SetString(PyExc_TypeError,
4132 "execve() arg 2 must be a tuple or list");
4133 goto fail_0;
4134 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004135 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004136 if (!PyMapping_Check(env)) {
4137 PyErr_SetString(PyExc_TypeError,
4138 "execve() arg 3 must be a mapping object");
4139 goto fail_0;
4140 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004141
Ross Lagerwall7807c352011-03-17 20:20:30 +02004142 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004143 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004144 goto fail_0;
4145 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004146
Victor Stinner8c62be82010-05-06 00:08:46 +00004147 envlist = parse_envlist(env, &envc);
4148 if (envlist == NULL)
4149 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004150
Victor Stinner8c62be82010-05-06 00:08:46 +00004151 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00004152
Victor Stinner8c62be82010-05-06 00:08:46 +00004153 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004154
Victor Stinner8c62be82010-05-06 00:08:46 +00004155 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004156
Victor Stinner8c62be82010-05-06 00:08:46 +00004157 while (--envc >= 0)
4158 PyMem_DEL(envlist[envc]);
4159 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004160 fail_1:
Ross Lagerwall7807c352011-03-17 20:20:30 +02004161 free_string_array(argvlist, argc);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004162 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004163 Py_DECREF(opath);
4164 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004165}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004166#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004167
Ross Lagerwall7807c352011-03-17 20:20:30 +02004168#ifdef HAVE_FEXECVE
4169PyDoc_STRVAR(posix_fexecve__doc__,
4170"fexecve(fd, args, env)\n\n\
4171Execute the program specified by a file descriptor with arguments and\n\
4172environment, replacing the current process.\n\
4173\n\
4174 fd: file descriptor of executable\n\
4175 args: tuple or list of arguments\n\
4176 env: dictionary of strings mapping to strings");
4177
4178static PyObject *
4179posix_fexecve(PyObject *self, PyObject *args)
4180{
4181 int fd;
4182 PyObject *argv, *env;
4183 char **argvlist;
4184 char **envlist;
4185 Py_ssize_t argc, envc;
4186
4187 if (!PyArg_ParseTuple(args, "iOO:fexecve",
4188 &fd, &argv, &env))
4189 return NULL;
4190 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4191 PyErr_SetString(PyExc_TypeError,
4192 "fexecve() arg 2 must be a tuple or list");
4193 return NULL;
4194 }
4195 argc = PySequence_Size(argv);
4196 if (!PyMapping_Check(env)) {
4197 PyErr_SetString(PyExc_TypeError,
4198 "fexecve() arg 3 must be a mapping object");
4199 return NULL;
4200 }
4201
4202 argvlist = parse_arglist(argv, &argc);
4203 if (argvlist == NULL)
4204 return NULL;
4205
4206 envlist = parse_envlist(env, &envc);
4207 if (envlist == NULL)
4208 goto fail;
4209
4210 fexecve(fd, argvlist, envlist);
4211
4212 /* If we get here it's definitely an error */
4213
4214 (void) posix_error();
4215
4216 while (--envc >= 0)
4217 PyMem_DEL(envlist[envc]);
4218 PyMem_DEL(envlist);
4219 fail:
4220 free_string_array(argvlist, argc);
4221 return NULL;
4222}
4223#endif /* HAVE_FEXECVE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004224
Guido van Rossuma1065681999-01-25 23:20:23 +00004225#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004226PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004227"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004228Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004229\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004230 mode: mode of process creation\n\
4231 path: path of executable file\n\
4232 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004233
4234static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004235posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004236{
Victor Stinner8c62be82010-05-06 00:08:46 +00004237 PyObject *opath;
4238 char *path;
4239 PyObject *argv;
4240 char **argvlist;
4241 int mode, i;
4242 Py_ssize_t argc;
4243 Py_intptr_t spawnval;
4244 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004245
Victor Stinner8c62be82010-05-06 00:08:46 +00004246 /* spawnv has three arguments: (mode, path, argv), where
4247 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004248
Victor Stinner8c62be82010-05-06 00:08:46 +00004249 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4250 PyUnicode_FSConverter,
4251 &opath, &argv))
4252 return NULL;
4253 path = PyBytes_AsString(opath);
4254 if (PyList_Check(argv)) {
4255 argc = PyList_Size(argv);
4256 getitem = PyList_GetItem;
4257 }
4258 else if (PyTuple_Check(argv)) {
4259 argc = PyTuple_Size(argv);
4260 getitem = PyTuple_GetItem;
4261 }
4262 else {
4263 PyErr_SetString(PyExc_TypeError,
4264 "spawnv() arg 2 must be a tuple or list");
4265 Py_DECREF(opath);
4266 return NULL;
4267 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004268
Victor Stinner8c62be82010-05-06 00:08:46 +00004269 argvlist = PyMem_NEW(char *, argc+1);
4270 if (argvlist == NULL) {
4271 Py_DECREF(opath);
4272 return PyErr_NoMemory();
4273 }
4274 for (i = 0; i < argc; i++) {
4275 if (!fsconvert_strdup((*getitem)(argv, i),
4276 &argvlist[i])) {
4277 free_string_array(argvlist, i);
4278 PyErr_SetString(
4279 PyExc_TypeError,
4280 "spawnv() arg 2 must contain only strings");
4281 Py_DECREF(opath);
4282 return NULL;
4283 }
4284 }
4285 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004286
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004287#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004288 Py_BEGIN_ALLOW_THREADS
4289 spawnval = spawnv(mode, path, argvlist);
4290 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004291#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004292 if (mode == _OLD_P_OVERLAY)
4293 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004294
Victor Stinner8c62be82010-05-06 00:08:46 +00004295 Py_BEGIN_ALLOW_THREADS
4296 spawnval = _spawnv(mode, path, argvlist);
4297 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004298#endif
Tim Peters5aa91602002-01-30 05:46:57 +00004299
Victor Stinner8c62be82010-05-06 00:08:46 +00004300 free_string_array(argvlist, argc);
4301 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004302
Victor Stinner8c62be82010-05-06 00:08:46 +00004303 if (spawnval == -1)
4304 return posix_error();
4305 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004306#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004307 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004308#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004309 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004310#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004311}
4312
4313
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004314PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004315"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004316Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004317\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004318 mode: mode of process creation\n\
4319 path: path of executable file\n\
4320 args: tuple or list of arguments\n\
4321 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004322
4323static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004324posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004325{
Victor Stinner8c62be82010-05-06 00:08:46 +00004326 PyObject *opath;
4327 char *path;
4328 PyObject *argv, *env;
4329 char **argvlist;
4330 char **envlist;
4331 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004332 int mode;
4333 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004334 Py_intptr_t spawnval;
4335 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4336 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004337
Victor Stinner8c62be82010-05-06 00:08:46 +00004338 /* spawnve has four arguments: (mode, path, argv, env), where
4339 argv is a list or tuple of strings and env is a dictionary
4340 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004341
Victor Stinner8c62be82010-05-06 00:08:46 +00004342 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4343 PyUnicode_FSConverter,
4344 &opath, &argv, &env))
4345 return NULL;
4346 path = PyBytes_AsString(opath);
4347 if (PyList_Check(argv)) {
4348 argc = PyList_Size(argv);
4349 getitem = PyList_GetItem;
4350 }
4351 else if (PyTuple_Check(argv)) {
4352 argc = PyTuple_Size(argv);
4353 getitem = PyTuple_GetItem;
4354 }
4355 else {
4356 PyErr_SetString(PyExc_TypeError,
4357 "spawnve() arg 2 must be a tuple or list");
4358 goto fail_0;
4359 }
4360 if (!PyMapping_Check(env)) {
4361 PyErr_SetString(PyExc_TypeError,
4362 "spawnve() arg 3 must be a mapping object");
4363 goto fail_0;
4364 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004365
Victor Stinner8c62be82010-05-06 00:08:46 +00004366 argvlist = PyMem_NEW(char *, argc+1);
4367 if (argvlist == NULL) {
4368 PyErr_NoMemory();
4369 goto fail_0;
4370 }
4371 for (i = 0; i < argc; i++) {
4372 if (!fsconvert_strdup((*getitem)(argv, i),
4373 &argvlist[i]))
4374 {
4375 lastarg = i;
4376 goto fail_1;
4377 }
4378 }
4379 lastarg = argc;
4380 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004381
Victor Stinner8c62be82010-05-06 00:08:46 +00004382 envlist = parse_envlist(env, &envc);
4383 if (envlist == NULL)
4384 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004385
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004386#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004387 Py_BEGIN_ALLOW_THREADS
4388 spawnval = spawnve(mode, path, argvlist, envlist);
4389 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004390#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004391 if (mode == _OLD_P_OVERLAY)
4392 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00004393
Victor Stinner8c62be82010-05-06 00:08:46 +00004394 Py_BEGIN_ALLOW_THREADS
4395 spawnval = _spawnve(mode, path, argvlist, envlist);
4396 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004397#endif
Tim Peters25059d32001-12-07 20:35:43 +00004398
Victor Stinner8c62be82010-05-06 00:08:46 +00004399 if (spawnval == -1)
4400 (void) posix_error();
4401 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004402#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004403 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004404#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004405 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004406#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004407
Victor Stinner8c62be82010-05-06 00:08:46 +00004408 while (--envc >= 0)
4409 PyMem_DEL(envlist[envc]);
4410 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004411 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004412 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004413 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004414 Py_DECREF(opath);
4415 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00004416}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004417
4418/* OS/2 supports spawnvp & spawnvpe natively */
4419#if defined(PYOS_OS2)
4420PyDoc_STRVAR(posix_spawnvp__doc__,
4421"spawnvp(mode, file, args)\n\n\
4422Execute the program 'file' in a new process, using the environment\n\
4423search path to find the file.\n\
4424\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004425 mode: mode of process creation\n\
4426 file: executable file name\n\
4427 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004428
4429static PyObject *
4430posix_spawnvp(PyObject *self, PyObject *args)
4431{
Victor Stinner8c62be82010-05-06 00:08:46 +00004432 PyObject *opath;
4433 char *path;
4434 PyObject *argv;
4435 char **argvlist;
4436 int mode, i, argc;
4437 Py_intptr_t spawnval;
4438 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004439
Victor Stinner8c62be82010-05-06 00:08:46 +00004440 /* spawnvp has three arguments: (mode, path, argv), where
4441 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004442
Victor Stinner8c62be82010-05-06 00:08:46 +00004443 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
4444 PyUnicode_FSConverter,
4445 &opath, &argv))
4446 return NULL;
4447 path = PyBytes_AsString(opath);
4448 if (PyList_Check(argv)) {
4449 argc = PyList_Size(argv);
4450 getitem = PyList_GetItem;
4451 }
4452 else if (PyTuple_Check(argv)) {
4453 argc = PyTuple_Size(argv);
4454 getitem = PyTuple_GetItem;
4455 }
4456 else {
4457 PyErr_SetString(PyExc_TypeError,
4458 "spawnvp() arg 2 must be a tuple or list");
4459 Py_DECREF(opath);
4460 return NULL;
4461 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004462
Victor Stinner8c62be82010-05-06 00:08:46 +00004463 argvlist = PyMem_NEW(char *, argc+1);
4464 if (argvlist == NULL) {
4465 Py_DECREF(opath);
4466 return PyErr_NoMemory();
4467 }
4468 for (i = 0; i < argc; i++) {
4469 if (!fsconvert_strdup((*getitem)(argv, i),
4470 &argvlist[i])) {
4471 free_string_array(argvlist, i);
4472 PyErr_SetString(
4473 PyExc_TypeError,
4474 "spawnvp() arg 2 must contain only strings");
4475 Py_DECREF(opath);
4476 return NULL;
4477 }
4478 }
4479 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004480
Victor Stinner8c62be82010-05-06 00:08:46 +00004481 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004482#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004483 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004484#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004485 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004486#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004487 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004488
Victor Stinner8c62be82010-05-06 00:08:46 +00004489 free_string_array(argvlist, argc);
4490 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004491
Victor Stinner8c62be82010-05-06 00:08:46 +00004492 if (spawnval == -1)
4493 return posix_error();
4494 else
4495 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004496}
4497
4498
4499PyDoc_STRVAR(posix_spawnvpe__doc__,
4500"spawnvpe(mode, file, args, env)\n\n\
4501Execute the program 'file' in a new process, using the environment\n\
4502search path to find the file.\n\
4503\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004504 mode: mode of process creation\n\
4505 file: executable file name\n\
4506 args: tuple or list of arguments\n\
4507 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004508
4509static PyObject *
4510posix_spawnvpe(PyObject *self, PyObject *args)
4511{
Victor Stinner8c62be82010-05-06 00:08:46 +00004512 PyObject *opath
4513 char *path;
4514 PyObject *argv, *env;
4515 char **argvlist;
4516 char **envlist;
4517 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004518 int mode;
4519 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004520 Py_intptr_t spawnval;
4521 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4522 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004523
Victor Stinner8c62be82010-05-06 00:08:46 +00004524 /* spawnvpe has four arguments: (mode, path, argv, env), where
4525 argv is a list or tuple of strings and env is a dictionary
4526 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004527
Victor Stinner8c62be82010-05-06 00:08:46 +00004528 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
4529 PyUnicode_FSConverter,
4530 &opath, &argv, &env))
4531 return NULL;
4532 path = PyBytes_AsString(opath);
4533 if (PyList_Check(argv)) {
4534 argc = PyList_Size(argv);
4535 getitem = PyList_GetItem;
4536 }
4537 else if (PyTuple_Check(argv)) {
4538 argc = PyTuple_Size(argv);
4539 getitem = PyTuple_GetItem;
4540 }
4541 else {
4542 PyErr_SetString(PyExc_TypeError,
4543 "spawnvpe() arg 2 must be a tuple or list");
4544 goto fail_0;
4545 }
4546 if (!PyMapping_Check(env)) {
4547 PyErr_SetString(PyExc_TypeError,
4548 "spawnvpe() arg 3 must be a mapping object");
4549 goto fail_0;
4550 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004551
Victor Stinner8c62be82010-05-06 00:08:46 +00004552 argvlist = PyMem_NEW(char *, argc+1);
4553 if (argvlist == NULL) {
4554 PyErr_NoMemory();
4555 goto fail_0;
4556 }
4557 for (i = 0; i < argc; i++) {
4558 if (!fsconvert_strdup((*getitem)(argv, i),
4559 &argvlist[i]))
4560 {
4561 lastarg = i;
4562 goto fail_1;
4563 }
4564 }
4565 lastarg = argc;
4566 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004567
Victor Stinner8c62be82010-05-06 00:08:46 +00004568 envlist = parse_envlist(env, &envc);
4569 if (envlist == NULL)
4570 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004571
Victor Stinner8c62be82010-05-06 00:08:46 +00004572 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004573#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004574 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004575#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004576 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004577#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004578 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004579
Victor Stinner8c62be82010-05-06 00:08:46 +00004580 if (spawnval == -1)
4581 (void) posix_error();
4582 else
4583 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004584
Victor Stinner8c62be82010-05-06 00:08:46 +00004585 while (--envc >= 0)
4586 PyMem_DEL(envlist[envc]);
4587 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004588 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004589 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004590 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004591 Py_DECREF(opath);
4592 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004593}
4594#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00004595#endif /* HAVE_SPAWNV */
4596
4597
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004598#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004599PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004600"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004601Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4602\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004603Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004604
4605static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004606posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004607{
Victor Stinner8c62be82010-05-06 00:08:46 +00004608 pid_t pid;
4609 int result = 0;
4610 _PyImport_AcquireLock();
4611 pid = fork1();
4612 if (pid == 0) {
4613 /* child: this clobbers and resets the import lock. */
4614 PyOS_AfterFork();
4615 } else {
4616 /* parent: release the import lock. */
4617 result = _PyImport_ReleaseLock();
4618 }
4619 if (pid == -1)
4620 return posix_error();
4621 if (result < 0) {
4622 /* Don't clobber the OSError if the fork failed. */
4623 PyErr_SetString(PyExc_RuntimeError,
4624 "not holding the import lock");
4625 return NULL;
4626 }
4627 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004628}
4629#endif
4630
4631
Guido van Rossumad0ee831995-03-01 10:34:45 +00004632#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004633PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004634"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004635Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004636Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004637
Barry Warsaw53699e91996-12-10 23:23:01 +00004638static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004639posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004640{
Victor Stinner8c62be82010-05-06 00:08:46 +00004641 pid_t pid;
4642 int result = 0;
4643 _PyImport_AcquireLock();
4644 pid = fork();
4645 if (pid == 0) {
4646 /* child: this clobbers and resets the import lock. */
4647 PyOS_AfterFork();
4648 } else {
4649 /* parent: release the import lock. */
4650 result = _PyImport_ReleaseLock();
4651 }
4652 if (pid == -1)
4653 return posix_error();
4654 if (result < 0) {
4655 /* Don't clobber the OSError if the fork failed. */
4656 PyErr_SetString(PyExc_RuntimeError,
4657 "not holding the import lock");
4658 return NULL;
4659 }
4660 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004661}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004662#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004663
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004664#ifdef HAVE_SCHED_H
4665
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004666#ifdef HAVE_SCHED_GET_PRIORITY_MAX
4667
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004668PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
4669"sched_get_priority_max(policy)\n\n\
4670Get the maximum scheduling priority for *policy*.");
4671
4672static PyObject *
4673posix_sched_get_priority_max(PyObject *self, PyObject *args)
4674{
4675 int policy, max;
4676
4677 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
4678 return NULL;
4679 max = sched_get_priority_max(policy);
4680 if (max < 0)
4681 return posix_error();
4682 return PyLong_FromLong(max);
4683}
4684
4685PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
4686"sched_get_priority_min(policy)\n\n\
4687Get the minimum scheduling priority for *policy*.");
4688
4689static PyObject *
4690posix_sched_get_priority_min(PyObject *self, PyObject *args)
4691{
4692 int policy, min;
4693
4694 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
4695 return NULL;
4696 min = sched_get_priority_min(policy);
4697 if (min < 0)
4698 return posix_error();
4699 return PyLong_FromLong(min);
4700}
4701
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004702#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
4703
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004704#ifdef HAVE_SCHED_SETSCHEDULER
4705
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004706PyDoc_STRVAR(posix_sched_getscheduler__doc__,
4707"sched_getscheduler(pid)\n\n\
4708Get the scheduling policy for the process with a PID of *pid*.\n\
4709Passing a PID of 0 returns the scheduling policy for the calling process.");
4710
4711static PyObject *
4712posix_sched_getscheduler(PyObject *self, PyObject *args)
4713{
4714 pid_t pid;
4715 int policy;
4716
4717 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
4718 return NULL;
4719 policy = sched_getscheduler(pid);
4720 if (policy < 0)
4721 return posix_error();
4722 return PyLong_FromLong(policy);
4723}
4724
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004725#endif
4726
4727#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
4728
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004729static PyObject *
4730sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4731{
4732 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05004733 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004734
4735 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
4736 return NULL;
4737 res = PyStructSequence_New(type);
4738 if (!res)
4739 return NULL;
4740 Py_INCREF(priority);
4741 PyStructSequence_SET_ITEM(res, 0, priority);
4742 return res;
4743}
4744
4745PyDoc_STRVAR(sched_param__doc__,
4746"sched_param(sched_priority): A scheduling parameter.\n\n\
4747Current has only one field: sched_priority");
4748
4749static PyStructSequence_Field sched_param_fields[] = {
4750 {"sched_priority", "the scheduling priority"},
4751 {0}
4752};
4753
4754static PyStructSequence_Desc sched_param_desc = {
4755 "sched_param", /* name */
4756 sched_param__doc__, /* doc */
4757 sched_param_fields,
4758 1
4759};
4760
4761static int
4762convert_sched_param(PyObject *param, struct sched_param *res)
4763{
4764 long priority;
4765
4766 if (Py_TYPE(param) != &SchedParamType) {
4767 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
4768 return 0;
4769 }
4770 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
4771 if (priority == -1 && PyErr_Occurred())
4772 return 0;
4773 if (priority > INT_MAX || priority < INT_MIN) {
4774 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
4775 return 0;
4776 }
4777 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
4778 return 1;
4779}
4780
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004781#endif
4782
4783#ifdef HAVE_SCHED_SETSCHEDULER
4784
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004785PyDoc_STRVAR(posix_sched_setscheduler__doc__,
4786"sched_setscheduler(pid, policy, param)\n\n\
4787Set the scheduling policy, *policy*, for *pid*.\n\
4788If *pid* is 0, the calling process is changed.\n\
4789*param* is an instance of sched_param.");
4790
4791static PyObject *
4792posix_sched_setscheduler(PyObject *self, PyObject *args)
4793{
4794 pid_t pid;
4795 int policy;
4796 struct sched_param param;
4797
4798 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
4799 &pid, &policy, &convert_sched_param, &param))
4800 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02004801
4802 /*
Jesus Cea54b01492011-09-10 01:53:19 +02004803 ** sched_setscheduler() returns 0 in Linux, but the previous
4804 ** scheduling policy under Solaris/Illumos, and others.
4805 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02004806 */
4807 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004808 return posix_error();
4809 Py_RETURN_NONE;
4810}
4811
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004812#endif
4813
4814#ifdef HAVE_SCHED_SETPARAM
4815
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004816PyDoc_STRVAR(posix_sched_getparam__doc__,
4817"sched_getparam(pid) -> sched_param\n\n\
4818Returns scheduling parameters for the process with *pid* as an instance of the\n\
4819sched_param class. A PID of 0 means the calling process.");
4820
4821static PyObject *
4822posix_sched_getparam(PyObject *self, PyObject *args)
4823{
4824 pid_t pid;
4825 struct sched_param param;
4826 PyObject *res, *priority;
4827
4828 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
4829 return NULL;
4830 if (sched_getparam(pid, &param))
4831 return posix_error();
4832 res = PyStructSequence_New(&SchedParamType);
4833 if (!res)
4834 return NULL;
4835 priority = PyLong_FromLong(param.sched_priority);
4836 if (!priority) {
4837 Py_DECREF(res);
4838 return NULL;
4839 }
4840 PyStructSequence_SET_ITEM(res, 0, priority);
4841 return res;
4842}
4843
4844PyDoc_STRVAR(posix_sched_setparam__doc__,
4845"sched_setparam(pid, param)\n\n\
4846Set scheduling parameters for a process with PID *pid*.\n\
4847A PID of 0 means the calling process.");
4848
4849static PyObject *
4850posix_sched_setparam(PyObject *self, PyObject *args)
4851{
4852 pid_t pid;
4853 struct sched_param param;
4854
4855 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
4856 &pid, &convert_sched_param, &param))
4857 return NULL;
4858 if (sched_setparam(pid, &param))
4859 return posix_error();
4860 Py_RETURN_NONE;
4861}
4862
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004863#endif
4864
4865#ifdef HAVE_SCHED_RR_GET_INTERVAL
4866
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004867PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
4868"sched_rr_get_interval(pid) -> float\n\n\
4869Return the round-robin quantum for the process with PID *pid* in seconds.");
4870
4871static PyObject *
4872posix_sched_rr_get_interval(PyObject *self, PyObject *args)
4873{
4874 pid_t pid;
4875 struct timespec interval;
4876
4877 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
4878 return NULL;
4879 if (sched_rr_get_interval(pid, &interval))
4880 return posix_error();
4881 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
4882}
4883
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004884#endif
4885
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004886PyDoc_STRVAR(posix_sched_yield__doc__,
4887"sched_yield()\n\n\
4888Voluntarily relinquish the CPU.");
4889
4890static PyObject *
4891posix_sched_yield(PyObject *self, PyObject *noargs)
4892{
4893 if (sched_yield())
4894 return posix_error();
4895 Py_RETURN_NONE;
4896}
4897
Benjamin Peterson2740af82011-08-02 17:41:34 -05004898#ifdef HAVE_SCHED_SETAFFINITY
4899
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004900typedef struct {
4901 PyObject_HEAD;
4902 Py_ssize_t size;
4903 int ncpus;
4904 cpu_set_t *set;
4905} Py_cpu_set;
4906
4907static PyTypeObject cpu_set_type;
4908
4909static void
4910cpu_set_dealloc(Py_cpu_set *set)
4911{
4912 assert(set->set);
4913 CPU_FREE(set->set);
4914 Py_TYPE(set)->tp_free(set);
4915}
4916
4917static Py_cpu_set *
4918make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
4919{
4920 Py_cpu_set *set;
4921
4922 if (size < 0) {
4923 PyErr_SetString(PyExc_ValueError, "negative size");
4924 return NULL;
4925 }
4926 set = (Py_cpu_set *)type->tp_alloc(type, 0);
4927 if (!set)
4928 return NULL;
4929 set->ncpus = size;
4930 set->size = CPU_ALLOC_SIZE(size);
4931 set->set = CPU_ALLOC(size);
4932 if (!set->set) {
4933 type->tp_free(set);
4934 PyErr_NoMemory();
4935 return NULL;
4936 }
4937 CPU_ZERO_S(set->size, set->set);
4938 return set;
4939}
4940
4941static PyObject *
4942cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4943{
4944 int size;
4945
4946 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
4947 !PyArg_ParseTuple(args, "i:cpu_set", &size))
4948 return NULL;
4949 return (PyObject *)make_new_cpu_set(type, size);
4950}
4951
4952static PyObject *
4953cpu_set_repr(Py_cpu_set *set)
4954{
4955 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02004956}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004957
4958static Py_ssize_t
4959cpu_set_len(Py_cpu_set *set)
4960{
4961 return set->ncpus;
4962}
4963
4964static int
4965_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
4966{
4967 int cpu;
4968 if (!PyArg_ParseTuple(args, requester, &cpu))
4969 return -1;
4970 if (cpu < 0) {
4971 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
4972 return -1;
4973 }
4974 if (cpu >= set->ncpus) {
4975 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
4976 return -1;
4977 }
4978 return cpu;
4979}
4980
4981PyDoc_STRVAR(cpu_set_set_doc,
4982"cpu_set.set(i)\n\n\
4983Add CPU *i* to the set.");
4984
4985static PyObject *
4986cpu_set_set(Py_cpu_set *set, PyObject *args)
4987{
4988 int cpu = _get_cpu(set, "i|set", args);
4989 if (cpu == -1)
4990 return NULL;
4991 CPU_SET_S(cpu, set->size, set->set);
4992 Py_RETURN_NONE;
4993}
4994
4995PyDoc_STRVAR(cpu_set_count_doc,
4996"cpu_set.count() -> int\n\n\
4997Return the number of CPUs active in the set.");
4998
4999static PyObject *
5000cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5001{
5002 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5003}
5004
5005PyDoc_STRVAR(cpu_set_clear_doc,
5006"cpu_set.clear(i)\n\n\
5007Remove CPU *i* from the set.");
5008
5009static PyObject *
5010cpu_set_clear(Py_cpu_set *set, PyObject *args)
5011{
5012 int cpu = _get_cpu(set, "i|clear", args);
5013 if (cpu == -1)
5014 return NULL;
5015 CPU_CLR_S(cpu, set->size, set->set);
5016 Py_RETURN_NONE;
5017}
5018
5019PyDoc_STRVAR(cpu_set_isset_doc,
5020"cpu_set.isset(i) -> bool\n\n\
5021Test if CPU *i* is in the set.");
5022
5023static PyObject *
5024cpu_set_isset(Py_cpu_set *set, PyObject *args)
5025{
5026 int cpu = _get_cpu(set, "i|isset", args);
5027 if (cpu == -1)
5028 return NULL;
5029 if (CPU_ISSET_S(cpu, set->size, set->set))
5030 Py_RETURN_TRUE;
5031 Py_RETURN_FALSE;
5032}
5033
5034PyDoc_STRVAR(cpu_set_zero_doc,
5035"cpu_set.zero()\n\n\
5036Clear the cpu_set.");
5037
5038static PyObject *
5039cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5040{
5041 CPU_ZERO_S(set->size, set->set);
5042 Py_RETURN_NONE;
5043}
5044
5045static PyObject *
5046cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5047{
5048 int eq;
5049
Brian Curtindfc80e32011-08-10 20:28:54 -05005050 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5051 Py_RETURN_NOTIMPLEMENTED;
5052
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005053 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5054 if ((op == Py_EQ) ? eq : !eq)
5055 Py_RETURN_TRUE;
5056 else
5057 Py_RETURN_FALSE;
5058}
5059
5060#define CPU_SET_BINOP(name, op) \
5061 static PyObject * \
5062 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5063 if (res) { \
5064 Py_INCREF(res); \
5065 } \
5066 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005067 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005068 if (!res) \
5069 return NULL; \
5070 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005071 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005072 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005073 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005074 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005075 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005076 op(res->size, res->set, left->set, right->set); \
5077 return (PyObject *)res; \
5078 } \
5079 static PyObject * \
5080 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5081 return do_cpu_set_##name(left, right, NULL); \
5082 } \
5083 static PyObject * \
5084 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5085 return do_cpu_set_##name(left, right, left); \
5086 } \
5087
5088CPU_SET_BINOP(and, CPU_AND_S)
5089CPU_SET_BINOP(or, CPU_OR_S)
5090CPU_SET_BINOP(xor, CPU_XOR_S)
5091#undef CPU_SET_BINOP
5092
5093PyDoc_STRVAR(cpu_set_doc,
5094"cpu_set(size)\n\n\
5095Create an empty mask of CPUs.");
5096
5097static PyNumberMethods cpu_set_as_number = {
5098 0, /*nb_add*/
5099 0, /*nb_subtract*/
5100 0, /*nb_multiply*/
5101 0, /*nb_remainder*/
5102 0, /*nb_divmod*/
5103 0, /*nb_power*/
5104 0, /*nb_negative*/
5105 0, /*nb_positive*/
5106 0, /*nb_absolute*/
5107 0, /*nb_bool*/
5108 0, /*nb_invert*/
5109 0, /*nb_lshift*/
5110 0, /*nb_rshift*/
5111 (binaryfunc)cpu_set_and, /*nb_and*/
5112 (binaryfunc)cpu_set_xor, /*nb_xor*/
5113 (binaryfunc)cpu_set_or, /*nb_or*/
5114 0, /*nb_int*/
5115 0, /*nb_reserved*/
5116 0, /*nb_float*/
5117 0, /*nb_inplace_add*/
5118 0, /*nb_inplace_subtract*/
5119 0, /*nb_inplace_multiply*/
5120 0, /*nb_inplace_remainder*/
5121 0, /*nb_inplace_power*/
5122 0, /*nb_inplace_lshift*/
5123 0, /*nb_inplace_rshift*/
5124 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5125 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5126 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5127};
5128
5129static PySequenceMethods cpu_set_as_sequence = {
5130 (lenfunc)cpu_set_len, /* sq_length */
5131};
5132
5133static PyMethodDef cpu_set_methods[] = {
5134 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5135 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5136 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5137 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5138 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5139 {NULL, NULL} /* sentinel */
5140};
5141
5142static PyTypeObject cpu_set_type = {
5143 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5144 "posix.cpu_set", /* tp_name */
5145 sizeof(Py_cpu_set), /* tp_basicsize */
5146 0, /* tp_itemsize */
5147 /* methods */
5148 (destructor)cpu_set_dealloc, /* tp_dealloc */
5149 0, /* tp_print */
5150 0, /* tp_getattr */
5151 0, /* tp_setattr */
5152 0, /* tp_reserved */
5153 (reprfunc)cpu_set_repr, /* tp_repr */
5154 &cpu_set_as_number, /* tp_as_number */
5155 &cpu_set_as_sequence, /* tp_as_sequence */
5156 0, /* tp_as_mapping */
5157 PyObject_HashNotImplemented, /* tp_hash */
5158 0, /* tp_call */
5159 0, /* tp_str */
5160 PyObject_GenericGetAttr, /* tp_getattro */
5161 0, /* tp_setattro */
5162 0, /* tp_as_buffer */
5163 Py_TPFLAGS_DEFAULT, /* tp_flags */
5164 cpu_set_doc, /* tp_doc */
5165 0, /* tp_traverse */
5166 0, /* tp_clear */
5167 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5168 0, /* tp_weaklistoffset */
5169 0, /* tp_iter */
5170 0, /* tp_iternext */
5171 cpu_set_methods, /* tp_methods */
5172 0, /* tp_members */
5173 0, /* tp_getset */
5174 0, /* tp_base */
5175 0, /* tp_dict */
5176 0, /* tp_descr_get */
5177 0, /* tp_descr_set */
5178 0, /* tp_dictoffset */
5179 0, /* tp_init */
5180 PyType_GenericAlloc, /* tp_alloc */
5181 cpu_set_new, /* tp_new */
5182 PyObject_Del, /* tp_free */
5183};
5184
5185PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5186"sched_setaffinity(pid, cpu_set)\n\n\
5187Set the affinity of the process with PID *pid* to *cpu_set*.");
5188
5189static PyObject *
5190posix_sched_setaffinity(PyObject *self, PyObject *args)
5191{
5192 pid_t pid;
5193 Py_cpu_set *cpu_set;
5194
Benjamin Petersona17a5d62011-08-09 16:49:13 -05005195 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005196 &pid, &cpu_set_type, &cpu_set))
5197 return NULL;
5198 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
5199 return posix_error();
5200 Py_RETURN_NONE;
5201}
5202
5203PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5204"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5205Return the affinity of the process with PID *pid*.\n\
5206The returned cpu_set will be of size *ncpus*.");
5207
5208static PyObject *
5209posix_sched_getaffinity(PyObject *self, PyObject *args)
5210{
5211 pid_t pid;
5212 int ncpus;
5213 Py_cpu_set *res;
5214
Benjamin Peterson7ac92142011-08-03 08:54:26 -05005215 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005216 &pid, &ncpus))
5217 return NULL;
5218 res = make_new_cpu_set(&cpu_set_type, ncpus);
5219 if (!res)
5220 return NULL;
5221 if (sched_getaffinity(pid, res->size, res->set)) {
5222 Py_DECREF(res);
5223 return posix_error();
5224 }
5225 return (PyObject *)res;
5226}
5227
Benjamin Peterson2740af82011-08-02 17:41:34 -05005228#endif /* HAVE_SCHED_SETAFFINITY */
5229
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005230#endif /* HAVE_SCHED_H */
5231
Neal Norwitzb59798b2003-03-21 01:43:31 +00005232/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005233/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5234#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005235#define DEV_PTY_FILE "/dev/ptc"
5236#define HAVE_DEV_PTMX
5237#else
5238#define DEV_PTY_FILE "/dev/ptmx"
5239#endif
5240
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005241#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005242#ifdef HAVE_PTY_H
5243#include <pty.h>
5244#else
5245#ifdef HAVE_LIBUTIL_H
5246#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005247#else
5248#ifdef HAVE_UTIL_H
5249#include <util.h>
5250#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005251#endif /* HAVE_LIBUTIL_H */
5252#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005253#ifdef HAVE_STROPTS_H
5254#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005255#endif
5256#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005257
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005258#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005259PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005260"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005261Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005262
5263static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005264posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005265{
Victor Stinner8c62be82010-05-06 00:08:46 +00005266 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005267#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005268 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005269#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005270#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005271 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005272#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005273 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005274#endif
5275#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005276
Thomas Wouters70c21a12000-07-14 14:28:33 +00005277#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005278 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5279 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005280#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005281 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5282 if (slave_name == NULL)
5283 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005284
Victor Stinner8c62be82010-05-06 00:08:46 +00005285 slave_fd = open(slave_name, O_RDWR);
5286 if (slave_fd < 0)
5287 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005288#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005289 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5290 if (master_fd < 0)
5291 return posix_error();
5292 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5293 /* change permission of slave */
5294 if (grantpt(master_fd) < 0) {
5295 PyOS_setsig(SIGCHLD, sig_saved);
5296 return posix_error();
5297 }
5298 /* unlock slave */
5299 if (unlockpt(master_fd) < 0) {
5300 PyOS_setsig(SIGCHLD, sig_saved);
5301 return posix_error();
5302 }
5303 PyOS_setsig(SIGCHLD, sig_saved);
5304 slave_name = ptsname(master_fd); /* get name of slave */
5305 if (slave_name == NULL)
5306 return posix_error();
5307 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5308 if (slave_fd < 0)
5309 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005310#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005311 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5312 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005313#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005315#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005316#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005317#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005318
Victor Stinner8c62be82010-05-06 00:08:46 +00005319 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005320
Fred Drake8cef4cf2000-06-28 16:40:38 +00005321}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005322#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005323
5324#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005325PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005326"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005327Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5328Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005329To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005330
5331static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005332posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005333{
Victor Stinner8c62be82010-05-06 00:08:46 +00005334 int master_fd = -1, result = 0;
5335 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005336
Victor Stinner8c62be82010-05-06 00:08:46 +00005337 _PyImport_AcquireLock();
5338 pid = forkpty(&master_fd, NULL, NULL, NULL);
5339 if (pid == 0) {
5340 /* child: this clobbers and resets the import lock. */
5341 PyOS_AfterFork();
5342 } else {
5343 /* parent: release the import lock. */
5344 result = _PyImport_ReleaseLock();
5345 }
5346 if (pid == -1)
5347 return posix_error();
5348 if (result < 0) {
5349 /* Don't clobber the OSError if the fork failed. */
5350 PyErr_SetString(PyExc_RuntimeError,
5351 "not holding the import lock");
5352 return NULL;
5353 }
5354 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005355}
5356#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005357
Ross Lagerwall7807c352011-03-17 20:20:30 +02005358
Guido van Rossumad0ee831995-03-01 10:34:45 +00005359#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005360PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005361"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005362Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005363
Barry Warsaw53699e91996-12-10 23:23:01 +00005364static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005365posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005366{
Victor Stinner8c62be82010-05-06 00:08:46 +00005367 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005368}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005369#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005370
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005371
Guido van Rossumad0ee831995-03-01 10:34:45 +00005372#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005373PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005374"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005375Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005376
Barry Warsaw53699e91996-12-10 23:23:01 +00005377static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005378posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005379{
Victor Stinner8c62be82010-05-06 00:08:46 +00005380 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005381}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005382#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005383
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005384
Guido van Rossumad0ee831995-03-01 10:34:45 +00005385#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005386PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005387"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005388Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005389
Barry Warsaw53699e91996-12-10 23:23:01 +00005390static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005391posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005392{
Victor Stinner8c62be82010-05-06 00:08:46 +00005393 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005394}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005395#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005396
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005397
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005398PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005399"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005400Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005401
Barry Warsaw53699e91996-12-10 23:23:01 +00005402static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005403posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005404{
Victor Stinner8c62be82010-05-06 00:08:46 +00005405 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005406}
5407
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005408#ifdef HAVE_GETGROUPLIST
5409PyDoc_STRVAR(posix_getgrouplist__doc__,
5410"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5411Returns a list of groups to which a user belongs.\n\n\
5412 user: username to lookup\n\
5413 group: base group id of the user");
5414
5415static PyObject *
5416posix_getgrouplist(PyObject *self, PyObject *args)
5417{
5418#ifdef NGROUPS_MAX
5419#define MAX_GROUPS NGROUPS_MAX
5420#else
5421 /* defined to be 16 on Solaris7, so this should be a small number */
5422#define MAX_GROUPS 64
5423#endif
5424
5425 const char *user;
5426 int i, ngroups;
5427 PyObject *list;
5428#ifdef __APPLE__
5429 int *groups, basegid;
5430#else
5431 gid_t *groups, basegid;
5432#endif
5433 ngroups = MAX_GROUPS;
5434
5435 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5436 return NULL;
5437
5438#ifdef __APPLE__
5439 groups = PyMem_Malloc(ngroups * sizeof(int));
5440#else
5441 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5442#endif
5443 if (groups == NULL)
5444 return PyErr_NoMemory();
5445
5446 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5447 PyMem_Del(groups);
5448 return posix_error();
5449 }
5450
5451 list = PyList_New(ngroups);
5452 if (list == NULL) {
5453 PyMem_Del(groups);
5454 return NULL;
5455 }
5456
5457 for (i = 0; i < ngroups; i++) {
5458 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5459 if (o == NULL) {
5460 Py_DECREF(list);
5461 PyMem_Del(groups);
5462 return NULL;
5463 }
5464 PyList_SET_ITEM(list, i, o);
5465 }
5466
5467 PyMem_Del(groups);
5468
5469 return list;
5470}
5471#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005472
Fred Drakec9680921999-12-13 16:37:25 +00005473#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005474PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005475"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005476Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005477
5478static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005479posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005480{
5481 PyObject *result = NULL;
5482
Fred Drakec9680921999-12-13 16:37:25 +00005483#ifdef NGROUPS_MAX
5484#define MAX_GROUPS NGROUPS_MAX
5485#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005486 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005487#define MAX_GROUPS 64
5488#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005489 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005490
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005491 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005492 * This is a helper variable to store the intermediate result when
5493 * that happens.
5494 *
5495 * To keep the code readable the OSX behaviour is unconditional,
5496 * according to the POSIX spec this should be safe on all unix-y
5497 * systems.
5498 */
5499 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005500 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005501
Victor Stinner8c62be82010-05-06 00:08:46 +00005502 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005503 if (n < 0) {
5504 if (errno == EINVAL) {
5505 n = getgroups(0, NULL);
5506 if (n == -1) {
5507 return posix_error();
5508 }
5509 if (n == 0) {
5510 /* Avoid malloc(0) */
5511 alt_grouplist = grouplist;
5512 } else {
5513 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5514 if (alt_grouplist == NULL) {
5515 errno = EINVAL;
5516 return posix_error();
5517 }
5518 n = getgroups(n, alt_grouplist);
5519 if (n == -1) {
5520 PyMem_Free(alt_grouplist);
5521 return posix_error();
5522 }
5523 }
5524 } else {
5525 return posix_error();
5526 }
5527 }
5528 result = PyList_New(n);
5529 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005530 int i;
5531 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005532 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005533 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005534 Py_DECREF(result);
5535 result = NULL;
5536 break;
Fred Drakec9680921999-12-13 16:37:25 +00005537 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005538 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005539 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005540 }
5541
5542 if (alt_grouplist != grouplist) {
5543 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005544 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005545
Fred Drakec9680921999-12-13 16:37:25 +00005546 return result;
5547}
5548#endif
5549
Antoine Pitroub7572f02009-12-02 20:46:48 +00005550#ifdef HAVE_INITGROUPS
5551PyDoc_STRVAR(posix_initgroups__doc__,
5552"initgroups(username, gid) -> None\n\n\
5553Call the system initgroups() to initialize the group access list with all of\n\
5554the groups of which the specified username is a member, plus the specified\n\
5555group id.");
5556
5557static PyObject *
5558posix_initgroups(PyObject *self, PyObject *args)
5559{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005560 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005561 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005562 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005563 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005564
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005565 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5566 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005567 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005568 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005569
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005570 res = initgroups(username, (gid_t) gid);
5571 Py_DECREF(oname);
5572 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005573 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005574
Victor Stinner8c62be82010-05-06 00:08:46 +00005575 Py_INCREF(Py_None);
5576 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005577}
5578#endif
5579
Martin v. Löwis606edc12002-06-13 21:09:11 +00005580#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005581PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005582"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005583Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005584
5585static PyObject *
5586posix_getpgid(PyObject *self, PyObject *args)
5587{
Victor Stinner8c62be82010-05-06 00:08:46 +00005588 pid_t pid, pgid;
5589 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5590 return NULL;
5591 pgid = getpgid(pid);
5592 if (pgid < 0)
5593 return posix_error();
5594 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005595}
5596#endif /* HAVE_GETPGID */
5597
5598
Guido van Rossumb6775db1994-08-01 11:34:53 +00005599#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005600PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005601"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005602Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005603
Barry Warsaw53699e91996-12-10 23:23:01 +00005604static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005605posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005606{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005607#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005608 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005609#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005610 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005611#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005612}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005613#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005614
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005615
Guido van Rossumb6775db1994-08-01 11:34:53 +00005616#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005617PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005618"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005619Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005620
Barry Warsaw53699e91996-12-10 23:23:01 +00005621static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005622posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005623{
Guido van Rossum64933891994-10-20 21:56:42 +00005624#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005625 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005626#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005627 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005628#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005629 return posix_error();
5630 Py_INCREF(Py_None);
5631 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005632}
5633
Guido van Rossumb6775db1994-08-01 11:34:53 +00005634#endif /* HAVE_SETPGRP */
5635
Guido van Rossumad0ee831995-03-01 10:34:45 +00005636#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005637
5638#ifdef MS_WINDOWS
5639#include <tlhelp32.h>
5640
5641static PyObject*
5642win32_getppid()
5643{
5644 HANDLE snapshot;
5645 pid_t mypid;
5646 PyObject* result = NULL;
5647 BOOL have_record;
5648 PROCESSENTRY32 pe;
5649
5650 mypid = getpid(); /* This function never fails */
5651
5652 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5653 if (snapshot == INVALID_HANDLE_VALUE)
5654 return PyErr_SetFromWindowsErr(GetLastError());
5655
5656 pe.dwSize = sizeof(pe);
5657 have_record = Process32First(snapshot, &pe);
5658 while (have_record) {
5659 if (mypid == (pid_t)pe.th32ProcessID) {
5660 /* We could cache the ulong value in a static variable. */
5661 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5662 break;
5663 }
5664
5665 have_record = Process32Next(snapshot, &pe);
5666 }
5667
5668 /* If our loop exits and our pid was not found (result will be NULL)
5669 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5670 * error anyway, so let's raise it. */
5671 if (!result)
5672 result = PyErr_SetFromWindowsErr(GetLastError());
5673
5674 CloseHandle(snapshot);
5675
5676 return result;
5677}
5678#endif /*MS_WINDOWS*/
5679
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005680PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005681"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005682Return the parent's process id. If the parent process has already exited,\n\
5683Windows machines will still return its id; others systems will return the id\n\
5684of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005685
Barry Warsaw53699e91996-12-10 23:23:01 +00005686static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005687posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005688{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005689#ifdef MS_WINDOWS
5690 return win32_getppid();
5691#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005692 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005693#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005694}
5695#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005696
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005697
Fred Drake12c6e2d1999-12-14 21:25:03 +00005698#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005699PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005700"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005701Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005702
5703static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005704posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005705{
Victor Stinner8c62be82010-05-06 00:08:46 +00005706 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005707#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005708 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02005709 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005710
5711 if (GetUserNameW(user_name, &num_chars)) {
5712 /* num_chars is the number of unicode chars plus null terminator */
5713 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005714 }
5715 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005716 result = PyErr_SetFromWindowsErr(GetLastError());
5717#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005718 char *name;
5719 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005720
Victor Stinner8c62be82010-05-06 00:08:46 +00005721 errno = 0;
5722 name = getlogin();
5723 if (name == NULL) {
5724 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005725 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005726 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005727 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005728 }
5729 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005730 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005731 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005732#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005733 return result;
5734}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005735#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005736
Guido van Rossumad0ee831995-03-01 10:34:45 +00005737#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005738PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005739"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005740Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005741
Barry Warsaw53699e91996-12-10 23:23:01 +00005742static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005743posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005744{
Victor Stinner8c62be82010-05-06 00:08:46 +00005745 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005746}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005747#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005748
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005749
Guido van Rossumad0ee831995-03-01 10:34:45 +00005750#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005751PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005752"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005753Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005754
Barry Warsaw53699e91996-12-10 23:23:01 +00005755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005756posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005757{
Victor Stinner8c62be82010-05-06 00:08:46 +00005758 pid_t pid;
5759 int sig;
5760 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
5761 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005762#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005763 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
5764 APIRET rc;
5765 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005766 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005767
5768 } else if (sig == XCPT_SIGNAL_KILLPROC) {
5769 APIRET rc;
5770 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005771 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005772
5773 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005774 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005775#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005776 if (kill(pid, sig) == -1)
5777 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005778#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005779 Py_INCREF(Py_None);
5780 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00005781}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005782#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005783
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005784#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005785PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005786"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005787Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005788
5789static PyObject *
5790posix_killpg(PyObject *self, PyObject *args)
5791{
Victor Stinner8c62be82010-05-06 00:08:46 +00005792 int sig;
5793 pid_t pgid;
5794 /* XXX some man pages make the `pgid` parameter an int, others
5795 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
5796 take the same type. Moreover, pid_t is always at least as wide as
5797 int (else compilation of this module fails), which is safe. */
5798 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
5799 return NULL;
5800 if (killpg(pgid, sig) == -1)
5801 return posix_error();
5802 Py_INCREF(Py_None);
5803 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005804}
5805#endif
5806
Brian Curtineb24d742010-04-12 17:16:38 +00005807#ifdef MS_WINDOWS
5808PyDoc_STRVAR(win32_kill__doc__,
5809"kill(pid, sig)\n\n\
5810Kill a process with a signal.");
5811
5812static PyObject *
5813win32_kill(PyObject *self, PyObject *args)
5814{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00005815 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005816 DWORD pid, sig, err;
5817 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00005818
Victor Stinner8c62be82010-05-06 00:08:46 +00005819 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
5820 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00005821
Victor Stinner8c62be82010-05-06 00:08:46 +00005822 /* Console processes which share a common console can be sent CTRL+C or
5823 CTRL+BREAK events, provided they handle said events. */
5824 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
5825 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
5826 err = GetLastError();
5827 PyErr_SetFromWindowsErr(err);
5828 }
5829 else
5830 Py_RETURN_NONE;
5831 }
Brian Curtineb24d742010-04-12 17:16:38 +00005832
Victor Stinner8c62be82010-05-06 00:08:46 +00005833 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
5834 attempt to open and terminate the process. */
5835 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
5836 if (handle == NULL) {
5837 err = GetLastError();
5838 return PyErr_SetFromWindowsErr(err);
5839 }
Brian Curtineb24d742010-04-12 17:16:38 +00005840
Victor Stinner8c62be82010-05-06 00:08:46 +00005841 if (TerminateProcess(handle, sig) == 0) {
5842 err = GetLastError();
5843 result = PyErr_SetFromWindowsErr(err);
5844 } else {
5845 Py_INCREF(Py_None);
5846 result = Py_None;
5847 }
Brian Curtineb24d742010-04-12 17:16:38 +00005848
Victor Stinner8c62be82010-05-06 00:08:46 +00005849 CloseHandle(handle);
5850 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00005851}
5852#endif /* MS_WINDOWS */
5853
Guido van Rossumc0125471996-06-28 18:55:32 +00005854#ifdef HAVE_PLOCK
5855
5856#ifdef HAVE_SYS_LOCK_H
5857#include <sys/lock.h>
5858#endif
5859
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005860PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005861"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005862Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005863
Barry Warsaw53699e91996-12-10 23:23:01 +00005864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005865posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00005866{
Victor Stinner8c62be82010-05-06 00:08:46 +00005867 int op;
5868 if (!PyArg_ParseTuple(args, "i:plock", &op))
5869 return NULL;
5870 if (plock(op) == -1)
5871 return posix_error();
5872 Py_INCREF(Py_None);
5873 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00005874}
5875#endif
5876
Guido van Rossumb6775db1994-08-01 11:34:53 +00005877#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005878PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005879"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005880Set the current process's user id.");
5881
Barry Warsaw53699e91996-12-10 23:23:01 +00005882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005883posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005884{
Victor Stinner8c62be82010-05-06 00:08:46 +00005885 long uid_arg;
5886 uid_t uid;
5887 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5888 return NULL;
5889 uid = uid_arg;
5890 if (uid != uid_arg) {
5891 PyErr_SetString(PyExc_OverflowError, "user id too big");
5892 return NULL;
5893 }
5894 if (setuid(uid) < 0)
5895 return posix_error();
5896 Py_INCREF(Py_None);
5897 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005898}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005899#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005901
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005902#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005903PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005904"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005905Set the current process's effective user id.");
5906
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005907static PyObject *
5908posix_seteuid (PyObject *self, PyObject *args)
5909{
Victor Stinner8c62be82010-05-06 00:08:46 +00005910 long euid_arg;
5911 uid_t euid;
5912 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5913 return NULL;
5914 euid = euid_arg;
5915 if (euid != euid_arg) {
5916 PyErr_SetString(PyExc_OverflowError, "user id too big");
5917 return NULL;
5918 }
5919 if (seteuid(euid) < 0) {
5920 return posix_error();
5921 } else {
5922 Py_INCREF(Py_None);
5923 return Py_None;
5924 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005925}
5926#endif /* HAVE_SETEUID */
5927
5928#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005929PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005930"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005931Set the current process's effective group id.");
5932
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005933static PyObject *
5934posix_setegid (PyObject *self, PyObject *args)
5935{
Victor Stinner8c62be82010-05-06 00:08:46 +00005936 long egid_arg;
5937 gid_t egid;
5938 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5939 return NULL;
5940 egid = egid_arg;
5941 if (egid != egid_arg) {
5942 PyErr_SetString(PyExc_OverflowError, "group id too big");
5943 return NULL;
5944 }
5945 if (setegid(egid) < 0) {
5946 return posix_error();
5947 } else {
5948 Py_INCREF(Py_None);
5949 return Py_None;
5950 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005951}
5952#endif /* HAVE_SETEGID */
5953
5954#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005955PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005956"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005957Set the current process's real and effective user ids.");
5958
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005959static PyObject *
5960posix_setreuid (PyObject *self, PyObject *args)
5961{
Victor Stinner8c62be82010-05-06 00:08:46 +00005962 long ruid_arg, euid_arg;
5963 uid_t ruid, euid;
5964 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5965 return NULL;
5966 if (ruid_arg == -1)
5967 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
5968 else
5969 ruid = ruid_arg; /* otherwise, assign from our long */
5970 if (euid_arg == -1)
5971 euid = (uid_t)-1;
5972 else
5973 euid = euid_arg;
5974 if ((euid_arg != -1 && euid != euid_arg) ||
5975 (ruid_arg != -1 && ruid != ruid_arg)) {
5976 PyErr_SetString(PyExc_OverflowError, "user id too big");
5977 return NULL;
5978 }
5979 if (setreuid(ruid, euid) < 0) {
5980 return posix_error();
5981 } else {
5982 Py_INCREF(Py_None);
5983 return Py_None;
5984 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005985}
5986#endif /* HAVE_SETREUID */
5987
5988#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005989PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005990"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005991Set the current process's real and effective group ids.");
5992
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005993static PyObject *
5994posix_setregid (PyObject *self, PyObject *args)
5995{
Victor Stinner8c62be82010-05-06 00:08:46 +00005996 long rgid_arg, egid_arg;
5997 gid_t rgid, egid;
5998 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
5999 return NULL;
6000 if (rgid_arg == -1)
6001 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6002 else
6003 rgid = rgid_arg; /* otherwise, assign from our long */
6004 if (egid_arg == -1)
6005 egid = (gid_t)-1;
6006 else
6007 egid = egid_arg;
6008 if ((egid_arg != -1 && egid != egid_arg) ||
6009 (rgid_arg != -1 && rgid != rgid_arg)) {
6010 PyErr_SetString(PyExc_OverflowError, "group id too big");
6011 return NULL;
6012 }
6013 if (setregid(rgid, egid) < 0) {
6014 return posix_error();
6015 } else {
6016 Py_INCREF(Py_None);
6017 return Py_None;
6018 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006019}
6020#endif /* HAVE_SETREGID */
6021
Guido van Rossumb6775db1994-08-01 11:34:53 +00006022#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006023PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006024"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006025Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006026
Barry Warsaw53699e91996-12-10 23:23:01 +00006027static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006028posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006029{
Victor Stinner8c62be82010-05-06 00:08:46 +00006030 long gid_arg;
6031 gid_t gid;
6032 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6033 return NULL;
6034 gid = gid_arg;
6035 if (gid != gid_arg) {
6036 PyErr_SetString(PyExc_OverflowError, "group id too big");
6037 return NULL;
6038 }
6039 if (setgid(gid) < 0)
6040 return posix_error();
6041 Py_INCREF(Py_None);
6042 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006043}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006044#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006045
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006046#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006047PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006048"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006050
6051static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006052posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006053{
Victor Stinner8c62be82010-05-06 00:08:46 +00006054 int i, len;
6055 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006056
Victor Stinner8c62be82010-05-06 00:08:46 +00006057 if (!PySequence_Check(groups)) {
6058 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6059 return NULL;
6060 }
6061 len = PySequence_Size(groups);
6062 if (len > MAX_GROUPS) {
6063 PyErr_SetString(PyExc_ValueError, "too many groups");
6064 return NULL;
6065 }
6066 for(i = 0; i < len; i++) {
6067 PyObject *elem;
6068 elem = PySequence_GetItem(groups, i);
6069 if (!elem)
6070 return NULL;
6071 if (!PyLong_Check(elem)) {
6072 PyErr_SetString(PyExc_TypeError,
6073 "groups must be integers");
6074 Py_DECREF(elem);
6075 return NULL;
6076 } else {
6077 unsigned long x = PyLong_AsUnsignedLong(elem);
6078 if (PyErr_Occurred()) {
6079 PyErr_SetString(PyExc_TypeError,
6080 "group id too big");
6081 Py_DECREF(elem);
6082 return NULL;
6083 }
6084 grouplist[i] = x;
6085 /* read back the value to see if it fitted in gid_t */
6086 if (grouplist[i] != x) {
6087 PyErr_SetString(PyExc_TypeError,
6088 "group id too big");
6089 Py_DECREF(elem);
6090 return NULL;
6091 }
6092 }
6093 Py_DECREF(elem);
6094 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006095
Victor Stinner8c62be82010-05-06 00:08:46 +00006096 if (setgroups(len, grouplist) < 0)
6097 return posix_error();
6098 Py_INCREF(Py_None);
6099 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006100}
6101#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006102
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006103#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6104static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00006105wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006106{
Victor Stinner8c62be82010-05-06 00:08:46 +00006107 PyObject *result;
6108 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006109 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006110
Victor Stinner8c62be82010-05-06 00:08:46 +00006111 if (pid == -1)
6112 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006113
Victor Stinner8c62be82010-05-06 00:08:46 +00006114 if (struct_rusage == NULL) {
6115 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6116 if (m == NULL)
6117 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006118 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006119 Py_DECREF(m);
6120 if (struct_rusage == NULL)
6121 return NULL;
6122 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006123
Victor Stinner8c62be82010-05-06 00:08:46 +00006124 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6125 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6126 if (!result)
6127 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006128
6129#ifndef doubletime
6130#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6131#endif
6132
Victor Stinner8c62be82010-05-06 00:08:46 +00006133 PyStructSequence_SET_ITEM(result, 0,
6134 PyFloat_FromDouble(doubletime(ru->ru_utime)));
6135 PyStructSequence_SET_ITEM(result, 1,
6136 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006137#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006138 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6139 SET_INT(result, 2, ru->ru_maxrss);
6140 SET_INT(result, 3, ru->ru_ixrss);
6141 SET_INT(result, 4, ru->ru_idrss);
6142 SET_INT(result, 5, ru->ru_isrss);
6143 SET_INT(result, 6, ru->ru_minflt);
6144 SET_INT(result, 7, ru->ru_majflt);
6145 SET_INT(result, 8, ru->ru_nswap);
6146 SET_INT(result, 9, ru->ru_inblock);
6147 SET_INT(result, 10, ru->ru_oublock);
6148 SET_INT(result, 11, ru->ru_msgsnd);
6149 SET_INT(result, 12, ru->ru_msgrcv);
6150 SET_INT(result, 13, ru->ru_nsignals);
6151 SET_INT(result, 14, ru->ru_nvcsw);
6152 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006153#undef SET_INT
6154
Victor Stinner8c62be82010-05-06 00:08:46 +00006155 if (PyErr_Occurred()) {
6156 Py_DECREF(result);
6157 return NULL;
6158 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006159
Victor Stinner8c62be82010-05-06 00:08:46 +00006160 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006161}
6162#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6163
6164#ifdef HAVE_WAIT3
6165PyDoc_STRVAR(posix_wait3__doc__,
6166"wait3(options) -> (pid, status, rusage)\n\n\
6167Wait for completion of a child process.");
6168
6169static PyObject *
6170posix_wait3(PyObject *self, PyObject *args)
6171{
Victor Stinner8c62be82010-05-06 00:08:46 +00006172 pid_t pid;
6173 int options;
6174 struct rusage ru;
6175 WAIT_TYPE status;
6176 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006177
Victor Stinner8c62be82010-05-06 00:08:46 +00006178 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6179 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006180
Victor Stinner8c62be82010-05-06 00:08:46 +00006181 Py_BEGIN_ALLOW_THREADS
6182 pid = wait3(&status, options, &ru);
6183 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006184
Victor Stinner8c62be82010-05-06 00:08:46 +00006185 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006186}
6187#endif /* HAVE_WAIT3 */
6188
6189#ifdef HAVE_WAIT4
6190PyDoc_STRVAR(posix_wait4__doc__,
6191"wait4(pid, options) -> (pid, status, rusage)\n\n\
6192Wait for completion of a given child process.");
6193
6194static PyObject *
6195posix_wait4(PyObject *self, PyObject *args)
6196{
Victor Stinner8c62be82010-05-06 00:08:46 +00006197 pid_t pid;
6198 int options;
6199 struct rusage ru;
6200 WAIT_TYPE status;
6201 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006202
Victor Stinner8c62be82010-05-06 00:08:46 +00006203 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
6204 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006205
Victor Stinner8c62be82010-05-06 00:08:46 +00006206 Py_BEGIN_ALLOW_THREADS
6207 pid = wait4(pid, &status, options, &ru);
6208 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006209
Victor Stinner8c62be82010-05-06 00:08:46 +00006210 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006211}
6212#endif /* HAVE_WAIT4 */
6213
Ross Lagerwall7807c352011-03-17 20:20:30 +02006214#if defined(HAVE_WAITID) && !defined(__APPLE__)
6215PyDoc_STRVAR(posix_waitid__doc__,
6216"waitid(idtype, id, options) -> waitid_result\n\n\
6217Wait for the completion of one or more child processes.\n\n\
6218idtype can be P_PID, P_PGID or P_ALL.\n\
6219id specifies the pid to wait on.\n\
6220options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6221or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6222Returns either waitid_result or None if WNOHANG is specified and there are\n\
6223no children in a waitable state.");
6224
6225static PyObject *
6226posix_waitid(PyObject *self, PyObject *args)
6227{
6228 PyObject *result;
6229 idtype_t idtype;
6230 id_t id;
6231 int options, res;
6232 siginfo_t si;
6233 si.si_pid = 0;
6234 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6235 return NULL;
6236 Py_BEGIN_ALLOW_THREADS
6237 res = waitid(idtype, id, &si, options);
6238 Py_END_ALLOW_THREADS
6239 if (res == -1)
6240 return posix_error();
6241
6242 if (si.si_pid == 0)
6243 Py_RETURN_NONE;
6244
6245 result = PyStructSequence_New(&WaitidResultType);
6246 if (!result)
6247 return NULL;
6248
6249 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6250 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6251 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6252 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6253 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6254 if (PyErr_Occurred()) {
6255 Py_DECREF(result);
6256 return NULL;
6257 }
6258
6259 return result;
6260}
6261#endif
6262
Guido van Rossumb6775db1994-08-01 11:34:53 +00006263#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006264PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006265"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006266Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006267
Barry Warsaw53699e91996-12-10 23:23:01 +00006268static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006269posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006270{
Victor Stinner8c62be82010-05-06 00:08:46 +00006271 pid_t pid;
6272 int options;
6273 WAIT_TYPE status;
6274 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006275
Victor Stinner8c62be82010-05-06 00:08:46 +00006276 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6277 return NULL;
6278 Py_BEGIN_ALLOW_THREADS
6279 pid = waitpid(pid, &status, options);
6280 Py_END_ALLOW_THREADS
6281 if (pid == -1)
6282 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006283
Victor Stinner8c62be82010-05-06 00:08:46 +00006284 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006285}
6286
Tim Petersab034fa2002-02-01 11:27:43 +00006287#elif defined(HAVE_CWAIT)
6288
6289/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006290PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006291"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006292"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006293
6294static PyObject *
6295posix_waitpid(PyObject *self, PyObject *args)
6296{
Victor Stinner8c62be82010-05-06 00:08:46 +00006297 Py_intptr_t pid;
6298 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006299
Victor Stinner8c62be82010-05-06 00:08:46 +00006300 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6301 return NULL;
6302 Py_BEGIN_ALLOW_THREADS
6303 pid = _cwait(&status, pid, options);
6304 Py_END_ALLOW_THREADS
6305 if (pid == -1)
6306 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006307
Victor Stinner8c62be82010-05-06 00:08:46 +00006308 /* shift the status left a byte so this is more like the POSIX waitpid */
6309 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006310}
6311#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006312
Guido van Rossumad0ee831995-03-01 10:34:45 +00006313#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006314PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006315"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006316Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006317
Barry Warsaw53699e91996-12-10 23:23:01 +00006318static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006319posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006320{
Victor Stinner8c62be82010-05-06 00:08:46 +00006321 pid_t pid;
6322 WAIT_TYPE status;
6323 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006324
Victor Stinner8c62be82010-05-06 00:08:46 +00006325 Py_BEGIN_ALLOW_THREADS
6326 pid = wait(&status);
6327 Py_END_ALLOW_THREADS
6328 if (pid == -1)
6329 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006330
Victor Stinner8c62be82010-05-06 00:08:46 +00006331 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006332}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006333#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006334
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006335
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006336PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006337"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006338Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006339
Barry Warsaw53699e91996-12-10 23:23:01 +00006340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006341posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006342{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006343#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00006344 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006345#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006346#ifdef MS_WINDOWS
Brian Curtind25aef52011-06-13 15:16:04 -05006347 return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat",
Brian Curtind40e6f72010-07-08 21:39:08 +00006348 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006349#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006350 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006351#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006352#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006353}
6354
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006355
Guido van Rossumb6775db1994-08-01 11:34:53 +00006356#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006357PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006358"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006359Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006360
Barry Warsaw53699e91996-12-10 23:23:01 +00006361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006362posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006363{
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 PyObject* v;
6365 char buf[MAXPATHLEN];
6366 PyObject *opath;
6367 char *path;
6368 int n;
6369 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006370
Victor Stinner8c62be82010-05-06 00:08:46 +00006371 if (!PyArg_ParseTuple(args, "O&:readlink",
6372 PyUnicode_FSConverter, &opath))
6373 return NULL;
6374 path = PyBytes_AsString(opath);
6375 v = PySequence_GetItem(args, 0);
6376 if (v == NULL) {
6377 Py_DECREF(opath);
6378 return NULL;
6379 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00006380
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 if (PyUnicode_Check(v)) {
6382 arg_is_unicode = 1;
6383 }
6384 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006385
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 Py_BEGIN_ALLOW_THREADS
6387 n = readlink(path, buf, (int) sizeof buf);
6388 Py_END_ALLOW_THREADS
6389 if (n < 0)
6390 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006391
Victor Stinner8c62be82010-05-06 00:08:46 +00006392 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00006393 if (arg_is_unicode)
6394 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
6395 else
6396 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006397}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006398#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006399
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006400
Brian Curtin52173d42010-12-02 18:29:18 +00006401#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006402PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006403"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006404Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006405
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006406static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006407posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006408{
Victor Stinner8c62be82010-05-06 00:08:46 +00006409 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006410}
6411#endif /* HAVE_SYMLINK */
6412
Brian Curtind40e6f72010-07-08 21:39:08 +00006413#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6414
6415PyDoc_STRVAR(win_readlink__doc__,
6416"readlink(path) -> path\n\n\
6417Return a string representing the path to which the symbolic link points.");
6418
Brian Curtind40e6f72010-07-08 21:39:08 +00006419/* Windows readlink implementation */
6420static PyObject *
6421win_readlink(PyObject *self, PyObject *args)
6422{
6423 wchar_t *path;
6424 DWORD n_bytes_returned;
6425 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006426 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00006427 HANDLE reparse_point_handle;
6428
6429 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6430 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6431 wchar_t *print_name;
6432
6433 if (!PyArg_ParseTuple(args,
Victor Stinnereb5657a2011-09-30 01:44:27 +02006434 "U:readlink",
6435 &po))
6436 return NULL;
6437 path = PyUnicode_AsUnicode(po);
6438 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006439 return NULL;
6440
6441 /* First get a handle to the reparse point */
6442 Py_BEGIN_ALLOW_THREADS
6443 reparse_point_handle = CreateFileW(
6444 path,
6445 0,
6446 0,
6447 0,
6448 OPEN_EXISTING,
6449 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6450 0);
6451 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006452
Brian Curtind40e6f72010-07-08 21:39:08 +00006453 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006454 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006455
Brian Curtind40e6f72010-07-08 21:39:08 +00006456 Py_BEGIN_ALLOW_THREADS
6457 /* New call DeviceIoControl to read the reparse point */
6458 io_result = DeviceIoControl(
6459 reparse_point_handle,
6460 FSCTL_GET_REPARSE_POINT,
6461 0, 0, /* in buffer */
6462 target_buffer, sizeof(target_buffer),
6463 &n_bytes_returned,
6464 0 /* we're not using OVERLAPPED_IO */
6465 );
6466 CloseHandle(reparse_point_handle);
6467 Py_END_ALLOW_THREADS
6468
6469 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006470 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006471
6472 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6473 {
6474 PyErr_SetString(PyExc_ValueError,
6475 "not a symbolic link");
6476 return NULL;
6477 }
Brian Curtin74e45612010-07-09 15:58:59 +00006478 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6479 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6480
6481 result = PyUnicode_FromWideChar(print_name,
6482 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006483 return result;
6484}
6485
6486#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6487
Brian Curtin52173d42010-12-02 18:29:18 +00006488#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtind40e6f72010-07-08 21:39:08 +00006489
6490/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6491static int has_CreateSymbolicLinkW = 0;
6492static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
6493static int
6494check_CreateSymbolicLinkW()
6495{
6496 HINSTANCE hKernel32;
6497 /* only recheck */
6498 if (has_CreateSymbolicLinkW)
6499 return has_CreateSymbolicLinkW;
6500 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00006501 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6502 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00006503 if (Py_CreateSymbolicLinkW)
6504 has_CreateSymbolicLinkW = 1;
6505 return has_CreateSymbolicLinkW;
6506}
6507
6508PyDoc_STRVAR(win_symlink__doc__,
6509"symlink(src, dst, target_is_directory=False)\n\n\
6510Create a symbolic link pointing to src named dst.\n\
6511target_is_directory is required if the target is to be interpreted as\n\
6512a directory.\n\
6513This function requires Windows 6.0 or greater, and raises a\n\
6514NotImplementedError otherwise.");
6515
6516static PyObject *
6517win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
6518{
6519 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
6520 PyObject *src, *dest;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006521 wchar_t *wsrc, *wdest;
Brian Curtind40e6f72010-07-08 21:39:08 +00006522 int target_is_directory = 0;
6523 DWORD res;
6524 WIN32_FILE_ATTRIBUTE_DATA src_info;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006525
Brian Curtind40e6f72010-07-08 21:39:08 +00006526 if (!check_CreateSymbolicLinkW())
6527 {
6528 /* raise NotImplementedError */
6529 return PyErr_Format(PyExc_NotImplementedError,
6530 "CreateSymbolicLinkW not found");
6531 }
6532 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
6533 kwlist, &src, &dest, &target_is_directory))
6534 return NULL;
Brian Curtin3b4499c2010-12-28 14:31:47 +00006535
6536 if (win32_can_symlink == 0)
6537 return PyErr_Format(PyExc_OSError, "symbolic link privilege not held");
6538
Victor Stinnereb5657a2011-09-30 01:44:27 +02006539 if (!convert_to_unicode(&src))
6540 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00006541 if (!convert_to_unicode(&dest)) {
6542 Py_DECREF(src);
6543 return NULL;
6544 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006545
Victor Stinnereb5657a2011-09-30 01:44:27 +02006546 wsrc = PyUnicode_AsUnicode(src);
6547 if (wsrc == NULL)
6548 goto error;
6549 wdest = PyUnicode_AsUnicode(dest);
6550 if (wsrc == NULL)
6551 goto error;
6552
Brian Curtind40e6f72010-07-08 21:39:08 +00006553 /* if src is a directory, ensure target_is_directory==1 */
6554 if(
6555 GetFileAttributesExW(
Victor Stinnereb5657a2011-09-30 01:44:27 +02006556 wsrc, GetFileExInfoStandard, &src_info
Brian Curtind40e6f72010-07-08 21:39:08 +00006557 ))
6558 {
6559 target_is_directory = target_is_directory ||
6560 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
6561 }
6562
6563 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006564 res = Py_CreateSymbolicLinkW(wdest, wsrc, target_is_directory);
Brian Curtind40e6f72010-07-08 21:39:08 +00006565 Py_END_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006566
Brian Curtind40e6f72010-07-08 21:39:08 +00006567 Py_DECREF(src);
6568 Py_DECREF(dest);
6569 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006570 return win32_error_object("symlink", src);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006571
Brian Curtind40e6f72010-07-08 21:39:08 +00006572 Py_INCREF(Py_None);
6573 return Py_None;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006574
6575error:
6576 Py_DECREF(src);
6577 Py_DECREF(dest);
6578 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00006579}
Brian Curtin52173d42010-12-02 18:29:18 +00006580#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006581
6582#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006583#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6584static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006585system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006586{
6587 ULONG value = 0;
6588
6589 Py_BEGIN_ALLOW_THREADS
6590 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6591 Py_END_ALLOW_THREADS
6592
6593 return value;
6594}
6595
6596static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006597posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006598{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006599 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00006600 return Py_BuildValue("ddddd",
6601 (double)0 /* t.tms_utime / HZ */,
6602 (double)0 /* t.tms_stime / HZ */,
6603 (double)0 /* t.tms_cutime / HZ */,
6604 (double)0 /* t.tms_cstime / HZ */,
6605 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006606}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006607#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00006608#define NEED_TICKS_PER_SECOND
6609static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006610static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006611posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006612{
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 struct tms t;
6614 clock_t c;
6615 errno = 0;
6616 c = times(&t);
6617 if (c == (clock_t) -1)
6618 return posix_error();
6619 return Py_BuildValue("ddddd",
6620 (double)t.tms_utime / ticks_per_second,
6621 (double)t.tms_stime / ticks_per_second,
6622 (double)t.tms_cutime / ticks_per_second,
6623 (double)t.tms_cstime / ticks_per_second,
6624 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006625}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006626#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006627#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006628
6629
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006630#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006631#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006632static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006633posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006634{
Victor Stinner8c62be82010-05-06 00:08:46 +00006635 FILETIME create, exit, kernel, user;
6636 HANDLE hProc;
6637 hProc = GetCurrentProcess();
6638 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6639 /* The fields of a FILETIME structure are the hi and lo part
6640 of a 64-bit value expressed in 100 nanosecond units.
6641 1e7 is one second in such units; 1e-7 the inverse.
6642 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6643 */
6644 return Py_BuildValue(
6645 "ddddd",
6646 (double)(user.dwHighDateTime*429.4967296 +
6647 user.dwLowDateTime*1e-7),
6648 (double)(kernel.dwHighDateTime*429.4967296 +
6649 kernel.dwLowDateTime*1e-7),
6650 (double)0,
6651 (double)0,
6652 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006653}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006654#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006655
6656#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006657PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006658"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006659Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006660#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006661
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006662
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006663#ifdef HAVE_GETSID
6664PyDoc_STRVAR(posix_getsid__doc__,
6665"getsid(pid) -> sid\n\n\
6666Call the system call getsid().");
6667
6668static PyObject *
6669posix_getsid(PyObject *self, PyObject *args)
6670{
Victor Stinner8c62be82010-05-06 00:08:46 +00006671 pid_t pid;
6672 int sid;
6673 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6674 return NULL;
6675 sid = getsid(pid);
6676 if (sid < 0)
6677 return posix_error();
6678 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006679}
6680#endif /* HAVE_GETSID */
6681
6682
Guido van Rossumb6775db1994-08-01 11:34:53 +00006683#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006684PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006685"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006686Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006687
Barry Warsaw53699e91996-12-10 23:23:01 +00006688static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006689posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006690{
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 if (setsid() < 0)
6692 return posix_error();
6693 Py_INCREF(Py_None);
6694 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006695}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006696#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006697
Guido van Rossumb6775db1994-08-01 11:34:53 +00006698#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006699PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006700"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006701Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006702
Barry Warsaw53699e91996-12-10 23:23:01 +00006703static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006704posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006705{
Victor Stinner8c62be82010-05-06 00:08:46 +00006706 pid_t pid;
6707 int pgrp;
6708 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
6709 return NULL;
6710 if (setpgid(pid, pgrp) < 0)
6711 return posix_error();
6712 Py_INCREF(Py_None);
6713 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006714}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006715#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006716
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006717
Guido van Rossumb6775db1994-08-01 11:34:53 +00006718#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006719PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006720"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006721Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006722
Barry Warsaw53699e91996-12-10 23:23:01 +00006723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006724posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006725{
Victor Stinner8c62be82010-05-06 00:08:46 +00006726 int fd;
6727 pid_t pgid;
6728 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6729 return NULL;
6730 pgid = tcgetpgrp(fd);
6731 if (pgid < 0)
6732 return posix_error();
6733 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006734}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006735#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006736
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006737
Guido van Rossumb6775db1994-08-01 11:34:53 +00006738#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006739PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006740"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006741Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006742
Barry Warsaw53699e91996-12-10 23:23:01 +00006743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006744posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006745{
Victor Stinner8c62be82010-05-06 00:08:46 +00006746 int fd;
6747 pid_t pgid;
6748 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
6749 return NULL;
6750 if (tcsetpgrp(fd, pgid) < 0)
6751 return posix_error();
6752 Py_INCREF(Py_None);
6753 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006754}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006755#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006756
Guido van Rossum687dd131993-05-17 08:34:16 +00006757/* Functions acting on file descriptors */
6758
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006759PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006760"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006761Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006762
Barry Warsaw53699e91996-12-10 23:23:01 +00006763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006764posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006765{
Victor Stinner8c62be82010-05-06 00:08:46 +00006766 PyObject *ofile;
6767 char *file;
6768 int flag;
6769 int mode = 0777;
6770 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006771
6772#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006773 PyObject *po;
Victor Stinner26de69d2011-06-17 15:15:38 +02006774 if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02006775 wchar_t *wpath = PyUnicode_AsUnicode(po);
6776 if (wpath == NULL)
6777 return NULL;
6778
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006780 fd = _wopen(wpath, flag, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 Py_END_ALLOW_THREADS
6782 if (fd < 0)
6783 return posix_error();
6784 return PyLong_FromLong((long)fd);
6785 }
6786 /* Drop the argument parsing error as narrow strings
6787 are also valid. */
6788 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006789#endif
6790
Victor Stinner26de69d2011-06-17 15:15:38 +02006791 if (!PyArg_ParseTuple(args, "O&i|i:open",
Victor Stinner8c62be82010-05-06 00:08:46 +00006792 PyUnicode_FSConverter, &ofile,
6793 &flag, &mode))
6794 return NULL;
6795 file = PyBytes_AsString(ofile);
6796 Py_BEGIN_ALLOW_THREADS
6797 fd = open(file, flag, mode);
6798 Py_END_ALLOW_THREADS
6799 if (fd < 0)
6800 return posix_error_with_allocated_filename(ofile);
6801 Py_DECREF(ofile);
6802 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006803}
6804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006805
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006806PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006807"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006808Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006809
Barry Warsaw53699e91996-12-10 23:23:01 +00006810static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006811posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006812{
Victor Stinner8c62be82010-05-06 00:08:46 +00006813 int fd, res;
6814 if (!PyArg_ParseTuple(args, "i:close", &fd))
6815 return NULL;
6816 if (!_PyVerify_fd(fd))
6817 return posix_error();
6818 Py_BEGIN_ALLOW_THREADS
6819 res = close(fd);
6820 Py_END_ALLOW_THREADS
6821 if (res < 0)
6822 return posix_error();
6823 Py_INCREF(Py_None);
6824 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006825}
6826
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006827
Victor Stinner8c62be82010-05-06 00:08:46 +00006828PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00006829"closerange(fd_low, fd_high)\n\n\
6830Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6831
6832static PyObject *
6833posix_closerange(PyObject *self, PyObject *args)
6834{
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 int fd_from, fd_to, i;
6836 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6837 return NULL;
6838 Py_BEGIN_ALLOW_THREADS
6839 for (i = fd_from; i < fd_to; i++)
6840 if (_PyVerify_fd(i))
6841 close(i);
6842 Py_END_ALLOW_THREADS
6843 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00006844}
6845
6846
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006847PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006848"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006849Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006850
Barry Warsaw53699e91996-12-10 23:23:01 +00006851static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006852posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006853{
Victor Stinner8c62be82010-05-06 00:08:46 +00006854 int fd;
6855 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6856 return NULL;
6857 if (!_PyVerify_fd(fd))
6858 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00006860 if (fd < 0)
6861 return posix_error();
6862 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006863}
6864
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006865
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006866PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006867"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006868Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006869
Barry Warsaw53699e91996-12-10 23:23:01 +00006870static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006871posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006872{
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 int fd, fd2, res;
6874 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6875 return NULL;
6876 if (!_PyVerify_fd_dup2(fd, fd2))
6877 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00006879 if (res < 0)
6880 return posix_error();
6881 Py_INCREF(Py_None);
6882 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006883}
6884
Ross Lagerwall7807c352011-03-17 20:20:30 +02006885#ifdef HAVE_LOCKF
6886PyDoc_STRVAR(posix_lockf__doc__,
6887"lockf(fd, cmd, len)\n\n\
6888Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
6889fd is an open file descriptor.\n\
6890cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
6891F_TEST.\n\
6892len specifies the section of the file to lock.");
6893
6894static PyObject *
6895posix_lockf(PyObject *self, PyObject *args)
6896{
6897 int fd, cmd, res;
6898 off_t len;
6899 if (!PyArg_ParseTuple(args, "iiO&:lockf",
6900 &fd, &cmd, _parse_off_t, &len))
6901 return NULL;
6902
6903 Py_BEGIN_ALLOW_THREADS
6904 res = lockf(fd, cmd, len);
6905 Py_END_ALLOW_THREADS
6906
6907 if (res < 0)
6908 return posix_error();
6909
6910 Py_RETURN_NONE;
6911}
6912#endif
6913
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006914
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006915PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006916"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006917Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006918
Barry Warsaw53699e91996-12-10 23:23:01 +00006919static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006920posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006921{
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006923#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00006924 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006925#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006927#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02006928 PyObject *posobj;
6929 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00006930 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006931#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00006932 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6933 switch (how) {
6934 case 0: how = SEEK_SET; break;
6935 case 1: how = SEEK_CUR; break;
6936 case 2: how = SEEK_END; break;
6937 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006938#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006939
Ross Lagerwall8e749672011-03-17 21:54:07 +02006940#if !defined(HAVE_LARGEFILE_SUPPORT)
6941 pos = PyLong_AsLong(posobj);
6942#else
6943 pos = PyLong_AsLongLong(posobj);
6944#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006945 if (PyErr_Occurred())
6946 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006947
Victor Stinner8c62be82010-05-06 00:08:46 +00006948 if (!_PyVerify_fd(fd))
6949 return posix_error();
6950 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006951#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006953#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006954 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006955#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006956 Py_END_ALLOW_THREADS
6957 if (res < 0)
6958 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006959
6960#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006962#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006963 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006964#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006965}
6966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006967
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006968PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006969"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006970Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006971
Barry Warsaw53699e91996-12-10 23:23:01 +00006972static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006973posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006974{
Victor Stinner8c62be82010-05-06 00:08:46 +00006975 int fd, size;
6976 Py_ssize_t n;
6977 PyObject *buffer;
6978 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6979 return NULL;
6980 if (size < 0) {
6981 errno = EINVAL;
6982 return posix_error();
6983 }
6984 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
6985 if (buffer == NULL)
6986 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00006987 if (!_PyVerify_fd(fd)) {
6988 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00006989 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00006990 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006991 Py_BEGIN_ALLOW_THREADS
6992 n = read(fd, PyBytes_AS_STRING(buffer), size);
6993 Py_END_ALLOW_THREADS
6994 if (n < 0) {
6995 Py_DECREF(buffer);
6996 return posix_error();
6997 }
6998 if (n != size)
6999 _PyBytes_Resize(&buffer, n);
7000 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007001}
7002
Ross Lagerwall7807c352011-03-17 20:20:30 +02007003#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7004 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007005static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007006iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7007{
7008 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007009 Py_ssize_t blen, total = 0;
7010
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007011 *iov = PyMem_New(struct iovec, cnt);
7012 if (*iov == NULL) {
7013 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007014 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007015 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007016
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007017 *buf = PyMem_New(Py_buffer, cnt);
7018 if (*buf == NULL) {
7019 PyMem_Del(*iov);
7020 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007021 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007022 }
7023
7024 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007025 PyObject *item = PySequence_GetItem(seq, i);
7026 if (item == NULL)
7027 goto fail;
7028 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7029 Py_DECREF(item);
7030 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007031 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007032 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007033 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007034 blen = (*buf)[i].len;
7035 (*iov)[i].iov_len = blen;
7036 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007037 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007038 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007039
7040fail:
7041 PyMem_Del(*iov);
7042 for (j = 0; j < i; j++) {
7043 PyBuffer_Release(&(*buf)[j]);
7044 }
7045 PyMem_Del(*buf);
7046 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007047}
7048
7049static void
7050iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7051{
7052 int i;
7053 PyMem_Del(iov);
7054 for (i = 0; i < cnt; i++) {
7055 PyBuffer_Release(&buf[i]);
7056 }
7057 PyMem_Del(buf);
7058}
7059#endif
7060
Ross Lagerwall7807c352011-03-17 20:20:30 +02007061#ifdef HAVE_READV
7062PyDoc_STRVAR(posix_readv__doc__,
7063"readv(fd, buffers) -> bytesread\n\n\
7064Read from a file descriptor into a number of writable buffers. buffers\n\
7065is an arbitrary sequence of writable buffers.\n\
7066Returns the total number of bytes read.");
7067
7068static PyObject *
7069posix_readv(PyObject *self, PyObject *args)
7070{
7071 int fd, cnt;
7072 Py_ssize_t n;
7073 PyObject *seq;
7074 struct iovec *iov;
7075 Py_buffer *buf;
7076
7077 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7078 return NULL;
7079 if (!PySequence_Check(seq)) {
7080 PyErr_SetString(PyExc_TypeError,
7081 "readv() arg 2 must be a sequence");
7082 return NULL;
7083 }
7084 cnt = PySequence_Size(seq);
7085
7086 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7087 return NULL;
7088
7089 Py_BEGIN_ALLOW_THREADS
7090 n = readv(fd, iov, cnt);
7091 Py_END_ALLOW_THREADS
7092
7093 iov_cleanup(iov, buf, cnt);
7094 return PyLong_FromSsize_t(n);
7095}
7096#endif
7097
7098#ifdef HAVE_PREAD
7099PyDoc_STRVAR(posix_pread__doc__,
7100"pread(fd, buffersize, offset) -> string\n\n\
7101Read from a file descriptor, fd, at a position of offset. It will read up\n\
7102to buffersize number of bytes. The file offset remains unchanged.");
7103
7104static PyObject *
7105posix_pread(PyObject *self, PyObject *args)
7106{
7107 int fd, size;
7108 off_t offset;
7109 Py_ssize_t n;
7110 PyObject *buffer;
7111 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7112 return NULL;
7113
7114 if (size < 0) {
7115 errno = EINVAL;
7116 return posix_error();
7117 }
7118 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7119 if (buffer == NULL)
7120 return NULL;
7121 if (!_PyVerify_fd(fd)) {
7122 Py_DECREF(buffer);
7123 return posix_error();
7124 }
7125 Py_BEGIN_ALLOW_THREADS
7126 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7127 Py_END_ALLOW_THREADS
7128 if (n < 0) {
7129 Py_DECREF(buffer);
7130 return posix_error();
7131 }
7132 if (n != size)
7133 _PyBytes_Resize(&buffer, n);
7134 return buffer;
7135}
7136#endif
7137
7138PyDoc_STRVAR(posix_write__doc__,
7139"write(fd, string) -> byteswritten\n\n\
7140Write a string to a file descriptor.");
7141
7142static PyObject *
7143posix_write(PyObject *self, PyObject *args)
7144{
7145 Py_buffer pbuf;
7146 int fd;
7147 Py_ssize_t size, len;
7148
7149 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7150 return NULL;
7151 if (!_PyVerify_fd(fd)) {
7152 PyBuffer_Release(&pbuf);
7153 return posix_error();
7154 }
7155 len = pbuf.len;
7156 Py_BEGIN_ALLOW_THREADS
7157#if defined(MS_WIN64) || defined(MS_WINDOWS)
7158 if (len > INT_MAX)
7159 len = INT_MAX;
7160 size = write(fd, pbuf.buf, (int)len);
7161#else
7162 size = write(fd, pbuf.buf, len);
7163#endif
7164 Py_END_ALLOW_THREADS
7165 PyBuffer_Release(&pbuf);
7166 if (size < 0)
7167 return posix_error();
7168 return PyLong_FromSsize_t(size);
7169}
7170
7171#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007172PyDoc_STRVAR(posix_sendfile__doc__,
7173"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7174sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7175 -> byteswritten\n\
7176Copy nbytes bytes from file descriptor in to file descriptor out.");
7177
7178static PyObject *
7179posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7180{
7181 int in, out;
7182 Py_ssize_t ret;
7183 off_t offset;
7184
7185#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7186#ifndef __APPLE__
7187 Py_ssize_t len;
7188#endif
7189 PyObject *headers = NULL, *trailers = NULL;
7190 Py_buffer *hbuf, *tbuf;
7191 off_t sbytes;
7192 struct sf_hdtr sf;
7193 int flags = 0;
7194 sf.headers = NULL;
7195 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007196 static char *keywords[] = {"out", "in",
7197 "offset", "count",
7198 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007199
7200#ifdef __APPLE__
7201 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007202 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007203#else
7204 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007205 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007206#endif
7207 &headers, &trailers, &flags))
7208 return NULL;
7209 if (headers != NULL) {
7210 if (!PySequence_Check(headers)) {
7211 PyErr_SetString(PyExc_TypeError,
7212 "sendfile() headers must be a sequence or None");
7213 return NULL;
7214 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007215 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007216 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007217 if (sf.hdr_cnt > 0 &&
7218 !(i = iov_setup(&(sf.headers), &hbuf,
7219 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007220 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007221#ifdef __APPLE__
7222 sbytes += i;
7223#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007224 }
7225 }
7226 if (trailers != NULL) {
7227 if (!PySequence_Check(trailers)) {
7228 PyErr_SetString(PyExc_TypeError,
7229 "sendfile() trailers must be a sequence or None");
7230 return NULL;
7231 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007232 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007233 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007234 if (sf.trl_cnt > 0 &&
7235 !(i = iov_setup(&(sf.trailers), &tbuf,
7236 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007237 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007238#ifdef __APPLE__
7239 sbytes += i;
7240#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007241 }
7242 }
7243
7244 Py_BEGIN_ALLOW_THREADS
7245#ifdef __APPLE__
7246 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7247#else
7248 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7249#endif
7250 Py_END_ALLOW_THREADS
7251
7252 if (sf.headers != NULL)
7253 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7254 if (sf.trailers != NULL)
7255 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7256
7257 if (ret < 0) {
7258 if ((errno == EAGAIN) || (errno == EBUSY)) {
7259 if (sbytes != 0) {
7260 // some data has been sent
7261 goto done;
7262 }
7263 else {
7264 // no data has been sent; upper application is supposed
7265 // to retry on EAGAIN or EBUSY
7266 return posix_error();
7267 }
7268 }
7269 return posix_error();
7270 }
7271 goto done;
7272
7273done:
7274 #if !defined(HAVE_LARGEFILE_SUPPORT)
7275 return Py_BuildValue("l", sbytes);
7276 #else
7277 return Py_BuildValue("L", sbytes);
7278 #endif
7279
7280#else
7281 Py_ssize_t count;
7282 PyObject *offobj;
7283 static char *keywords[] = {"out", "in",
7284 "offset", "count", NULL};
7285 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7286 keywords, &out, &in, &offobj, &count))
7287 return NULL;
7288#ifdef linux
7289 if (offobj == Py_None) {
7290 Py_BEGIN_ALLOW_THREADS
7291 ret = sendfile(out, in, NULL, count);
7292 Py_END_ALLOW_THREADS
7293 if (ret < 0)
7294 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007295 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007296 }
7297#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007298 if (!_parse_off_t(offobj, &offset))
7299 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007300 Py_BEGIN_ALLOW_THREADS
7301 ret = sendfile(out, in, &offset, count);
7302 Py_END_ALLOW_THREADS
7303 if (ret < 0)
7304 return posix_error();
7305 return Py_BuildValue("n", ret);
7306#endif
7307}
7308#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007309
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007310PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007311"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007312Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007313
Barry Warsaw53699e91996-12-10 23:23:01 +00007314static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007315posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007316{
Victor Stinner8c62be82010-05-06 00:08:46 +00007317 int fd;
7318 STRUCT_STAT st;
7319 int res;
7320 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
7321 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007322#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007323 /* on OpenVMS we must ensure that all bytes are written to the file */
7324 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007325#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007326 if (!_PyVerify_fd(fd))
7327 return posix_error();
7328 Py_BEGIN_ALLOW_THREADS
7329 res = FSTAT(fd, &st);
7330 Py_END_ALLOW_THREADS
7331 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007332#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007333 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00007334#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007335 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007336#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007337 }
Tim Peters5aa91602002-01-30 05:46:57 +00007338
Victor Stinner8c62be82010-05-06 00:08:46 +00007339 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007340}
7341
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007342PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007343"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007344Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007345connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007346
7347static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007348posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007349{
Victor Stinner8c62be82010-05-06 00:08:46 +00007350 int fd;
7351 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7352 return NULL;
7353 if (!_PyVerify_fd(fd))
7354 return PyBool_FromLong(0);
7355 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007356}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007357
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007358#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007359PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007360"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007361Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007362
Barry Warsaw53699e91996-12-10 23:23:01 +00007363static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007364posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007365{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007366#if defined(PYOS_OS2)
7367 HFILE read, write;
7368 APIRET rc;
7369
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007370 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007371 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007372 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007373
7374 return Py_BuildValue("(ii)", read, write);
7375#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007376#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007377 int fds[2];
7378 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007379 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007380 if (res != 0)
7381 return posix_error();
7382 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007383#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007384 HANDLE read, write;
7385 int read_fd, write_fd;
7386 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007387 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007388 if (!ok)
7389 return win32_error("CreatePipe", NULL);
7390 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7391 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7392 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007393#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007394#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007395}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007396#endif /* HAVE_PIPE */
7397
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007398#ifdef HAVE_PIPE2
7399PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007400"pipe2(flags) -> (read_end, write_end)\n\n\
7401Create a pipe with flags set atomically.\n\
7402flags can be constructed by ORing together one or more of these values:\n\
7403O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007404");
7405
7406static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007407posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007408{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007409 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007410 int fds[2];
7411 int res;
7412
Charles-François Natali368f34b2011-06-06 19:49:47 +02007413 flags = PyLong_AsLong(arg);
7414 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007415 return NULL;
7416
7417 res = pipe2(fds, flags);
7418 if (res != 0)
7419 return posix_error();
7420 return Py_BuildValue("(ii)", fds[0], fds[1]);
7421}
7422#endif /* HAVE_PIPE2 */
7423
Ross Lagerwall7807c352011-03-17 20:20:30 +02007424#ifdef HAVE_WRITEV
7425PyDoc_STRVAR(posix_writev__doc__,
7426"writev(fd, buffers) -> byteswritten\n\n\
7427Write the contents of buffers to a file descriptor, where buffers is an\n\
7428arbitrary sequence of buffers.\n\
7429Returns the total bytes written.");
7430
7431static PyObject *
7432posix_writev(PyObject *self, PyObject *args)
7433{
7434 int fd, cnt;
7435 Py_ssize_t res;
7436 PyObject *seq;
7437 struct iovec *iov;
7438 Py_buffer *buf;
7439 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7440 return NULL;
7441 if (!PySequence_Check(seq)) {
7442 PyErr_SetString(PyExc_TypeError,
7443 "writev() arg 2 must be a sequence");
7444 return NULL;
7445 }
7446 cnt = PySequence_Size(seq);
7447
7448 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7449 return NULL;
7450 }
7451
7452 Py_BEGIN_ALLOW_THREADS
7453 res = writev(fd, iov, cnt);
7454 Py_END_ALLOW_THREADS
7455
7456 iov_cleanup(iov, buf, cnt);
7457 return PyLong_FromSsize_t(res);
7458}
7459#endif
7460
7461#ifdef HAVE_PWRITE
7462PyDoc_STRVAR(posix_pwrite__doc__,
7463"pwrite(fd, string, offset) -> byteswritten\n\n\
7464Write string to a file descriptor, fd, from offset, leaving the file\n\
7465offset unchanged.");
7466
7467static PyObject *
7468posix_pwrite(PyObject *self, PyObject *args)
7469{
7470 Py_buffer pbuf;
7471 int fd;
7472 off_t offset;
7473 Py_ssize_t size;
7474
7475 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7476 return NULL;
7477
7478 if (!_PyVerify_fd(fd)) {
7479 PyBuffer_Release(&pbuf);
7480 return posix_error();
7481 }
7482 Py_BEGIN_ALLOW_THREADS
7483 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7484 Py_END_ALLOW_THREADS
7485 PyBuffer_Release(&pbuf);
7486 if (size < 0)
7487 return posix_error();
7488 return PyLong_FromSsize_t(size);
7489}
7490#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007491
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007492#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007493PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007494"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007495Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007496
Barry Warsaw53699e91996-12-10 23:23:01 +00007497static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007498posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007499{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007500 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007501 char *filename;
7502 int mode = 0666;
7503 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007504 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
7505 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00007506 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007507 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007508 Py_BEGIN_ALLOW_THREADS
7509 res = mkfifo(filename, mode);
7510 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007511 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007512 if (res < 0)
7513 return posix_error();
7514 Py_INCREF(Py_None);
7515 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007516}
7517#endif
7518
7519
Neal Norwitz11690112002-07-30 01:08:28 +00007520#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007521PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007522"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007523Create a filesystem node (file, device special file or named pipe)\n\
7524named filename. mode specifies both the permissions to use and the\n\
7525type of node to be created, being combined (bitwise OR) with one of\n\
7526S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007527device defines the newly created device special file (probably using\n\
7528os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007529
7530
7531static PyObject *
7532posix_mknod(PyObject *self, PyObject *args)
7533{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007534 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007535 char *filename;
7536 int mode = 0600;
7537 int device = 0;
7538 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007539 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
7540 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00007541 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007542 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007543 Py_BEGIN_ALLOW_THREADS
7544 res = mknod(filename, mode, device);
7545 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007546 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007547 if (res < 0)
7548 return posix_error();
7549 Py_INCREF(Py_None);
7550 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007551}
7552#endif
7553
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007554#ifdef HAVE_DEVICE_MACROS
7555PyDoc_STRVAR(posix_major__doc__,
7556"major(device) -> major number\n\
7557Extracts a device major number from a raw device number.");
7558
7559static PyObject *
7560posix_major(PyObject *self, PyObject *args)
7561{
Victor Stinner8c62be82010-05-06 00:08:46 +00007562 int device;
7563 if (!PyArg_ParseTuple(args, "i:major", &device))
7564 return NULL;
7565 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007566}
7567
7568PyDoc_STRVAR(posix_minor__doc__,
7569"minor(device) -> minor number\n\
7570Extracts a device minor number from a raw device number.");
7571
7572static PyObject *
7573posix_minor(PyObject *self, PyObject *args)
7574{
Victor Stinner8c62be82010-05-06 00:08:46 +00007575 int device;
7576 if (!PyArg_ParseTuple(args, "i:minor", &device))
7577 return NULL;
7578 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007579}
7580
7581PyDoc_STRVAR(posix_makedev__doc__,
7582"makedev(major, minor) -> device number\n\
7583Composes a raw device number from the major and minor device numbers.");
7584
7585static PyObject *
7586posix_makedev(PyObject *self, PyObject *args)
7587{
Victor Stinner8c62be82010-05-06 00:08:46 +00007588 int major, minor;
7589 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7590 return NULL;
7591 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007592}
7593#endif /* device macros */
7594
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007595
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007596#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007597PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007598"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007599Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007600
Barry Warsaw53699e91996-12-10 23:23:01 +00007601static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007602posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007603{
Victor Stinner8c62be82010-05-06 00:08:46 +00007604 int fd;
7605 off_t length;
7606 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007607
Ross Lagerwall7807c352011-03-17 20:20:30 +02007608 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007609 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007610
Victor Stinner8c62be82010-05-06 00:08:46 +00007611 Py_BEGIN_ALLOW_THREADS
7612 res = ftruncate(fd, length);
7613 Py_END_ALLOW_THREADS
7614 if (res < 0)
7615 return posix_error();
7616 Py_INCREF(Py_None);
7617 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007618}
7619#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007620
Ross Lagerwall7807c352011-03-17 20:20:30 +02007621#ifdef HAVE_TRUNCATE
7622PyDoc_STRVAR(posix_truncate__doc__,
7623"truncate(path, length)\n\n\
7624Truncate the file given by path to length bytes.");
7625
7626static PyObject *
7627posix_truncate(PyObject *self, PyObject *args)
7628{
7629 PyObject *opath;
7630 const char *path;
7631 off_t length;
7632 int res;
7633
7634 if (!PyArg_ParseTuple(args, "O&O&:truncate",
7635 PyUnicode_FSConverter, &opath, _parse_off_t, &length))
7636 return NULL;
7637 path = PyBytes_AsString(opath);
7638
7639 Py_BEGIN_ALLOW_THREADS
7640 res = truncate(path, length);
7641 Py_END_ALLOW_THREADS
7642 Py_DECREF(opath);
7643 if (res < 0)
7644 return posix_error();
7645 Py_RETURN_NONE;
7646}
7647#endif
7648
7649#ifdef HAVE_POSIX_FALLOCATE
7650PyDoc_STRVAR(posix_posix_fallocate__doc__,
7651"posix_fallocate(fd, offset, len)\n\n\
7652Ensures that enough disk space is allocated for the file specified by fd\n\
7653starting from offset and continuing for len bytes.");
7654
7655static PyObject *
7656posix_posix_fallocate(PyObject *self, PyObject *args)
7657{
7658 off_t len, offset;
7659 int res, fd;
7660
7661 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
7662 &fd, _parse_off_t, &offset, _parse_off_t, &len))
7663 return NULL;
7664
7665 Py_BEGIN_ALLOW_THREADS
7666 res = posix_fallocate(fd, offset, len);
7667 Py_END_ALLOW_THREADS
7668 if (res != 0) {
7669 errno = res;
7670 return posix_error();
7671 }
7672 Py_RETURN_NONE;
7673}
7674#endif
7675
7676#ifdef HAVE_POSIX_FADVISE
7677PyDoc_STRVAR(posix_posix_fadvise__doc__,
7678"posix_fadvise(fd, offset, len, advice)\n\n\
7679Announces an intention to access data in a specific pattern thus allowing\n\
7680the kernel to make optimizations.\n\
7681The advice applies to the region of the file specified by fd starting at\n\
7682offset and continuing for len bytes.\n\
7683advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
7684POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
7685POSIX_FADV_DONTNEED.");
7686
7687static PyObject *
7688posix_posix_fadvise(PyObject *self, PyObject *args)
7689{
7690 off_t len, offset;
7691 int res, fd, advice;
7692
7693 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
7694 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
7695 return NULL;
7696
7697 Py_BEGIN_ALLOW_THREADS
7698 res = posix_fadvise(fd, offset, len, advice);
7699 Py_END_ALLOW_THREADS
7700 if (res != 0) {
7701 errno = res;
7702 return posix_error();
7703 }
7704 Py_RETURN_NONE;
7705}
7706#endif
7707
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007708#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007709PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007710"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007711Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007712
Fred Drake762e2061999-08-26 17:23:54 +00007713/* Save putenv() parameters as values here, so we can collect them when they
7714 * get re-set with another call for the same key. */
7715static PyObject *posix_putenv_garbage;
7716
Tim Peters5aa91602002-01-30 05:46:57 +00007717static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007718posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007719{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007720#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007721 wchar_t *s1, *s2;
7722 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007723#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007724 PyObject *os1, *os2;
7725 char *s1, *s2;
7726 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007727#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007728 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007729 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007730
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007731#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007732 if (!PyArg_ParseTuple(args,
7733 "uu:putenv",
7734 &s1, &s2))
7735 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00007736#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007737 if (!PyArg_ParseTuple(args,
7738 "O&O&:putenv",
7739 PyUnicode_FSConverter, &os1,
7740 PyUnicode_FSConverter, &os2))
7741 return NULL;
7742 s1 = PyBytes_AsString(os1);
7743 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00007744#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007745
7746#if defined(PYOS_OS2)
7747 if (stricmp(s1, "BEGINLIBPATH") == 0) {
7748 APIRET rc;
7749
Guido van Rossumd48f2521997-12-05 22:19:34 +00007750 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00007751 if (rc != NO_ERROR) {
7752 os2_error(rc);
7753 goto error;
7754 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007755
7756 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
7757 APIRET rc;
7758
Guido van Rossumd48f2521997-12-05 22:19:34 +00007759 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00007760 if (rc != NO_ERROR) {
7761 os2_error(rc);
7762 goto error;
7763 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007764 } else {
7765#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 /* XXX This can leak memory -- not easy to fix :-( */
7767 /* len includes space for a trailing \0; the size arg to
7768 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007769#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 len = wcslen(s1) + wcslen(s2) + 2;
7771 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007772#else
Victor Stinner84ae1182010-05-06 22:05:07 +00007773 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00007774 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007775#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007776 if (newstr == NULL) {
7777 PyErr_NoMemory();
7778 goto error;
7779 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007780#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007781 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02007782 if (newenv == NULL)
7783 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 _snwprintf(newenv, len, L"%s=%s", s1, s2);
7785 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007786 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007787 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007789#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007790 newenv = PyBytes_AS_STRING(newstr);
7791 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
7792 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007793 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007794 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007795 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007796#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007797
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 /* Install the first arg and newstr in posix_putenv_garbage;
7799 * this will cause previous value to be collected. This has to
7800 * happen after the real putenv() call because the old value
7801 * was still accessible until then. */
7802 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00007803#ifdef MS_WINDOWS
7804 PyTuple_GET_ITEM(args, 0),
7805#else
7806 os1,
7807#endif
7808 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007809 /* really not much we can do; just leak */
7810 PyErr_Clear();
7811 }
7812 else {
7813 Py_DECREF(newstr);
7814 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007815
7816#if defined(PYOS_OS2)
7817 }
7818#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007819
Martin v. Löwis011e8422009-05-05 04:43:17 +00007820#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007821 Py_DECREF(os1);
7822 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00007823#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007824 Py_RETURN_NONE;
7825
7826error:
7827#ifndef MS_WINDOWS
7828 Py_DECREF(os1);
7829 Py_DECREF(os2);
7830#endif
7831 Py_XDECREF(newstr);
7832 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007833}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007834#endif /* putenv */
7835
Guido van Rossumc524d952001-10-19 01:31:59 +00007836#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007837PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007838"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007839Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007840
7841static PyObject *
7842posix_unsetenv(PyObject *self, PyObject *args)
7843{
Victor Stinner84ae1182010-05-06 22:05:07 +00007844#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007845 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00007846
Victor Stinner8c62be82010-05-06 00:08:46 +00007847 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7848 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00007849#else
7850 PyObject *os1;
7851 char *s1;
7852
7853 if (!PyArg_ParseTuple(args, "O&:unsetenv",
7854 PyUnicode_FSConverter, &os1))
7855 return NULL;
7856 s1 = PyBytes_AsString(os1);
7857#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007858
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00007860
Victor Stinner8c62be82010-05-06 00:08:46 +00007861 /* Remove the key from posix_putenv_garbage;
7862 * this will cause it to be collected. This has to
7863 * happen after the real unsetenv() call because the
7864 * old value was still accessible until then.
7865 */
7866 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00007867#ifdef MS_WINDOWS
7868 PyTuple_GET_ITEM(args, 0)
7869#else
7870 os1
7871#endif
7872 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 /* really not much we can do; just leak */
7874 PyErr_Clear();
7875 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007876
Victor Stinner84ae1182010-05-06 22:05:07 +00007877#ifndef MS_WINDOWS
7878 Py_DECREF(os1);
7879#endif
7880 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00007881}
7882#endif /* unsetenv */
7883
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007884PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007885"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007886Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007887
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007888static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007889posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007890{
Victor Stinner8c62be82010-05-06 00:08:46 +00007891 int code;
7892 char *message;
7893 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7894 return NULL;
7895 message = strerror(code);
7896 if (message == NULL) {
7897 PyErr_SetString(PyExc_ValueError,
7898 "strerror() argument out of range");
7899 return NULL;
7900 }
7901 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007902}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007903
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007904
Guido van Rossumc9641791998-08-04 15:26:23 +00007905#ifdef HAVE_SYS_WAIT_H
7906
Fred Drake106c1a02002-04-23 15:58:02 +00007907#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007908PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007909"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007910Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007911
7912static PyObject *
7913posix_WCOREDUMP(PyObject *self, PyObject *args)
7914{
Victor Stinner8c62be82010-05-06 00:08:46 +00007915 WAIT_TYPE status;
7916 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007917
Victor Stinner8c62be82010-05-06 00:08:46 +00007918 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7919 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007920
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007922}
7923#endif /* WCOREDUMP */
7924
7925#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007926PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007927"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007928Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007929job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007930
7931static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007932posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007933{
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 WAIT_TYPE status;
7935 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007936
Victor Stinner8c62be82010-05-06 00:08:46 +00007937 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7938 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007939
Victor Stinner8c62be82010-05-06 00:08:46 +00007940 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007941}
7942#endif /* WIFCONTINUED */
7943
Guido van Rossumc9641791998-08-04 15:26:23 +00007944#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007945PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007946"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007947Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007948
7949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007950posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007951{
Victor Stinner8c62be82010-05-06 00:08:46 +00007952 WAIT_TYPE status;
7953 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007954
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7956 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007957
Victor Stinner8c62be82010-05-06 00:08:46 +00007958 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007959}
7960#endif /* WIFSTOPPED */
7961
7962#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007963PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007964"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007965Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007966
7967static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007968posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007969{
Victor Stinner8c62be82010-05-06 00:08:46 +00007970 WAIT_TYPE status;
7971 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007972
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7974 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007975
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007977}
7978#endif /* WIFSIGNALED */
7979
7980#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007981PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007982"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007983Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007984system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007985
7986static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007987posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007988{
Victor Stinner8c62be82010-05-06 00:08:46 +00007989 WAIT_TYPE status;
7990 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007991
Victor Stinner8c62be82010-05-06 00:08:46 +00007992 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7993 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007994
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007996}
7997#endif /* WIFEXITED */
7998
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007999#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008000PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008001"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008002Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008003
8004static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008005posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008006{
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 WAIT_TYPE status;
8008 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008009
Victor Stinner8c62be82010-05-06 00:08:46 +00008010 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8011 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008012
Victor Stinner8c62be82010-05-06 00:08:46 +00008013 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008014}
8015#endif /* WEXITSTATUS */
8016
8017#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008018PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008019"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008020Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008021value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008022
8023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008024posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008025{
Victor Stinner8c62be82010-05-06 00:08:46 +00008026 WAIT_TYPE status;
8027 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008028
Victor Stinner8c62be82010-05-06 00:08:46 +00008029 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8030 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008031
Victor Stinner8c62be82010-05-06 00:08:46 +00008032 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008033}
8034#endif /* WTERMSIG */
8035
8036#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008037PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008038"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008039Return the signal that stopped the process that provided\n\
8040the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008041
8042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008043posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008044{
Victor Stinner8c62be82010-05-06 00:08:46 +00008045 WAIT_TYPE status;
8046 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008047
Victor Stinner8c62be82010-05-06 00:08:46 +00008048 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8049 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008050
Victor Stinner8c62be82010-05-06 00:08:46 +00008051 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008052}
8053#endif /* WSTOPSIG */
8054
8055#endif /* HAVE_SYS_WAIT_H */
8056
8057
Thomas Wouters477c8d52006-05-27 19:21:47 +00008058#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008059#ifdef _SCO_DS
8060/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8061 needed definitions in sys/statvfs.h */
8062#define _SVID3
8063#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008064#include <sys/statvfs.h>
8065
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008066static PyObject*
8067_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008068 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8069 if (v == NULL)
8070 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008071
8072#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008073 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8074 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8075 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8076 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8077 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8078 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8079 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8080 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8081 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8082 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008083#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008084 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8085 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8086 PyStructSequence_SET_ITEM(v, 2,
8087 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8088 PyStructSequence_SET_ITEM(v, 3,
8089 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8090 PyStructSequence_SET_ITEM(v, 4,
8091 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8092 PyStructSequence_SET_ITEM(v, 5,
8093 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8094 PyStructSequence_SET_ITEM(v, 6,
8095 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8096 PyStructSequence_SET_ITEM(v, 7,
8097 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8098 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8099 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008100#endif
8101
Victor Stinner8c62be82010-05-06 00:08:46 +00008102 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008103}
8104
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008105PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008106"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008107Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008108
8109static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008110posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008111{
Victor Stinner8c62be82010-05-06 00:08:46 +00008112 int fd, res;
8113 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008114
Victor Stinner8c62be82010-05-06 00:08:46 +00008115 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8116 return NULL;
8117 Py_BEGIN_ALLOW_THREADS
8118 res = fstatvfs(fd, &st);
8119 Py_END_ALLOW_THREADS
8120 if (res != 0)
8121 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008122
Victor Stinner8c62be82010-05-06 00:08:46 +00008123 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008124}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008125#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008126
8127
Thomas Wouters477c8d52006-05-27 19:21:47 +00008128#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008129#include <sys/statvfs.h>
8130
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008131PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008132"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008133Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008134
8135static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008136posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008137{
Victor Stinner6fa67772011-09-20 04:04:33 +02008138 PyObject *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008139 int res;
8140 struct statvfs st;
Victor Stinner6fa67772011-09-20 04:04:33 +02008141 if (!PyArg_ParseTuple(args, "O&:statvfs", PyUnicode_FSConverter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00008142 return NULL;
8143 Py_BEGIN_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008144 res = statvfs(PyBytes_AS_STRING(path), &st);
Victor Stinner8c62be82010-05-06 00:08:46 +00008145 Py_END_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008146 if (res != 0) {
8147 posix_error_with_filename(PyBytes_AS_STRING(path));
8148 Py_DECREF(path);
8149 return NULL;
8150 }
8151 Py_DECREF(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008152
Victor Stinner8c62be82010-05-06 00:08:46 +00008153 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008154}
8155#endif /* HAVE_STATVFS */
8156
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008157#ifdef MS_WINDOWS
8158PyDoc_STRVAR(win32__getdiskusage__doc__,
8159"_getdiskusage(path) -> (total, free)\n\n\
8160Return disk usage statistics about the given path as (total, free) tuple.");
8161
8162static PyObject *
8163win32__getdiskusage(PyObject *self, PyObject *args)
8164{
8165 BOOL retval;
8166 ULARGE_INTEGER _, total, free;
8167 LPCTSTR path;
8168
8169 if (! PyArg_ParseTuple(args, "s", &path))
8170 return NULL;
8171
8172 Py_BEGIN_ALLOW_THREADS
8173 retval = GetDiskFreeSpaceEx(path, &_, &total, &free);
8174 Py_END_ALLOW_THREADS
8175 if (retval == 0)
8176 return PyErr_SetFromWindowsErr(0);
8177
8178 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8179}
8180#endif
8181
8182
Fred Drakec9680921999-12-13 16:37:25 +00008183/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8184 * It maps strings representing configuration variable names to
8185 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008186 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008187 * rarely-used constants. There are three separate tables that use
8188 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008189 *
8190 * This code is always included, even if none of the interfaces that
8191 * need it are included. The #if hackery needed to avoid it would be
8192 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008193 */
8194struct constdef {
8195 char *name;
8196 long value;
8197};
8198
Fred Drake12c6e2d1999-12-14 21:25:03 +00008199static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008200conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008201 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008202{
Christian Heimes217cfd12007-12-02 14:31:20 +00008203 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008204 *valuep = PyLong_AS_LONG(arg);
8205 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008206 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008207 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008208 /* look up the value in the table using a binary search */
8209 size_t lo = 0;
8210 size_t mid;
8211 size_t hi = tablesize;
8212 int cmp;
8213 const char *confname;
8214 if (!PyUnicode_Check(arg)) {
8215 PyErr_SetString(PyExc_TypeError,
8216 "configuration names must be strings or integers");
8217 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008218 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008219 confname = _PyUnicode_AsString(arg);
8220 if (confname == NULL)
8221 return 0;
8222 while (lo < hi) {
8223 mid = (lo + hi) / 2;
8224 cmp = strcmp(confname, table[mid].name);
8225 if (cmp < 0)
8226 hi = mid;
8227 else if (cmp > 0)
8228 lo = mid + 1;
8229 else {
8230 *valuep = table[mid].value;
8231 return 1;
8232 }
8233 }
8234 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8235 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008236 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008237}
8238
8239
8240#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8241static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008242#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008243 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008244#endif
8245#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008246 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008247#endif
Fred Drakec9680921999-12-13 16:37:25 +00008248#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008249 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008250#endif
8251#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008252 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008253#endif
8254#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008255 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008256#endif
8257#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008258 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008259#endif
8260#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008261 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008262#endif
8263#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008264 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008265#endif
8266#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008267 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008268#endif
8269#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008270 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008271#endif
8272#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008273 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008274#endif
8275#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008276 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008277#endif
8278#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008279 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008280#endif
8281#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008282 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008283#endif
8284#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008285 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008286#endif
8287#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008288 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008289#endif
8290#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008291 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008292#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008293#ifdef _PC_ACL_ENABLED
8294 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8295#endif
8296#ifdef _PC_MIN_HOLE_SIZE
8297 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8298#endif
8299#ifdef _PC_ALLOC_SIZE_MIN
8300 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8301#endif
8302#ifdef _PC_REC_INCR_XFER_SIZE
8303 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8304#endif
8305#ifdef _PC_REC_MAX_XFER_SIZE
8306 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8307#endif
8308#ifdef _PC_REC_MIN_XFER_SIZE
8309 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8310#endif
8311#ifdef _PC_REC_XFER_ALIGN
8312 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8313#endif
8314#ifdef _PC_SYMLINK_MAX
8315 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8316#endif
8317#ifdef _PC_XATTR_ENABLED
8318 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8319#endif
8320#ifdef _PC_XATTR_EXISTS
8321 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8322#endif
8323#ifdef _PC_TIMESTAMP_RESOLUTION
8324 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8325#endif
Fred Drakec9680921999-12-13 16:37:25 +00008326};
8327
Fred Drakec9680921999-12-13 16:37:25 +00008328static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008329conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008330{
8331 return conv_confname(arg, valuep, posix_constants_pathconf,
8332 sizeof(posix_constants_pathconf)
8333 / sizeof(struct constdef));
8334}
8335#endif
8336
8337#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008338PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008339"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008340Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008341If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008342
8343static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008344posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008345{
8346 PyObject *result = NULL;
8347 int name, fd;
8348
Fred Drake12c6e2d1999-12-14 21:25:03 +00008349 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8350 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008351 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008352
Stefan Krah0e803b32010-11-26 16:16:47 +00008353 errno = 0;
8354 limit = fpathconf(fd, name);
8355 if (limit == -1 && errno != 0)
8356 posix_error();
8357 else
8358 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008359 }
8360 return result;
8361}
8362#endif
8363
8364
8365#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008366PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008367"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008368Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008369If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008370
8371static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008372posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008373{
8374 PyObject *result = NULL;
8375 int name;
8376 char *path;
8377
8378 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
8379 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008380 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008381
Victor Stinner8c62be82010-05-06 00:08:46 +00008382 errno = 0;
8383 limit = pathconf(path, name);
8384 if (limit == -1 && errno != 0) {
8385 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008386 /* could be a path or name problem */
8387 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008388 else
Stefan Krah99439262010-11-26 12:58:05 +00008389 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008390 }
8391 else
8392 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008393 }
8394 return result;
8395}
8396#endif
8397
8398#ifdef HAVE_CONFSTR
8399static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008400#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008401 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008402#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008403#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008404 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008405#endif
8406#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008407 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008408#endif
Fred Draked86ed291999-12-15 15:34:33 +00008409#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008410 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008411#endif
8412#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008413 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008414#endif
8415#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008416 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008417#endif
8418#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008419 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008420#endif
Fred Drakec9680921999-12-13 16:37:25 +00008421#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008422 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008423#endif
8424#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008425 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008426#endif
8427#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008428 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008429#endif
8430#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008431 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008432#endif
8433#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008434 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008435#endif
8436#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008437 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008438#endif
8439#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008440 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008441#endif
8442#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008443 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008444#endif
Fred Draked86ed291999-12-15 15:34:33 +00008445#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008446 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008447#endif
Fred Drakec9680921999-12-13 16:37:25 +00008448#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008449 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008450#endif
Fred Draked86ed291999-12-15 15:34:33 +00008451#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008452 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008453#endif
8454#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008455 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008456#endif
8457#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008458 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008459#endif
8460#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008461 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008462#endif
Fred Drakec9680921999-12-13 16:37:25 +00008463#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008464 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008465#endif
8466#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008467 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008468#endif
8469#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008470 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008471#endif
8472#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008473 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008474#endif
8475#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008476 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008477#endif
8478#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008479 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008480#endif
8481#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008482 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008483#endif
8484#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008485 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008486#endif
8487#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008488 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008489#endif
8490#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008491 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008492#endif
8493#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008494 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008495#endif
8496#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008497 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008498#endif
8499#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008500 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008501#endif
8502#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008503 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008504#endif
8505#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008506 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008507#endif
8508#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008509 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008510#endif
Fred Draked86ed291999-12-15 15:34:33 +00008511#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008512 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008513#endif
8514#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008515 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008516#endif
8517#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008518 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008519#endif
8520#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008521 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008522#endif
8523#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008524 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008525#endif
8526#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008527 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008528#endif
8529#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008530 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008531#endif
8532#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008533 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008534#endif
8535#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008536 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008537#endif
8538#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008539 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008540#endif
8541#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008542 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008543#endif
8544#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008545 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008546#endif
8547#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008548 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008549#endif
Fred Drakec9680921999-12-13 16:37:25 +00008550};
8551
8552static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008553conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008554{
8555 return conv_confname(arg, valuep, posix_constants_confstr,
8556 sizeof(posix_constants_confstr)
8557 / sizeof(struct constdef));
8558}
8559
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008560PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008561"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008562Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008563
8564static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008565posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008566{
8567 PyObject *result = NULL;
8568 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008569 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008570 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008571
Victor Stinnercb043522010-09-10 23:49:04 +00008572 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8573 return NULL;
8574
8575 errno = 0;
8576 len = confstr(name, buffer, sizeof(buffer));
8577 if (len == 0) {
8578 if (errno) {
8579 posix_error();
8580 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008581 }
8582 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008583 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008584 }
8585 }
Victor Stinnercb043522010-09-10 23:49:04 +00008586
8587 if ((unsigned int)len >= sizeof(buffer)) {
8588 char *buf = PyMem_Malloc(len);
8589 if (buf == NULL)
8590 return PyErr_NoMemory();
8591 confstr(name, buf, len);
8592 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8593 PyMem_Free(buf);
8594 }
8595 else
8596 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008597 return result;
8598}
8599#endif
8600
8601
8602#ifdef HAVE_SYSCONF
8603static struct constdef posix_constants_sysconf[] = {
8604#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008605 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008606#endif
8607#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008608 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008609#endif
8610#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008611 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008612#endif
8613#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008614 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008615#endif
8616#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008617 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008618#endif
8619#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00008620 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008621#endif
8622#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00008623 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008624#endif
8625#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008626 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008627#endif
8628#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008629 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008630#endif
8631#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008632 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008633#endif
Fred Draked86ed291999-12-15 15:34:33 +00008634#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008635 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008636#endif
8637#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00008638 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008639#endif
Fred Drakec9680921999-12-13 16:37:25 +00008640#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008641 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008642#endif
Fred Drakec9680921999-12-13 16:37:25 +00008643#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008644 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008645#endif
8646#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008647 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008648#endif
8649#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008650 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008651#endif
8652#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008653 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008654#endif
8655#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008656 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008657#endif
Fred Draked86ed291999-12-15 15:34:33 +00008658#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008659 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008660#endif
Fred Drakec9680921999-12-13 16:37:25 +00008661#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008662 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008663#endif
8664#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008665 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008666#endif
8667#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008668 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008669#endif
8670#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008671 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008672#endif
8673#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008674 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008675#endif
Fred Draked86ed291999-12-15 15:34:33 +00008676#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00008677 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008678#endif
Fred Drakec9680921999-12-13 16:37:25 +00008679#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008680 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008681#endif
8682#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008683 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008684#endif
8685#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008686 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008687#endif
8688#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008689 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008690#endif
8691#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008692 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008693#endif
8694#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008695 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008696#endif
8697#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008698 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008699#endif
8700#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008701 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008702#endif
8703#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008704 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008705#endif
8706#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008707 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008708#endif
8709#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008710 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008711#endif
8712#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008713 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008714#endif
8715#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008716 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008717#endif
8718#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008719 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008720#endif
8721#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008722 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008723#endif
8724#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008725 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008726#endif
8727#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008728 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008729#endif
8730#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008731 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008732#endif
8733#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008734 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008735#endif
8736#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008737 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008738#endif
8739#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008740 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008741#endif
8742#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008743 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008744#endif
8745#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008746 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008747#endif
Fred Draked86ed291999-12-15 15:34:33 +00008748#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00008749 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008750#endif
Fred Drakec9680921999-12-13 16:37:25 +00008751#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008752 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008753#endif
8754#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008755 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008756#endif
8757#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008758 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008759#endif
Fred Draked86ed291999-12-15 15:34:33 +00008760#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008761 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008762#endif
Fred Drakec9680921999-12-13 16:37:25 +00008763#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00008764 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008765#endif
Fred Draked86ed291999-12-15 15:34:33 +00008766#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00008767 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008768#endif
8769#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00008770 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008771#endif
Fred Drakec9680921999-12-13 16:37:25 +00008772#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008773 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008774#endif
8775#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008776 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008777#endif
8778#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008779 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008780#endif
8781#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008782 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008783#endif
Fred Draked86ed291999-12-15 15:34:33 +00008784#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00008785 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008786#endif
Fred Drakec9680921999-12-13 16:37:25 +00008787#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00008788 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008789#endif
8790#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00008791 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008792#endif
8793#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008794 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008795#endif
8796#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008797 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008798#endif
8799#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008800 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008801#endif
8802#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00008803 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008804#endif
8805#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00008806 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008807#endif
Fred Draked86ed291999-12-15 15:34:33 +00008808#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00008809 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008810#endif
Fred Drakec9680921999-12-13 16:37:25 +00008811#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008812 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008813#endif
8814#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008815 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008816#endif
Fred Draked86ed291999-12-15 15:34:33 +00008817#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008818 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008819#endif
Fred Drakec9680921999-12-13 16:37:25 +00008820#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008821 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008822#endif
8823#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008824 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008825#endif
8826#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008827 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008828#endif
8829#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008830 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008831#endif
8832#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008833 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008834#endif
8835#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008836 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008837#endif
8838#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008839 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008840#endif
8841#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008842 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008843#endif
8844#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008845 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008846#endif
Fred Draked86ed291999-12-15 15:34:33 +00008847#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008848 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008849#endif
8850#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008851 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008852#endif
Fred Drakec9680921999-12-13 16:37:25 +00008853#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00008854 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008855#endif
8856#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008857 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008858#endif
8859#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008860 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008861#endif
8862#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008863 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008864#endif
8865#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008866 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008867#endif
8868#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008869 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008870#endif
8871#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00008872 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008873#endif
8874#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00008875 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008876#endif
8877#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008878 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008879#endif
8880#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008881 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008882#endif
8883#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00008884 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008885#endif
8886#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008887 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008888#endif
8889#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008890 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008891#endif
8892#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00008893 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008894#endif
8895#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00008896 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008897#endif
8898#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00008899 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008900#endif
8901#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00008902 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008903#endif
8904#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008905 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008906#endif
8907#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008908 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008909#endif
8910#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00008911 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008912#endif
8913#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008914 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008915#endif
8916#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008917 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008918#endif
8919#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00008920 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008921#endif
8922#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008923 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008924#endif
8925#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008926 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008927#endif
8928#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008929 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008930#endif
8931#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00008932 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008933#endif
8934#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008936#endif
8937#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008938 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008939#endif
8940#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008941 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008942#endif
8943#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008944 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008945#endif
8946#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008947 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008948#endif
8949#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008950 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008951#endif
8952#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008953 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008954#endif
8955#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008956 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008957#endif
Fred Draked86ed291999-12-15 15:34:33 +00008958#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00008959 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008960#endif
Fred Drakec9680921999-12-13 16:37:25 +00008961#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00008962 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008963#endif
8964#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008965 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008966#endif
8967#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00008968 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008969#endif
8970#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008971 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008972#endif
8973#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008974 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008975#endif
8976#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00008977 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008978#endif
8979#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00008980 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008981#endif
8982#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008983 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008984#endif
8985#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00008986 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008987#endif
8988#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008989 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008990#endif
8991#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008992 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008993#endif
8994#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008995 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008996#endif
8997#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008998 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008999#endif
9000#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009001 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009002#endif
9003#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009004 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009005#endif
9006#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009007 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009008#endif
9009#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009010 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009011#endif
9012#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009013 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009014#endif
9015#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009016 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009017#endif
9018#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009019 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009020#endif
9021#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009022 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009023#endif
9024#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009025 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009026#endif
9027#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009028 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009029#endif
9030#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009031 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009032#endif
9033#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009034 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009035#endif
9036#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009037 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009038#endif
9039#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009040 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009041#endif
9042#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009043 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009044#endif
9045#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009046 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009047#endif
9048#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009049 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009050#endif
9051#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009052 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009053#endif
9054#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009055 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009056#endif
9057#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009058 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009059#endif
9060#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009061 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009062#endif
9063#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009064 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009065#endif
9066#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009067 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009068#endif
9069#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009070 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009071#endif
9072#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009073 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009074#endif
9075#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009076 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009077#endif
9078#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009079 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009080#endif
9081#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009082 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009083#endif
9084#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009085 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009086#endif
9087#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009088 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009089#endif
9090#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009091 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009092#endif
9093#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009094 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009095#endif
9096};
9097
9098static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009099conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009100{
9101 return conv_confname(arg, valuep, posix_constants_sysconf,
9102 sizeof(posix_constants_sysconf)
9103 / sizeof(struct constdef));
9104}
9105
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009106PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009107"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009108Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009109
9110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009111posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009112{
9113 PyObject *result = NULL;
9114 int name;
9115
9116 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9117 int value;
9118
9119 errno = 0;
9120 value = sysconf(name);
9121 if (value == -1 && errno != 0)
9122 posix_error();
9123 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009124 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009125 }
9126 return result;
9127}
9128#endif
9129
9130
Fred Drakebec628d1999-12-15 18:31:10 +00009131/* This code is used to ensure that the tables of configuration value names
9132 * are in sorted order as required by conv_confname(), and also to build the
9133 * the exported dictionaries that are used to publish information about the
9134 * names available on the host platform.
9135 *
9136 * Sorting the table at runtime ensures that the table is properly ordered
9137 * when used, even for platforms we're not able to test on. It also makes
9138 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009139 */
Fred Drakebec628d1999-12-15 18:31:10 +00009140
9141static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009142cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009143{
9144 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009145 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009146 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009147 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009148
9149 return strcmp(c1->name, c2->name);
9150}
9151
9152static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009153setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009154 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009155{
Fred Drakebec628d1999-12-15 18:31:10 +00009156 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009157 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009158
9159 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9160 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009161 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009162 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009163
Barry Warsaw3155db32000-04-13 15:20:40 +00009164 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009165 PyObject *o = PyLong_FromLong(table[i].value);
9166 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9167 Py_XDECREF(o);
9168 Py_DECREF(d);
9169 return -1;
9170 }
9171 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009172 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009173 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009174}
9175
Fred Drakebec628d1999-12-15 18:31:10 +00009176/* Return -1 on failure, 0 on success. */
9177static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009178setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009179{
9180#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009181 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009182 sizeof(posix_constants_pathconf)
9183 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009184 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009185 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009186#endif
9187#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009188 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009189 sizeof(posix_constants_confstr)
9190 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009191 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009192 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009193#endif
9194#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009195 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009196 sizeof(posix_constants_sysconf)
9197 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009198 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009199 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009200#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009201 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009202}
Fred Draked86ed291999-12-15 15:34:33 +00009203
9204
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009205PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009206"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009207Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009208in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009209
9210static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009211posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009212{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009213 abort();
9214 /*NOTREACHED*/
9215 Py_FatalError("abort() called from Python code didn't abort!");
9216 return NULL;
9217}
Fred Drakebec628d1999-12-15 18:31:10 +00009218
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009219#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009220PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009221"startfile(filepath [, operation]) - Start a file with its associated\n\
9222application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009223\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009224When \"operation\" is not specified or \"open\", this acts like\n\
9225double-clicking the file in Explorer, or giving the file name as an\n\
9226argument to the DOS \"start\" command: the file is opened with whatever\n\
9227application (if any) its extension is associated.\n\
9228When another \"operation\" is given, it specifies what should be done with\n\
9229the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009230\n\
9231startfile returns as soon as the associated application is launched.\n\
9232There is no option to wait for the application to close, and no way\n\
9233to retrieve the application's exit status.\n\
9234\n\
9235The filepath is relative to the current directory. If you want to use\n\
9236an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009237the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009238
9239static PyObject *
9240win32_startfile(PyObject *self, PyObject *args)
9241{
Victor Stinner8c62be82010-05-06 00:08:46 +00009242 PyObject *ofilepath;
9243 char *filepath;
9244 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009245 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009246 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009247
Victor Stinnereb5657a2011-09-30 01:44:27 +02009248 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009249 if (!PyArg_ParseTuple(args, "U|s:startfile",
9250 &unipath, &operation)) {
9251 PyErr_Clear();
9252 goto normal;
9253 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009254
Victor Stinner8c62be82010-05-06 00:08:46 +00009255 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009256 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009257 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009258 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009259 PyErr_Clear();
9260 operation = NULL;
9261 goto normal;
9262 }
9263 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009264
Victor Stinnereb5657a2011-09-30 01:44:27 +02009265 wpath = PyUnicode_AsUnicode(unipath);
9266 if (wpath == NULL)
9267 goto normal;
9268 if (uoperation) {
9269 woperation = PyUnicode_AsUnicode(uoperation);
9270 if (woperation == NULL)
9271 goto normal;
9272 }
9273 else
9274 woperation = NULL;
9275
Victor Stinner8c62be82010-05-06 00:08:46 +00009276 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009277 rc = ShellExecuteW((HWND)0, woperation, wpath,
9278 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009279 Py_END_ALLOW_THREADS
9280
Victor Stinnereb5657a2011-09-30 01:44:27 +02009281 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009282 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009283 win32_error_object("startfile", unipath);
9284 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009285 }
9286 Py_INCREF(Py_None);
9287 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009288
9289normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009290 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9291 PyUnicode_FSConverter, &ofilepath,
9292 &operation))
9293 return NULL;
9294 filepath = PyBytes_AsString(ofilepath);
9295 Py_BEGIN_ALLOW_THREADS
9296 rc = ShellExecute((HWND)0, operation, filepath,
9297 NULL, NULL, SW_SHOWNORMAL);
9298 Py_END_ALLOW_THREADS
9299 if (rc <= (HINSTANCE)32) {
9300 PyObject *errval = win32_error("startfile", filepath);
9301 Py_DECREF(ofilepath);
9302 return errval;
9303 }
9304 Py_DECREF(ofilepath);
9305 Py_INCREF(Py_None);
9306 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009307}
9308#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009309
Martin v. Löwis438b5342002-12-27 10:16:42 +00009310#ifdef HAVE_GETLOADAVG
9311PyDoc_STRVAR(posix_getloadavg__doc__,
9312"getloadavg() -> (float, float, float)\n\n\
9313Return the number of processes in the system run queue averaged over\n\
9314the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9315was unobtainable");
9316
9317static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009318posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009319{
9320 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009321 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009322 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9323 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009324 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009325 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009326}
9327#endif
9328
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009329#ifdef MS_WINDOWS
9330
9331PyDoc_STRVAR(win32_urandom__doc__,
9332"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009333Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009334
9335typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
9336 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
9337 DWORD dwFlags );
9338typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
9339 BYTE *pbBuffer );
9340
9341static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00009342/* This handle is never explicitly released. Instead, the operating
9343 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009344static HCRYPTPROV hCryptProv = 0;
9345
Tim Peters4ad82172004-08-30 17:02:04 +00009346static PyObject*
9347win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009348{
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 int howMany;
9350 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009351
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 /* Read arguments */
9353 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9354 return NULL;
9355 if (howMany < 0)
9356 return PyErr_Format(PyExc_ValueError,
9357 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009358
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 if (hCryptProv == 0) {
9360 HINSTANCE hAdvAPI32 = NULL;
9361 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009362
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 /* Obtain handle to the DLL containing CryptoAPI
9364 This should not fail */
9365 hAdvAPI32 = GetModuleHandle("advapi32.dll");
9366 if(hAdvAPI32 == NULL)
9367 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009368
Victor Stinner8c62be82010-05-06 00:08:46 +00009369 /* Obtain pointers to the CryptoAPI functions
9370 This will fail on some early versions of Win95 */
9371 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
9372 hAdvAPI32,
9373 "CryptAcquireContextA");
9374 if (pCryptAcquireContext == NULL)
9375 return PyErr_Format(PyExc_NotImplementedError,
9376 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009377
Victor Stinner8c62be82010-05-06 00:08:46 +00009378 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
9379 hAdvAPI32, "CryptGenRandom");
9380 if (pCryptGenRandom == NULL)
9381 return PyErr_Format(PyExc_NotImplementedError,
9382 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009383
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 /* Acquire context */
9385 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
9386 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
9387 return win32_error("CryptAcquireContext", NULL);
9388 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009389
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 /* Allocate bytes */
9391 result = PyBytes_FromStringAndSize(NULL, howMany);
9392 if (result != NULL) {
9393 /* Get random data */
9394 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
9395 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
9396 PyBytes_AS_STRING(result))) {
9397 Py_DECREF(result);
9398 return win32_error("CryptGenRandom", NULL);
9399 }
9400 }
9401 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009402}
9403#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009404
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009405PyDoc_STRVAR(device_encoding__doc__,
9406"device_encoding(fd) -> str\n\n\
9407Return a string describing the encoding of the device\n\
9408if the output is a terminal; else return None.");
9409
9410static PyObject *
9411device_encoding(PyObject *self, PyObject *args)
9412{
Victor Stinner8c62be82010-05-06 00:08:46 +00009413 int fd;
Victor Stinner7870bdf2011-05-23 18:12:52 +02009414#if defined(MS_WINDOWS) || defined(MS_WIN64)
9415 UINT cp;
9416#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009417 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9418 return NULL;
9419 if (!_PyVerify_fd(fd) || !isatty(fd)) {
9420 Py_INCREF(Py_None);
9421 return Py_None;
9422 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009423#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner7870bdf2011-05-23 18:12:52 +02009424 if (fd == 0)
9425 cp = GetConsoleCP();
9426 else if (fd == 1 || fd == 2)
9427 cp = GetConsoleOutputCP();
9428 else
9429 cp = 0;
9430 /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application
9431 has no console */
9432 if (cp != 0)
9433 return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009434#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00009435 {
9436 char *codeset = nl_langinfo(CODESET);
9437 if (codeset != NULL && codeset[0] != 0)
9438 return PyUnicode_FromString(codeset);
9439 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009440#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009441 Py_INCREF(Py_None);
9442 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009443}
9444
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009445#ifdef __VMS
9446/* Use openssl random routine */
9447#include <openssl/rand.h>
9448PyDoc_STRVAR(vms_urandom__doc__,
9449"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009450Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009451
9452static PyObject*
9453vms_urandom(PyObject *self, PyObject *args)
9454{
Victor Stinner8c62be82010-05-06 00:08:46 +00009455 int howMany;
9456 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009457
Victor Stinner8c62be82010-05-06 00:08:46 +00009458 /* Read arguments */
9459 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9460 return NULL;
9461 if (howMany < 0)
9462 return PyErr_Format(PyExc_ValueError,
9463 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009464
Victor Stinner8c62be82010-05-06 00:08:46 +00009465 /* Allocate bytes */
9466 result = PyBytes_FromStringAndSize(NULL, howMany);
9467 if (result != NULL) {
9468 /* Get random data */
9469 if (RAND_pseudo_bytes((unsigned char*)
9470 PyBytes_AS_STRING(result),
9471 howMany) < 0) {
9472 Py_DECREF(result);
9473 return PyErr_Format(PyExc_ValueError,
9474 "RAND_pseudo_bytes");
9475 }
9476 }
9477 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009478}
9479#endif
9480
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009481#ifdef HAVE_SETRESUID
9482PyDoc_STRVAR(posix_setresuid__doc__,
9483"setresuid(ruid, euid, suid)\n\n\
9484Set the current process's real, effective, and saved user ids.");
9485
9486static PyObject*
9487posix_setresuid (PyObject *self, PyObject *args)
9488{
Victor Stinner8c62be82010-05-06 00:08:46 +00009489 /* We assume uid_t is no larger than a long. */
9490 long ruid, euid, suid;
9491 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9492 return NULL;
9493 if (setresuid(ruid, euid, suid) < 0)
9494 return posix_error();
9495 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009496}
9497#endif
9498
9499#ifdef HAVE_SETRESGID
9500PyDoc_STRVAR(posix_setresgid__doc__,
9501"setresgid(rgid, egid, sgid)\n\n\
9502Set the current process's real, effective, and saved group ids.");
9503
9504static PyObject*
9505posix_setresgid (PyObject *self, PyObject *args)
9506{
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 /* We assume uid_t is no larger than a long. */
9508 long rgid, egid, sgid;
9509 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9510 return NULL;
9511 if (setresgid(rgid, egid, sgid) < 0)
9512 return posix_error();
9513 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009514}
9515#endif
9516
9517#ifdef HAVE_GETRESUID
9518PyDoc_STRVAR(posix_getresuid__doc__,
9519"getresuid() -> (ruid, euid, suid)\n\n\
9520Get tuple of the current process's real, effective, and saved user ids.");
9521
9522static PyObject*
9523posix_getresuid (PyObject *self, PyObject *noargs)
9524{
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 uid_t ruid, euid, suid;
9526 long l_ruid, l_euid, l_suid;
9527 if (getresuid(&ruid, &euid, &suid) < 0)
9528 return posix_error();
9529 /* Force the values into long's as we don't know the size of uid_t. */
9530 l_ruid = ruid;
9531 l_euid = euid;
9532 l_suid = suid;
9533 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009534}
9535#endif
9536
9537#ifdef HAVE_GETRESGID
9538PyDoc_STRVAR(posix_getresgid__doc__,
9539"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009540Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009541
9542static PyObject*
9543posix_getresgid (PyObject *self, PyObject *noargs)
9544{
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 uid_t rgid, egid, sgid;
9546 long l_rgid, l_egid, l_sgid;
9547 if (getresgid(&rgid, &egid, &sgid) < 0)
9548 return posix_error();
9549 /* Force the values into long's as we don't know the size of uid_t. */
9550 l_rgid = rgid;
9551 l_egid = egid;
9552 l_sgid = sgid;
9553 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009554}
9555#endif
9556
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009557/* Posix *at family of functions:
9558 faccessat, fchmodat, fchownat, fstatat, futimesat,
9559 linkat, mkdirat, mknodat, openat, readlinkat, renameat, symlinkat,
9560 unlinkat, utimensat, mkfifoat */
9561
9562#ifdef HAVE_FACCESSAT
9563PyDoc_STRVAR(posix_faccessat__doc__,
9564"faccessat(dirfd, path, mode, flags=0) -> True if granted, False otherwise\n\n\
9565Like access() but if path is relative, it is taken as relative to dirfd.\n\
9566flags is optional and can be constructed by ORing together zero or more\n\
9567of these values: AT_SYMLINK_NOFOLLOW, AT_EACCESS.\n\
9568If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9569is interpreted relative to the current working directory.");
9570
9571static PyObject *
9572posix_faccessat(PyObject *self, PyObject *args)
9573{
9574 PyObject *opath;
9575 char *path;
9576 int mode;
9577 int res;
9578 int dirfd, flags = 0;
9579 if (!PyArg_ParseTuple(args, "iO&i|i:faccessat",
9580 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9581 return NULL;
9582 path = PyBytes_AsString(opath);
9583 Py_BEGIN_ALLOW_THREADS
9584 res = faccessat(dirfd, path, mode, flags);
9585 Py_END_ALLOW_THREADS
9586 Py_DECREF(opath);
9587 return PyBool_FromLong(res == 0);
9588}
9589#endif
9590
9591#ifdef HAVE_FCHMODAT
9592PyDoc_STRVAR(posix_fchmodat__doc__,
9593"fchmodat(dirfd, path, mode, flags=0)\n\n\
9594Like chmod() but if path is relative, it is taken as relative to dirfd.\n\
9595flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9596If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9597is interpreted relative to the current working directory.");
9598
9599static PyObject *
9600posix_fchmodat(PyObject *self, PyObject *args)
9601{
9602 int dirfd, mode, res;
9603 int flags = 0;
9604 PyObject *opath;
9605 char *path;
9606
9607 if (!PyArg_ParseTuple(args, "iO&i|i:fchmodat",
9608 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9609 return NULL;
9610
9611 path = PyBytes_AsString(opath);
9612
9613 Py_BEGIN_ALLOW_THREADS
9614 res = fchmodat(dirfd, path, mode, flags);
9615 Py_END_ALLOW_THREADS
9616 Py_DECREF(opath);
9617 if (res < 0)
9618 return posix_error();
9619 Py_RETURN_NONE;
9620}
9621#endif /* HAVE_FCHMODAT */
9622
9623#ifdef HAVE_FCHOWNAT
9624PyDoc_STRVAR(posix_fchownat__doc__,
9625"fchownat(dirfd, path, uid, gid, flags=0)\n\n\
9626Like chown() but if path is relative, it is taken as relative to dirfd.\n\
9627flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9628If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9629is interpreted relative to the current working directory.");
9630
9631static PyObject *
9632posix_fchownat(PyObject *self, PyObject *args)
9633{
9634 PyObject *opath;
9635 int dirfd, res;
9636 long uid, gid;
9637 int flags = 0;
9638 char *path;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009639
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009640 if (!PyArg_ParseTuple(args, "iO&ll|i:fchownat",
9641 &dirfd, PyUnicode_FSConverter, &opath, &uid, &gid, &flags))
9642 return NULL;
9643
9644 path = PyBytes_AsString(opath);
9645
9646 Py_BEGIN_ALLOW_THREADS
9647 res = fchownat(dirfd, path, (uid_t) uid, (gid_t) gid, flags);
9648 Py_END_ALLOW_THREADS
9649 Py_DECREF(opath);
9650 if (res < 0)
9651 return posix_error();
9652 Py_RETURN_NONE;
9653}
9654#endif /* HAVE_FCHOWNAT */
9655
9656#ifdef HAVE_FSTATAT
9657PyDoc_STRVAR(posix_fstatat__doc__,
9658"fstatat(dirfd, path, flags=0) -> stat result\n\n\
9659Like stat() but if path is relative, it is taken as relative to dirfd.\n\
9660flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9661If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9662is interpreted relative to the current working directory.");
9663
9664static PyObject *
9665posix_fstatat(PyObject *self, PyObject *args)
9666{
9667 PyObject *opath;
9668 char *path;
9669 STRUCT_STAT st;
9670 int dirfd, res, flags = 0;
9671
9672 if (!PyArg_ParseTuple(args, "iO&|i:fstatat",
9673 &dirfd, PyUnicode_FSConverter, &opath, &flags))
9674 return NULL;
9675 path = PyBytes_AsString(opath);
9676
9677 Py_BEGIN_ALLOW_THREADS
9678 res = fstatat(dirfd, path, &st, flags);
9679 Py_END_ALLOW_THREADS
9680 Py_DECREF(opath);
9681 if (res != 0)
9682 return posix_error();
9683
9684 return _pystat_fromstructstat(&st);
9685}
9686#endif
9687
9688#ifdef HAVE_FUTIMESAT
9689PyDoc_STRVAR(posix_futimesat__doc__,
9690"futimesat(dirfd, path, (atime, mtime))\n\
9691futimesat(dirfd, path, None)\n\n\
9692Like utime() but if path is relative, it is taken as relative to dirfd.\n\
9693If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9694is interpreted relative to the current working directory.");
9695
9696static PyObject *
9697posix_futimesat(PyObject *self, PyObject *args)
9698{
9699 PyObject *opath;
9700 char *path;
9701 int res, dirfd;
9702 PyObject* arg;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009703 time_t atime, mtime;
9704 long ausec, musec;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009705
9706 if (!PyArg_ParseTuple(args, "iO&O:futimesat",
9707 &dirfd, PyUnicode_FSConverter, &opath, &arg))
9708 return NULL;
9709 path = PyBytes_AsString(opath);
9710 if (arg == Py_None) {
9711 /* optional time values not given */
9712 Py_BEGIN_ALLOW_THREADS
9713 res = futimesat(dirfd, path, NULL);
9714 Py_END_ALLOW_THREADS
9715 }
9716 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
9717 PyErr_SetString(PyExc_TypeError,
9718 "futimesat() arg 3 must be a tuple (atime, mtime)");
9719 Py_DECREF(opath);
9720 return NULL;
9721 }
9722 else {
9723 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009724 &atime, &ausec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009725 Py_DECREF(opath);
9726 return NULL;
9727 }
9728 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009729 &mtime, &musec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009730 Py_DECREF(opath);
9731 return NULL;
9732 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009733
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009734 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009735 {
9736#ifdef HAVE_UTIMENSAT
9737 struct timespec buf[2];
9738 buf[0].tv_sec = atime;
9739 buf[0].tv_nsec = ausec;
9740 buf[1].tv_sec = mtime;
9741 buf[1].tv_nsec = musec;
9742 res = utimensat(dirfd, path, buf, 0);
9743#else
9744 struct timeval buf[2];
9745 buf[0].tv_sec = atime;
9746 buf[0].tv_usec = ausec;
9747 buf[1].tv_sec = mtime;
9748 buf[1].tv_usec = musec;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009749 res = futimesat(dirfd, path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009750#endif
9751 }
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009752 Py_END_ALLOW_THREADS
9753 }
9754 Py_DECREF(opath);
9755 if (res < 0) {
9756 return posix_error();
9757 }
9758 Py_RETURN_NONE;
9759}
9760#endif
9761
9762#ifdef HAVE_LINKAT
9763PyDoc_STRVAR(posix_linkat__doc__,
9764"linkat(srcfd, srcpath, dstfd, dstpath, flags=0)\n\n\
9765Like link() but if srcpath is relative, it is taken as relative to srcfd\n\
9766and if dstpath is relative, it is taken as relative to dstfd.\n\
9767flags is optional and may be 0 or AT_SYMLINK_FOLLOW.\n\
9768If srcpath is relative and srcfd is the special value AT_FDCWD, then\n\
9769srcpath is interpreted relative to the current working directory. This\n\
9770also applies for dstpath.");
9771
9772static PyObject *
9773posix_linkat(PyObject *self, PyObject *args)
9774{
9775 PyObject *osrc, *odst;
9776 char *src, *dst;
9777 int res, srcfd, dstfd;
9778 int flags = 0;
9779
9780 if (!PyArg_ParseTuple(args, "iO&iO&|i:linkat",
9781 &srcfd, PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst, &flags))
9782 return NULL;
9783 src = PyBytes_AsString(osrc);
9784 dst = PyBytes_AsString(odst);
9785 Py_BEGIN_ALLOW_THREADS
9786 res = linkat(srcfd, src, dstfd, dst, flags);
9787 Py_END_ALLOW_THREADS
9788 Py_DECREF(osrc);
9789 Py_DECREF(odst);
9790 if (res < 0)
9791 return posix_error();
9792 Py_RETURN_NONE;
9793}
9794#endif /* HAVE_LINKAT */
9795
9796#ifdef HAVE_MKDIRAT
9797PyDoc_STRVAR(posix_mkdirat__doc__,
9798"mkdirat(dirfd, path, mode=0o777)\n\n\
9799Like mkdir() but if path is relative, it is taken as relative to dirfd.\n\
9800If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9801is interpreted relative to the current working directory.");
9802
9803static PyObject *
9804posix_mkdirat(PyObject *self, PyObject *args)
9805{
9806 int res, dirfd;
9807 PyObject *opath;
9808 char *path;
9809 int mode = 0777;
9810
9811 if (!PyArg_ParseTuple(args, "iO&|i:mkdirat",
9812 &dirfd, PyUnicode_FSConverter, &opath, &mode))
9813 return NULL;
9814 path = PyBytes_AsString(opath);
9815 Py_BEGIN_ALLOW_THREADS
9816 res = mkdirat(dirfd, path, mode);
9817 Py_END_ALLOW_THREADS
9818 Py_DECREF(opath);
9819 if (res < 0)
9820 return posix_error();
9821 Py_RETURN_NONE;
9822}
9823#endif
9824
9825#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
9826PyDoc_STRVAR(posix_mknodat__doc__,
9827"mknodat(dirfd, path, mode=0o600, device=0)\n\n\
9828Like mknod() but if path is relative, it is taken as relative to dirfd.\n\
9829If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9830is interpreted relative to the current working directory.");
9831
9832static PyObject *
9833posix_mknodat(PyObject *self, PyObject *args)
9834{
9835 PyObject *opath;
9836 char *filename;
9837 int mode = 0600;
9838 int device = 0;
9839 int res, dirfd;
9840 if (!PyArg_ParseTuple(args, "iO&|ii:mknodat", &dirfd,
9841 PyUnicode_FSConverter, &opath, &mode, &device))
9842 return NULL;
9843 filename = PyBytes_AS_STRING(opath);
9844 Py_BEGIN_ALLOW_THREADS
9845 res = mknodat(dirfd, filename, mode, device);
9846 Py_END_ALLOW_THREADS
9847 Py_DECREF(opath);
9848 if (res < 0)
9849 return posix_error();
9850 Py_RETURN_NONE;
9851}
9852#endif
9853
9854#ifdef HAVE_OPENAT
9855PyDoc_STRVAR(posix_openat__doc__,
9856"openat(dirfd, path, flag, mode=0o777) -> fd\n\n\
9857Like open() but if path is relative, it is taken as relative to dirfd.\n\
9858If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9859is interpreted relative to the current working directory.");
9860
9861static PyObject *
9862posix_openat(PyObject *self, PyObject *args)
9863{
9864 PyObject *ofile;
9865 char *file;
9866 int flag, dirfd, fd;
9867 int mode = 0777;
9868
9869 if (!PyArg_ParseTuple(args, "iO&i|i:openat",
9870 &dirfd, PyUnicode_FSConverter, &ofile,
9871 &flag, &mode))
9872 return NULL;
9873 file = PyBytes_AsString(ofile);
9874 Py_BEGIN_ALLOW_THREADS
9875 fd = openat(dirfd, file, flag, mode);
9876 Py_END_ALLOW_THREADS
9877 Py_DECREF(ofile);
9878 if (fd < 0)
9879 return posix_error();
9880 return PyLong_FromLong((long)fd);
9881}
9882#endif
9883
9884#ifdef HAVE_READLINKAT
9885PyDoc_STRVAR(posix_readlinkat__doc__,
9886"readlinkat(dirfd, path) -> path\n\n\
9887Like readlink() but if path is relative, it is taken as relative to dirfd.\n\
9888If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9889is interpreted relative to the current working directory.");
9890
9891static PyObject *
9892posix_readlinkat(PyObject *self, PyObject *args)
9893{
9894 PyObject *v, *opath;
9895 char buf[MAXPATHLEN];
9896 char *path;
9897 int n, dirfd;
9898 int arg_is_unicode = 0;
9899
9900 if (!PyArg_ParseTuple(args, "iO&:readlinkat",
9901 &dirfd, PyUnicode_FSConverter, &opath))
9902 return NULL;
9903 path = PyBytes_AsString(opath);
9904 v = PySequence_GetItem(args, 1);
9905 if (v == NULL) {
9906 Py_DECREF(opath);
9907 return NULL;
9908 }
9909
9910 if (PyUnicode_Check(v)) {
9911 arg_is_unicode = 1;
9912 }
9913 Py_DECREF(v);
9914
9915 Py_BEGIN_ALLOW_THREADS
9916 n = readlinkat(dirfd, path, buf, (int) sizeof buf);
9917 Py_END_ALLOW_THREADS
9918 Py_DECREF(opath);
9919 if (n < 0)
9920 return posix_error();
9921
9922 if (arg_is_unicode)
9923 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
9924 else
9925 return PyBytes_FromStringAndSize(buf, n);
9926}
9927#endif /* HAVE_READLINKAT */
9928
9929#ifdef HAVE_RENAMEAT
9930PyDoc_STRVAR(posix_renameat__doc__,
9931"renameat(olddirfd, oldpath, newdirfd, newpath)\n\n\
9932Like rename() but if oldpath is relative, it is taken as relative to\n\
9933olddirfd and if newpath is relative, it is taken as relative to newdirfd.\n\
9934If oldpath is relative and olddirfd is the special value AT_FDCWD, then\n\
9935oldpath is interpreted relative to the current working directory. This\n\
9936also applies for newpath.");
9937
9938static PyObject *
9939posix_renameat(PyObject *self, PyObject *args)
9940{
9941 int res;
9942 PyObject *opathold, *opathnew;
9943 char *opath, *npath;
9944 int oldfd, newfd;
9945
9946 if (!PyArg_ParseTuple(args, "iO&iO&:renameat",
9947 &oldfd, PyUnicode_FSConverter, &opathold, &newfd, PyUnicode_FSConverter, &opathnew))
9948 return NULL;
9949 opath = PyBytes_AsString(opathold);
9950 npath = PyBytes_AsString(opathnew);
9951 Py_BEGIN_ALLOW_THREADS
9952 res = renameat(oldfd, opath, newfd, npath);
9953 Py_END_ALLOW_THREADS
9954 Py_DECREF(opathold);
9955 Py_DECREF(opathnew);
9956 if (res < 0)
9957 return posix_error();
9958 Py_RETURN_NONE;
9959}
9960#endif
9961
9962#if HAVE_SYMLINKAT
9963PyDoc_STRVAR(posix_symlinkat__doc__,
9964"symlinkat(src, dstfd, dst)\n\n\
9965Like symlink() but if dst is relative, it is taken as relative to dstfd.\n\
9966If dst is relative and dstfd is the special value AT_FDCWD, then dst\n\
9967is interpreted relative to the current working directory.");
9968
9969static PyObject *
9970posix_symlinkat(PyObject *self, PyObject *args)
9971{
9972 int res, dstfd;
9973 PyObject *osrc, *odst;
9974 char *src, *dst;
9975
9976 if (!PyArg_ParseTuple(args, "O&iO&:symlinkat",
9977 PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst))
9978 return NULL;
9979 src = PyBytes_AsString(osrc);
9980 dst = PyBytes_AsString(odst);
9981 Py_BEGIN_ALLOW_THREADS
9982 res = symlinkat(src, dstfd, dst);
9983 Py_END_ALLOW_THREADS
9984 Py_DECREF(osrc);
9985 Py_DECREF(odst);
9986 if (res < 0)
9987 return posix_error();
9988 Py_RETURN_NONE;
9989}
9990#endif /* HAVE_SYMLINKAT */
9991
9992#ifdef HAVE_UNLINKAT
9993PyDoc_STRVAR(posix_unlinkat__doc__,
9994"unlinkat(dirfd, path, flags=0)\n\n\
9995Like unlink() but if path is relative, it is taken as relative to dirfd.\n\
9996flags is optional and may be 0 or AT_REMOVEDIR. If AT_REMOVEDIR is\n\
9997specified, unlinkat() behaves like rmdir().\n\
9998If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9999is interpreted relative to the current working directory.");
10000
10001static PyObject *
10002posix_unlinkat(PyObject *self, PyObject *args)
10003{
10004 int dirfd, res, flags = 0;
10005 PyObject *opath;
10006 char *path;
10007
10008 if (!PyArg_ParseTuple(args, "iO&|i:unlinkat",
10009 &dirfd, PyUnicode_FSConverter, &opath, &flags))
10010 return NULL;
10011 path = PyBytes_AsString(opath);
10012 Py_BEGIN_ALLOW_THREADS
10013 res = unlinkat(dirfd, path, flags);
10014 Py_END_ALLOW_THREADS
10015 Py_DECREF(opath);
10016 if (res < 0)
10017 return posix_error();
10018 Py_RETURN_NONE;
10019}
10020#endif
10021
10022#ifdef HAVE_UTIMENSAT
10023PyDoc_STRVAR(posix_utimensat__doc__,
10024"utimensat(dirfd, path, (atime_sec, atime_nsec),\n\
10025 (mtime_sec, mtime_nsec), flags)\n\
10026utimensat(dirfd, path, None, None, flags)\n\n\
10027Updates the timestamps of a file with nanosecond precision. If path is\n\
10028relative, it is taken as relative to dirfd.\n\
10029The second form sets atime and mtime to the current time.\n\
10030flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
10031If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10032is interpreted relative to the current working directory.\n\
10033If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
10034current time.\n\
10035If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
10036
10037static PyObject *
10038posix_utimensat(PyObject *self, PyObject *args)
10039{
10040 PyObject *opath;
10041 char *path;
10042 int res, dirfd, flags = 0;
10043 PyObject *atime, *mtime;
10044
10045 struct timespec buf[2];
10046
10047 if (!PyArg_ParseTuple(args, "iO&OO|i:utimensat",
10048 &dirfd, PyUnicode_FSConverter, &opath, &atime, &mtime, &flags))
10049 return NULL;
10050 path = PyBytes_AsString(opath);
10051 if (atime == Py_None && mtime == Py_None) {
10052 /* optional time values not given */
10053 Py_BEGIN_ALLOW_THREADS
10054 res = utimensat(dirfd, path, NULL, flags);
10055 Py_END_ALLOW_THREADS
10056 }
10057 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
10058 PyErr_SetString(PyExc_TypeError,
10059 "utimensat() arg 3 must be a tuple (atime_sec, atime_nsec)");
10060 Py_DECREF(opath);
10061 return NULL;
10062 }
10063 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
10064 PyErr_SetString(PyExc_TypeError,
10065 "utimensat() arg 4 must be a tuple (mtime_sec, mtime_nsec)");
10066 Py_DECREF(opath);
10067 return NULL;
10068 }
10069 else {
10070 if (!PyArg_ParseTuple(atime, "ll:utimensat",
10071 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
10072 Py_DECREF(opath);
10073 return NULL;
10074 }
10075 if (!PyArg_ParseTuple(mtime, "ll:utimensat",
10076 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
10077 Py_DECREF(opath);
10078 return NULL;
10079 }
10080 Py_BEGIN_ALLOW_THREADS
10081 res = utimensat(dirfd, path, buf, flags);
10082 Py_END_ALLOW_THREADS
10083 }
10084 Py_DECREF(opath);
10085 if (res < 0) {
10086 return posix_error();
10087 }
10088 Py_RETURN_NONE;
10089}
10090#endif
10091
10092#ifdef HAVE_MKFIFOAT
10093PyDoc_STRVAR(posix_mkfifoat__doc__,
10094"mkfifoat(dirfd, path, mode=0o666)\n\n\
10095Like mkfifo() but if path is relative, it is taken as relative to dirfd.\n\
10096If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10097is interpreted relative to the current working directory.");
10098
10099static PyObject *
10100posix_mkfifoat(PyObject *self, PyObject *args)
10101{
10102 PyObject *opath;
10103 char *filename;
10104 int mode = 0666;
10105 int res, dirfd;
10106 if (!PyArg_ParseTuple(args, "iO&|i:mkfifoat",
10107 &dirfd, PyUnicode_FSConverter, &opath, &mode))
10108 return NULL;
10109 filename = PyBytes_AS_STRING(opath);
10110 Py_BEGIN_ALLOW_THREADS
10111 res = mkfifoat(dirfd, filename, mode);
10112 Py_END_ALLOW_THREADS
10113 Py_DECREF(opath);
10114 if (res < 0)
10115 return posix_error();
10116 Py_RETURN_NONE;
10117}
10118#endif
10119
Benjamin Peterson9428d532011-09-14 11:45:52 -040010120#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010121
10122static int
10123try_getxattr(const char *path, const char *name,
10124 ssize_t (*get)(const char *, const char *, void *, size_t),
10125 Py_ssize_t buf_size, PyObject **res)
10126{
10127 PyObject *value;
10128 Py_ssize_t len;
10129
10130 assert(buf_size <= XATTR_SIZE_MAX);
10131 value = PyBytes_FromStringAndSize(NULL, buf_size);
10132 if (!value)
10133 return 0;
10134 Py_BEGIN_ALLOW_THREADS;
10135 len = get(path, name, PyBytes_AS_STRING(value), buf_size);
10136 Py_END_ALLOW_THREADS;
10137 if (len < 0) {
10138 Py_DECREF(value);
10139 if (errno == ERANGE) {
10140 value = NULL;
10141 }
10142 else {
10143 posix_error();
10144 return 0;
10145 }
10146 }
10147 else if (len != buf_size) {
10148 /* Can only shrink. */
10149 _PyBytes_Resize(&value, len);
10150 }
10151 *res = value;
10152 return 1;
10153}
10154
10155static PyObject *
10156getxattr_common(const char *path, PyObject *name_obj,
10157 ssize_t (*get)(const char *, const char *, void *, size_t))
10158{
10159 PyObject *value;
10160 const char *name = PyBytes_AS_STRING(name_obj);
10161
10162 /* Try a small value first. */
10163 if (!try_getxattr(path, name, get, 128, &value))
10164 return NULL;
10165 if (value)
10166 return value;
10167 /* Now the maximum possible one. */
10168 if (!try_getxattr(path, name, get, XATTR_SIZE_MAX, &value))
10169 return NULL;
10170 assert(value);
10171 return value;
10172}
10173
10174PyDoc_STRVAR(posix_getxattr__doc__,
10175"getxattr(path, attr) -> value\n\n\
10176Return the value of extended attribute *name* on *path*.");
10177
10178static PyObject *
10179posix_getxattr(PyObject *self, PyObject *args)
10180{
10181 PyObject *path, *res, *name;
10182
10183 if (!PyArg_ParseTuple(args, "O&O&:getxattr", PyUnicode_FSConverter, &path,
10184 PyUnicode_FSConverter, &name))
10185 return NULL;
10186 res = getxattr_common(PyBytes_AS_STRING(path), name, getxattr);
10187 Py_DECREF(path);
10188 Py_DECREF(name);
10189 return res;
10190}
10191
10192PyDoc_STRVAR(posix_lgetxattr__doc__,
10193"lgetxattr(path, attr) -> value\n\n\
10194Like getxattr but don't follow symlinks.");
10195
10196static PyObject *
10197posix_lgetxattr(PyObject *self, PyObject *args)
10198{
10199 PyObject *path, *res, *name;
10200
10201 if (!PyArg_ParseTuple(args, "O&O&:lgetxattr", PyUnicode_FSConverter, &path,
10202 PyUnicode_FSConverter, &name))
10203 return NULL;
10204 res = getxattr_common(PyBytes_AS_STRING(path), name, lgetxattr);
10205 Py_DECREF(path);
10206 Py_DECREF(name);
10207 return res;
10208}
10209
10210static ssize_t
10211wrap_fgetxattr(const char *path, const char *name, void *value, size_t size)
10212{
10213 /* Hack to share code. */
10214 return fgetxattr((int)(Py_uintptr_t)path, name, value, size);
10215}
10216
10217PyDoc_STRVAR(posix_fgetxattr__doc__,
10218"fgetxattr(fd, attr) -> value\n\n\
10219Like getxattr but operate on a fd instead of a path.");
10220
10221static PyObject *
10222posix_fgetxattr(PyObject *self, PyObject *args)
10223{
10224 PyObject *res, *name;
10225 int fd;
10226
10227 if (!PyArg_ParseTuple(args, "iO&:fgetxattr", &fd, PyUnicode_FSConverter, &name))
10228 return NULL;
10229 res = getxattr_common((const char *)(Py_uintptr_t)fd, name, wrap_fgetxattr);
10230 Py_DECREF(name);
10231 return res;
10232}
10233
10234PyDoc_STRVAR(posix_setxattr__doc__,
10235"setxattr(path, attr, value, flags=0)\n\n\
10236Set extended attribute *attr* on *path* to *value*.");
10237
10238static PyObject *
10239posix_setxattr(PyObject *self, PyObject *args)
10240{
10241 PyObject *path, *name;
10242 Py_buffer data;
10243 int flags = 0, err;
10244
10245 if (!PyArg_ParseTuple(args, "O&O&y*|i:setxattr", PyUnicode_FSConverter,
10246 &path, PyUnicode_FSConverter, &name, &data, &flags))
10247 return NULL;
10248 Py_BEGIN_ALLOW_THREADS;
10249 err = setxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10250 data.buf, data.len, flags);
10251 Py_END_ALLOW_THREADS;
10252 Py_DECREF(path);
10253 Py_DECREF(name);
10254 PyBuffer_Release(&data);
10255 if (err)
10256 return posix_error();
10257 Py_RETURN_NONE;
10258}
10259
10260PyDoc_STRVAR(posix_lsetxattr__doc__,
10261"lsetxattr(path, attr, value, flags=0)\n\n\
10262Like setxattr but don't follow symlinks.");
10263
10264static PyObject *
10265posix_lsetxattr(PyObject *self, PyObject *args)
10266{
10267 PyObject *path, *name;
10268 Py_buffer data;
10269 int flags = 0, err;
10270
10271 if (!PyArg_ParseTuple(args, "O&O&y*|i:lsetxattr", PyUnicode_FSConverter,
10272 &path, PyUnicode_FSConverter, &name, &data, &flags))
10273 return NULL;
10274 Py_BEGIN_ALLOW_THREADS;
10275 err = lsetxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10276 data.buf, data.len, flags);
10277 Py_END_ALLOW_THREADS;
10278 Py_DECREF(path);
10279 Py_DECREF(name);
10280 PyBuffer_Release(&data);
10281 if (err)
10282 return posix_error();
10283 Py_RETURN_NONE;
10284}
10285
10286PyDoc_STRVAR(posix_fsetxattr__doc__,
10287"fsetxattr(fd, attr, value, flags=0)\n\n\
10288Like setxattr but operates on *fd* instead of a path.");
10289
10290static PyObject *
10291posix_fsetxattr(PyObject *self, PyObject *args)
10292{
10293 Py_buffer data;
10294 const char *name;
10295 int fd, flags = 0, err;
10296
10297 if (!PyArg_ParseTuple(args, "iO&y*|i:fsetxattr", &fd, PyUnicode_FSConverter,
10298 &name, &data, &flags))
10299 return NULL;
10300 Py_BEGIN_ALLOW_THREADS;
10301 err = fsetxattr(fd, PyBytes_AS_STRING(name), data.buf, data.len, flags);
10302 Py_END_ALLOW_THREADS;
10303 Py_DECREF(name);
10304 PyBuffer_Release(&data);
10305 if (err)
10306 return posix_error();
10307 Py_RETURN_NONE;
10308}
10309
10310PyDoc_STRVAR(posix_removexattr__doc__,
10311"removexattr(path, attr)\n\n\
10312Remove extended attribute *attr* on *path*.");
10313
10314static PyObject *
10315posix_removexattr(PyObject *self, PyObject *args)
10316{
10317 PyObject *path, *name;
10318 int err;
10319
10320 if (!PyArg_ParseTuple(args, "O&O&:removexattr", PyUnicode_FSConverter, &path,
10321 PyUnicode_FSConverter, &name))
10322 return NULL;
10323 Py_BEGIN_ALLOW_THREADS;
10324 err = removexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10325 Py_END_ALLOW_THREADS;
10326 Py_DECREF(path);
10327 Py_DECREF(name);
10328 if (err)
10329 return posix_error();
10330 Py_RETURN_NONE;
10331}
10332
10333PyDoc_STRVAR(posix_lremovexattr__doc__,
10334"lremovexattr(path, attr)\n\n\
10335Like removexattr but don't follow symlinks.");
10336
10337static PyObject *
10338posix_lremovexattr(PyObject *self, PyObject *args)
10339{
10340 PyObject *path, *name;
10341 int err;
10342
10343 if (!PyArg_ParseTuple(args, "O&O&:lremovexattr", PyUnicode_FSConverter, &path,
10344 PyUnicode_FSConverter, &name))
10345 return NULL;
10346 Py_BEGIN_ALLOW_THREADS;
10347 err = lremovexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10348 Py_END_ALLOW_THREADS;
10349 Py_DECREF(path);
10350 Py_DECREF(name);
10351 if (err)
10352 return posix_error();
10353 Py_RETURN_NONE;
10354}
10355
10356PyDoc_STRVAR(posix_fremovexattr__doc__,
10357"fremovexattr(fd, attr)\n\n\
10358Like removexattr but operates on a file descriptor.");
10359
10360static PyObject *
10361posix_fremovexattr(PyObject *self, PyObject *args)
10362{
10363 PyObject *name;
10364 int fd, err;
10365
10366 if (!PyArg_ParseTuple(args, "iO&:fremovexattr", &fd,
10367 PyUnicode_FSConverter, &name))
10368 return NULL;
10369 Py_BEGIN_ALLOW_THREADS;
10370 err = fremovexattr(fd, PyBytes_AS_STRING(name));
10371 Py_END_ALLOW_THREADS;
10372 Py_DECREF(name);
10373 if (err)
10374 return posix_error();
10375 Py_RETURN_NONE;
10376}
10377
10378static Py_ssize_t
10379try_listxattr(const char *path, ssize_t (*list)(const char *, char *, size_t),
10380 Py_ssize_t buf_size, char **buf)
10381{
10382 Py_ssize_t len;
10383
10384 *buf = PyMem_MALLOC(buf_size);
10385 if (!*buf) {
10386 PyErr_NoMemory();
10387 return -1;
10388 }
10389 Py_BEGIN_ALLOW_THREADS;
10390 len = list(path, *buf, buf_size);
10391 Py_END_ALLOW_THREADS;
10392 if (len < 0) {
10393 PyMem_FREE(*buf);
10394 if (errno != ERANGE)
10395 posix_error();
10396 return -1;
10397 }
10398 return len;
10399}
10400
10401static PyObject *
10402listxattr_common(const char *path, ssize_t (*list)(const char *, char *, size_t))
10403{
10404 PyObject *res, *attr;
10405 Py_ssize_t len, err, start, i;
10406 char *buf;
10407
10408 len = try_listxattr(path, list, 256, &buf);
10409 if (len < 0) {
10410 if (PyErr_Occurred())
10411 return NULL;
10412 len = try_listxattr(path, list, XATTR_LIST_MAX, &buf);
10413 if (len < 0)
10414 return NULL;
10415 }
10416 res = PyList_New(0);
10417 if (!res) {
10418 PyMem_FREE(buf);
10419 return NULL;
10420 }
10421 for (start = i = 0; i < len; i++) {
10422 if (!buf[i]) {
10423 attr = PyUnicode_DecodeFSDefaultAndSize(&buf[start], i - start);
10424 if (!attr) {
10425 Py_DECREF(res);
10426 PyMem_FREE(buf);
10427 return NULL;
10428 }
10429 err = PyList_Append(res, attr);
10430 Py_DECREF(attr);
10431 if (err) {
10432 Py_DECREF(res);
10433 PyMem_FREE(buf);
10434 return NULL;
10435 }
10436 start = i + 1;
10437 }
10438 }
10439 PyMem_FREE(buf);
10440 return res;
10441}
10442
10443PyDoc_STRVAR(posix_listxattr__doc__,
10444"listxattr(path)\n\n\
10445Return a list of extended attributes on *path*.");
10446
10447static PyObject *
10448posix_listxattr(PyObject *self, PyObject *args)
10449{
10450 PyObject *path, *res;
10451
10452 if (!PyArg_ParseTuple(args, "O&:listxattr", PyUnicode_FSConverter, &path))
10453 return NULL;
10454 res = listxattr_common(PyBytes_AS_STRING(path), listxattr);
10455 Py_DECREF(path);
10456 return res;
10457}
10458
10459PyDoc_STRVAR(posix_llistxattr__doc__,
10460"llistxattr(path)\n\n\
10461Like listxattr but don't follow symlinks..");
10462
10463static PyObject *
10464posix_llistxattr(PyObject *self, PyObject *args)
10465{
10466 PyObject *path, *res;
10467
10468 if (!PyArg_ParseTuple(args, "O&:llistxattr", PyUnicode_FSConverter, &path))
10469 return NULL;
10470 res = listxattr_common(PyBytes_AS_STRING(path), llistxattr);
10471 Py_DECREF(path);
10472 return res;
10473}
10474
10475static ssize_t
10476wrap_flistxattr(const char *path, char *buf, size_t len)
10477{
10478 /* Hack to share code. */
10479 return flistxattr((int)(Py_uintptr_t)path, buf, len);
10480}
10481
10482PyDoc_STRVAR(posix_flistxattr__doc__,
10483"flistxattr(path)\n\n\
10484Like flistxattr but operates on a file descriptor.");
10485
10486static PyObject *
10487posix_flistxattr(PyObject *self, PyObject *args)
10488{
10489 long fd;
10490
10491 if (!PyArg_ParseTuple(args, "i:flistxattr", &fd))
10492 return NULL;
10493 return listxattr_common((const char *)(Py_uintptr_t)fd, wrap_flistxattr);
10494}
10495
Benjamin Peterson9428d532011-09-14 11:45:52 -040010496#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010497
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010498static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010500#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010501 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010502#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010504#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010506#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +000010507 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010508#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010510#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010511#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010513#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010514#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010515 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010516#endif /* HAVE_LCHMOD */
10517#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010518 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010519#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010520#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010521 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010522#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010523#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010525#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010526#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010527 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010528#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010529#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010530 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010531#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +000010532#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010533 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10534 METH_NOARGS, posix_getcwd__doc__},
10535 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10536 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +000010537#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010538#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010540#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010542#ifdef HAVE_FDOPENDIR
10543 {"fdlistdir", posix_fdlistdir, METH_VARARGS, posix_fdlistdir__doc__},
10544#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
10546 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010547#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010549#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010550#ifdef HAVE_GETPRIORITY
10551 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10552#endif /* HAVE_GETPRIORITY */
10553#ifdef HAVE_SETPRIORITY
10554 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10555#endif /* HAVE_SETPRIORITY */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010556#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010558#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010559#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010560 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010561#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010562 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
10563 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
10564 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Brian Curtin52173d42010-12-02 18:29:18 +000010566#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +000010567 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010568#endif /* HAVE_SYMLINK */
Brian Curtin52173d42010-12-02 18:29:18 +000010569#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010570 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
Brian Curtin52173d42010-12-02 18:29:18 +000010571 win_symlink__doc__},
10572#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010573#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010574 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010575#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010576 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010577#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010579#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +000010580 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
10581 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
10582 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010583#ifdef HAVE_FUTIMES
10584 {"futimes", posix_futimes, METH_VARARGS, posix_futimes__doc__},
10585#endif
10586#ifdef HAVE_LUTIMES
10587 {"lutimes", posix_lutimes, METH_VARARGS, posix_lutimes__doc__},
10588#endif
10589#ifdef HAVE_FUTIMENS
10590 {"futimens", posix_futimens, METH_VARARGS, posix_futimens__doc__},
10591#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010592#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010593 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010594#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010596#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010597 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
10598 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010599#endif /* HAVE_EXECV */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010600#ifdef HAVE_FEXECVE
10601 {"fexecve", posix_fexecve, METH_VARARGS, posix_fexecve__doc__},
10602#endif
Guido van Rossuma1065681999-01-25 23:20:23 +000010603#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10605 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010606#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10608 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010609#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010610#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010611#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010612 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010613#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010614#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010615 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010616#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010617#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010618#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010619 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10620 {"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 +020010621#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010622#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010623 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010624#endif
10625#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010626 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010627#endif
10628#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010629 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010630#endif
10631#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010632 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010633#endif
10634#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010635 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010636#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010637 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010638#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010639 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10640 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10641#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010642#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010643#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010644 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010645#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010646#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010647 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010648#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010649#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010650 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010651#endif /* HAVE_GETEGID */
10652#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010653 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010654#endif /* HAVE_GETEUID */
10655#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010657#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010658#ifdef HAVE_GETGROUPLIST
10659 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10660#endif
Fred Drakec9680921999-12-13 16:37:25 +000010661#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010662 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010663#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010664 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010665#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010667#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010668#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010670#endif /* HAVE_GETPPID */
10671#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010673#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010674#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010676#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010677#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010679#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010680#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010682#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010683#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010685#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010686#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10688 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +000010689 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010690#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010691#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010692 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010693#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010694#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010695 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010696#endif /* HAVE_SETEUID */
10697#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010698 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010699#endif /* HAVE_SETEGID */
10700#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010701 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010702#endif /* HAVE_SETREUID */
10703#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010704 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010705#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010706#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010707 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010708#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010709#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010710 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010711#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010712#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010713 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010714#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010715#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010716 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010717#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010718#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010719 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010720#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010721#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010722 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010723#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010724#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +000010725 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010726#endif /* HAVE_WAIT3 */
10727#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +000010728 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010729#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010730#if defined(HAVE_WAITID) && !defined(__APPLE__)
10731 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10732#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010733#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010734 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010735#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010736#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010737 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010738#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010739#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010740 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010741#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010742#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010743 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010744#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010745#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010746 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010747#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010748#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010749 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010750#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +000010751 {"open", posix_open, METH_VARARGS, posix_open__doc__},
10752 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10753 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10754 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10755 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10756 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010757#ifdef HAVE_LOCKF
10758 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10759#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010760 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10761 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010762#ifdef HAVE_READV
10763 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10764#endif
10765#ifdef HAVE_PREAD
10766 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10767#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010768 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010769#ifdef HAVE_WRITEV
10770 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10771#endif
10772#ifdef HAVE_PWRITE
10773 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10774#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010775#ifdef HAVE_SENDFILE
10776 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10777 posix_sendfile__doc__},
10778#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010779 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
10780 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010781#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010782 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010783#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010784#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010785 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010786#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010787#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +000010788 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010789#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010790#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +000010791 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010792#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010793#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010794 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10795 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10796 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010797#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010798#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010800#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010801#ifdef HAVE_TRUNCATE
10802 {"truncate", posix_truncate, METH_VARARGS, posix_truncate__doc__},
10803#endif
10804#ifdef HAVE_POSIX_FALLOCATE
10805 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10806#endif
10807#ifdef HAVE_POSIX_FADVISE
10808 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10809#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010810#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010812#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010813#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010815#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010817#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010818 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010819#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010820#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010821 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010822#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010823#ifdef HAVE_SYNC
10824 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10825#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010826#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010827 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010828#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010829#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010830#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010831 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010832#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010833#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010834 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010835#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010836#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010837 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010838#endif /* WIFSTOPPED */
10839#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010840 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010841#endif /* WIFSIGNALED */
10842#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010843 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010844#endif /* WIFEXITED */
10845#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010846 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010847#endif /* WEXITSTATUS */
10848#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010849 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010850#endif /* WTERMSIG */
10851#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010853#endif /* WSTOPSIG */
10854#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010855#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010856 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010857#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010858#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010859 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010860#endif
Fred Drakec9680921999-12-13 16:37:25 +000010861#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010862 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010863#endif
10864#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010865 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010866#endif
10867#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010868 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010869#endif
10870#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010871 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010872#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010874#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010875 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010876 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000010877 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010878 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010879 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010880#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010881#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010883#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +000010884 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +000010886 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010887 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010889 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010890#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010892#endif
10893#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010895#endif
10896#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010898#endif
10899#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010901#endif
10902
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010903/* posix *at family of functions */
10904#ifdef HAVE_FACCESSAT
10905 {"faccessat", posix_faccessat, METH_VARARGS, posix_faccessat__doc__},
10906#endif
10907#ifdef HAVE_FCHMODAT
10908 {"fchmodat", posix_fchmodat, METH_VARARGS, posix_fchmodat__doc__},
10909#endif /* HAVE_FCHMODAT */
10910#ifdef HAVE_FCHOWNAT
10911 {"fchownat", posix_fchownat, METH_VARARGS, posix_fchownat__doc__},
10912#endif /* HAVE_FCHOWNAT */
10913#ifdef HAVE_FSTATAT
10914 {"fstatat", posix_fstatat, METH_VARARGS, posix_fstatat__doc__},
10915#endif
10916#ifdef HAVE_FUTIMESAT
10917 {"futimesat", posix_futimesat, METH_VARARGS, posix_futimesat__doc__},
10918#endif
10919#ifdef HAVE_LINKAT
10920 {"linkat", posix_linkat, METH_VARARGS, posix_linkat__doc__},
10921#endif /* HAVE_LINKAT */
10922#ifdef HAVE_MKDIRAT
10923 {"mkdirat", posix_mkdirat, METH_VARARGS, posix_mkdirat__doc__},
10924#endif
10925#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
10926 {"mknodat", posix_mknodat, METH_VARARGS, posix_mknodat__doc__},
10927#endif
10928#ifdef HAVE_OPENAT
10929 {"openat", posix_openat, METH_VARARGS, posix_openat__doc__},
10930#endif
10931#ifdef HAVE_READLINKAT
10932 {"readlinkat", posix_readlinkat, METH_VARARGS, posix_readlinkat__doc__},
10933#endif /* HAVE_READLINKAT */
10934#ifdef HAVE_RENAMEAT
10935 {"renameat", posix_renameat, METH_VARARGS, posix_renameat__doc__},
10936#endif
10937#if HAVE_SYMLINKAT
10938 {"symlinkat", posix_symlinkat, METH_VARARGS, posix_symlinkat__doc__},
10939#endif /* HAVE_SYMLINKAT */
10940#ifdef HAVE_UNLINKAT
10941 {"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__},
10942#endif
10943#ifdef HAVE_UTIMENSAT
10944 {"utimensat", posix_utimensat, METH_VARARGS, posix_utimensat__doc__},
10945#endif
10946#ifdef HAVE_MKFIFOAT
10947 {"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__},
10948#endif
Benjamin Peterson9428d532011-09-14 11:45:52 -040010949#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010950 {"setxattr", posix_setxattr, METH_VARARGS, posix_setxattr__doc__},
10951 {"lsetxattr", posix_lsetxattr, METH_VARARGS, posix_lsetxattr__doc__},
10952 {"fsetxattr", posix_fsetxattr, METH_VARARGS, posix_fsetxattr__doc__},
10953 {"getxattr", posix_getxattr, METH_VARARGS, posix_getxattr__doc__},
10954 {"lgetxattr", posix_lgetxattr, METH_VARARGS, posix_lgetxattr__doc__},
10955 {"fgetxattr", posix_fgetxattr, METH_VARARGS, posix_fgetxattr__doc__},
10956 {"removexattr", posix_removexattr, METH_VARARGS, posix_removexattr__doc__},
10957 {"lremovexattr", posix_lremovexattr, METH_VARARGS, posix_lremovexattr__doc__},
10958 {"fremovexattr", posix_fremovexattr, METH_VARARGS, posix_fremovexattr__doc__},
10959 {"listxattr", posix_listxattr, METH_VARARGS, posix_listxattr__doc__},
10960 {"llistxattr", posix_llistxattr, METH_VARARGS, posix_llistxattr__doc__},
10961 {"flistxattr", posix_flistxattr, METH_VARARGS, posix_flistxattr__doc__},
10962#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010963 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010964};
10965
10966
Barry Warsaw4a342091996-12-19 23:50:02 +000010967static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010968ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000010969{
Victor Stinner8c62be82010-05-06 00:08:46 +000010970 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000010971}
10972
Guido van Rossumd48f2521997-12-05 22:19:34 +000010973#if defined(PYOS_OS2)
10974/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000010975static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000010976{
10977 APIRET rc;
10978 ULONG values[QSV_MAX+1];
10979 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000010980 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000010981
10982 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000010983 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000010984 Py_END_ALLOW_THREADS
10985
10986 if (rc != NO_ERROR) {
10987 os2_error(rc);
10988 return -1;
10989 }
10990
Fred Drake4d1e64b2002-04-15 19:40:07 +000010991 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
10992 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
10993 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
10994 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
10995 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
10996 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
10997 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000010998
10999 switch (values[QSV_VERSION_MINOR]) {
11000 case 0: ver = "2.00"; break;
11001 case 10: ver = "2.10"; break;
11002 case 11: ver = "2.11"; break;
11003 case 30: ver = "3.00"; break;
11004 case 40: ver = "4.00"; break;
11005 case 50: ver = "5.00"; break;
11006 default:
Tim Peters885d4572001-11-28 20:27:42 +000011007 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011008 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011009 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011010 ver = &tmp[0];
11011 }
11012
11013 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011014 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011015 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011016
11017 /* Add Indicator of Which Drive was Used to Boot the System */
11018 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11019 tmp[1] = ':';
11020 tmp[2] = '\0';
11021
Fred Drake4d1e64b2002-04-15 19:40:07 +000011022 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011023}
11024#endif
11025
Brian Curtin52173d42010-12-02 18:29:18 +000011026#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011027static int
Brian Curtin52173d42010-12-02 18:29:18 +000011028enable_symlink()
11029{
11030 HANDLE tok;
11031 TOKEN_PRIVILEGES tok_priv;
11032 LUID luid;
11033 int meth_idx = 0;
11034
11035 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011036 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011037
11038 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011039 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011040
11041 tok_priv.PrivilegeCount = 1;
11042 tok_priv.Privileges[0].Luid = luid;
11043 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11044
11045 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11046 sizeof(TOKEN_PRIVILEGES),
11047 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011048 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011049
Brian Curtin3b4499c2010-12-28 14:31:47 +000011050 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11051 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011052}
11053#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11054
Barry Warsaw4a342091996-12-19 23:50:02 +000011055static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011056all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011057{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011058#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011059 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011060#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011061#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011062 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011063#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011064#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011066#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011067#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011068 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011069#endif
Fred Drakec9680921999-12-13 16:37:25 +000011070#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011072#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011073#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011075#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011076#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011078#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011079#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011081#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011082#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011084#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011085#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011087#endif
11088#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011090#endif
11091#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011092 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011093#endif
11094#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011096#endif
11097#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011098 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011099#endif
11100#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011102#endif
11103#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011105#endif
11106#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011108#endif
11109#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011111#endif
11112#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011114#endif
11115#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011117#endif
11118#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011120#endif
11121#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011123#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011124#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011126#endif
11127#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011129#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011130#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011132#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011133#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011134 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011135#endif
11136#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011137 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011138#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011139#ifdef PRIO_PROCESS
11140 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11141#endif
11142#ifdef PRIO_PGRP
11143 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11144#endif
11145#ifdef PRIO_USER
11146 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11147#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011148#ifdef O_CLOEXEC
11149 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11150#endif
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011151/* posix - constants for *at functions */
11152#ifdef AT_SYMLINK_NOFOLLOW
11153 if (ins(d, "AT_SYMLINK_NOFOLLOW", (long)AT_SYMLINK_NOFOLLOW)) return -1;
11154#endif
11155#ifdef AT_EACCESS
11156 if (ins(d, "AT_EACCESS", (long)AT_EACCESS)) return -1;
11157#endif
11158#ifdef AT_FDCWD
11159 if (ins(d, "AT_FDCWD", (long)AT_FDCWD)) return -1;
11160#endif
11161#ifdef AT_REMOVEDIR
11162 if (ins(d, "AT_REMOVEDIR", (long)AT_REMOVEDIR)) return -1;
11163#endif
11164#ifdef AT_SYMLINK_FOLLOW
11165 if (ins(d, "AT_SYMLINK_FOLLOW", (long)AT_SYMLINK_FOLLOW)) return -1;
11166#endif
11167#ifdef UTIME_NOW
11168 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11169#endif
11170#ifdef UTIME_OMIT
11171 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11172#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011173
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011174
Tim Peters5aa91602002-01-30 05:46:57 +000011175/* MS Windows */
11176#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011177 /* Don't inherit in child processes. */
11178 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011179#endif
11180#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011181 /* Optimize for short life (keep in memory). */
11182 /* MS forgot to define this one with a non-underscore form too. */
11183 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011184#endif
11185#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011186 /* Automatically delete when last handle is closed. */
11187 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011188#endif
11189#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011190 /* Optimize for random access. */
11191 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011192#endif
11193#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011194 /* Optimize for sequential access. */
11195 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011196#endif
11197
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011198/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011199#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011200 /* Send a SIGIO signal whenever input or output
11201 becomes available on file descriptor */
11202 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011203#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011204#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011205 /* Direct disk access. */
11206 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011207#endif
11208#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011209 /* Must be a directory. */
11210 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011211#endif
11212#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011213 /* Do not follow links. */
11214 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011215#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011216#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 /* Do not update the access time. */
11218 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011219#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011220
Victor Stinner8c62be82010-05-06 00:08:46 +000011221 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011222#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011223 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011224#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011225#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011227#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011228#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011230#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011231#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011233#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011234#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011235 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011236#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011237#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011239#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011240#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011242#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011243#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011245#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011246#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011248#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011249#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011250 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011251#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011252#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011254#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011255#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011257#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011258#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011260#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011261#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011263#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011264#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011266#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011267#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011268 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011269#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011270#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011271 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011272#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011273
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011274 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011275#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011276 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011277#endif /* ST_RDONLY */
11278#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011279 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011280#endif /* ST_NOSUID */
11281
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011282 /* FreeBSD sendfile() constants */
11283#ifdef SF_NODISKIO
11284 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11285#endif
11286#ifdef SF_MNOWAIT
11287 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11288#endif
11289#ifdef SF_SYNC
11290 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11291#endif
11292
Ross Lagerwall7807c352011-03-17 20:20:30 +020011293 /* constants for posix_fadvise */
11294#ifdef POSIX_FADV_NORMAL
11295 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11296#endif
11297#ifdef POSIX_FADV_SEQUENTIAL
11298 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11299#endif
11300#ifdef POSIX_FADV_RANDOM
11301 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11302#endif
11303#ifdef POSIX_FADV_NOREUSE
11304 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11305#endif
11306#ifdef POSIX_FADV_WILLNEED
11307 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11308#endif
11309#ifdef POSIX_FADV_DONTNEED
11310 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11311#endif
11312
11313 /* constants for waitid */
11314#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11315 if (ins(d, "P_PID", (long)P_PID)) return -1;
11316 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11317 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11318#endif
11319#ifdef WEXITED
11320 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11321#endif
11322#ifdef WNOWAIT
11323 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11324#endif
11325#ifdef WSTOPPED
11326 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11327#endif
11328#ifdef CLD_EXITED
11329 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11330#endif
11331#ifdef CLD_DUMPED
11332 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11333#endif
11334#ifdef CLD_TRAPPED
11335 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11336#endif
11337#ifdef CLD_CONTINUED
11338 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11339#endif
11340
11341 /* constants for lockf */
11342#ifdef F_LOCK
11343 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11344#endif
11345#ifdef F_TLOCK
11346 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11347#endif
11348#ifdef F_ULOCK
11349 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11350#endif
11351#ifdef F_TEST
11352 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11353#endif
11354
11355 /* constants for futimens */
11356#ifdef UTIME_NOW
11357 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11358#endif
11359#ifdef UTIME_OMIT
11360 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11361#endif
11362
Guido van Rossum246bc171999-02-01 23:54:31 +000011363#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011364#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011365 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11366 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11367 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11368 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11369 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11370 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11371 if (ins(d, "P_PM", (long)P_PM)) return -1;
11372 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11373 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11374 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11375 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11376 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11377 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11378 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11379 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11380 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11381 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11382 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11383 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11384 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011385#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011386 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11387 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11388 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11389 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11390 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011391#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011392#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011393
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011394#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011395 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011396 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11397 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11398#ifdef SCHED_SPORADIC
11399 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11400#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011401#ifdef SCHED_BATCH
11402 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11403#endif
11404#ifdef SCHED_IDLE
11405 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11406#endif
11407#ifdef SCHED_RESET_ON_FORK
11408 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11409#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011410#ifdef SCHED_SYS
11411 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11412#endif
11413#ifdef SCHED_IA
11414 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11415#endif
11416#ifdef SCHED_FSS
11417 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11418#endif
11419#ifdef SCHED_FX
11420 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11421#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011422#endif
11423
Benjamin Peterson9428d532011-09-14 11:45:52 -040011424#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011425 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11426 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11427 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11428#endif
11429
Victor Stinner8b905bd2011-10-25 13:34:04 +020011430#ifdef RTLD_LAZY
11431 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11432#endif
11433#ifdef RTLD_NOW
11434 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11435#endif
11436#ifdef RTLD_GLOBAL
11437 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11438#endif
11439#ifdef RTLD_LOCAL
11440 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11441#endif
11442#ifdef RTLD_NODELETE
11443 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11444#endif
11445#ifdef RTLD_NOLOAD
11446 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11447#endif
11448#ifdef RTLD_DEEPBIND
11449 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11450#endif
11451
Guido van Rossumd48f2521997-12-05 22:19:34 +000011452#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011453 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011454#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011455 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011456}
11457
11458
Tim Peters5aa91602002-01-30 05:46:57 +000011459#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011460#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011461#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011462
11463#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011464#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011465#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011466
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011467#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011468#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011469#define MODNAME "posix"
11470#endif
11471
Martin v. Löwis1a214512008-06-11 05:26:20 +000011472static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011473 PyModuleDef_HEAD_INIT,
11474 MODNAME,
11475 posix__doc__,
11476 -1,
11477 posix_methods,
11478 NULL,
11479 NULL,
11480 NULL,
11481 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011482};
11483
11484
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011485PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011486INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011487{
Victor Stinner8c62be82010-05-06 00:08:46 +000011488 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +000011489
Brian Curtin52173d42010-12-02 18:29:18 +000011490#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011491 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011492#endif
11493
Victor Stinner8c62be82010-05-06 00:08:46 +000011494 m = PyModule_Create(&posixmodule);
11495 if (m == NULL)
11496 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011497
Victor Stinner8c62be82010-05-06 00:08:46 +000011498 /* Initialize environ dictionary */
11499 v = convertenviron();
11500 Py_XINCREF(v);
11501 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11502 return NULL;
11503 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011504
Victor Stinner8c62be82010-05-06 00:08:46 +000011505 if (all_ins(m))
11506 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011507
Victor Stinner8c62be82010-05-06 00:08:46 +000011508 if (setup_confname_tables(m))
11509 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011510
Victor Stinner8c62be82010-05-06 00:08:46 +000011511 Py_INCREF(PyExc_OSError);
11512 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011513
Benjamin Peterson2740af82011-08-02 17:41:34 -050011514#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011515 if (PyType_Ready(&cpu_set_type) < 0)
11516 return NULL;
11517 Py_INCREF(&cpu_set_type);
11518 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011519#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011520
Guido van Rossumb3d39562000-01-31 18:41:26 +000011521#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011522 if (posix_putenv_garbage == NULL)
11523 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011524#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011525
Victor Stinner8c62be82010-05-06 00:08:46 +000011526 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011527#if defined(HAVE_WAITID) && !defined(__APPLE__)
11528 waitid_result_desc.name = MODNAME ".waitid_result";
11529 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11530#endif
11531
Victor Stinner8c62be82010-05-06 00:08:46 +000011532 stat_result_desc.name = MODNAME ".stat_result";
11533 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11534 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11535 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11536 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11537 structseq_new = StatResultType.tp_new;
11538 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011539
Victor Stinner8c62be82010-05-06 00:08:46 +000011540 statvfs_result_desc.name = MODNAME ".statvfs_result";
11541 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011542#ifdef NEED_TICKS_PER_SECOND
11543# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011544 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011545# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011547# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011549# endif
11550#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011551
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011552#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011553 sched_param_desc.name = MODNAME ".sched_param";
11554 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11555 SchedParamType.tp_new = sched_param_new;
11556#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011557 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011558#if defined(HAVE_WAITID) && !defined(__APPLE__)
11559 Py_INCREF((PyObject*) &WaitidResultType);
11560 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11561#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011562 Py_INCREF((PyObject*) &StatResultType);
11563 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11564 Py_INCREF((PyObject*) &StatVFSResultType);
11565 PyModule_AddObject(m, "statvfs_result",
11566 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011567
11568#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011569 Py_INCREF(&SchedParamType);
11570 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011571#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011572 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011573
11574#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011575 /*
11576 * Step 2 of weak-linking support on Mac OS X.
11577 *
11578 * The code below removes functions that are not available on the
11579 * currently active platform.
11580 *
11581 * This block allow one to use a python binary that was build on
11582 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
11583 * OSX 10.4.
11584 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011585#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011586 if (fstatvfs == NULL) {
11587 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11588 return NULL;
11589 }
11590 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011591#endif /* HAVE_FSTATVFS */
11592
11593#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011594 if (statvfs == NULL) {
11595 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11596 return NULL;
11597 }
11598 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011599#endif /* HAVE_STATVFS */
11600
11601# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011602 if (lchown == NULL) {
11603 if (PyObject_DelAttrString(m, "lchown") == -1) {
11604 return NULL;
11605 }
11606 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011607#endif /* HAVE_LCHOWN */
11608
11609
11610#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +000011611 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011612
Guido van Rossumb6775db1994-08-01 11:34:53 +000011613}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011614
11615#ifdef __cplusplus
11616}
11617#endif