blob: bd94ffb5fe5d2c44452513972773380ec9efa50d [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 Peterson2dbda072012-03-16 10:12:55 -0500110#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500111#undef HAVE_SCHED_SETAFFINITY
112#endif
113
Benjamin Peterson9428d532011-09-14 11:45:52 -0400114#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
115#define USE_XATTRS
116#endif
117
118#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400119#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400120#endif
121
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000122#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
123#ifdef HAVE_SYS_SOCKET_H
124#include <sys/socket.h>
125#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000126#endif
127
Victor Stinner8b905bd2011-10-25 13:34:04 +0200128#ifdef HAVE_DLFCN_H
129#include <dlfcn.h>
130#endif
131
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100132#if defined(MS_WINDOWS)
133# define TERMSIZE_USE_CONIO
134#elif defined(HAVE_SYS_IOCTL_H)
135# include <sys/ioctl.h>
136# if defined(HAVE_TERMIOS_H)
137# include <termios.h>
138# endif
139# if defined(TIOCGWINSZ)
140# define TERMSIZE_USE_IOCTL
141# endif
142#endif /* MS_WINDOWS */
143
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000145/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000146#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#include <process.h>
148#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_GETCWD 1
151#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#if defined(__OS2__)
154#define HAVE_EXECV 1
155#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000156#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#include <process.h>
158#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#define HAVE_EXECV 1
161#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#define HAVE_OPENDIR 1
163#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000164#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_WAIT 1
166#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000168#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000169#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000170#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000171#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_EXECV 1
173#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_SYSTEM 1
175#define HAVE_CWAIT 1
176#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000177#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000178#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000179#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
180/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000181#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182/* Unix functions that the configure script doesn't check for */
183#define HAVE_EXECV 1
184#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000185#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000186#define HAVE_FORK1 1
187#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#define HAVE_GETCWD 1
189#define HAVE_GETEGID 1
190#define HAVE_GETEUID 1
191#define HAVE_GETGID 1
192#define HAVE_GETPPID 1
193#define HAVE_GETUID 1
194#define HAVE_KILL 1
195#define HAVE_OPENDIR 1
196#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000197#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000199#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000200#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#endif /* _MSC_VER */
202#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000205
Victor Stinnera2f7c002012-02-08 03:36:25 +0100206
207
208
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000210
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000211#if defined(__sgi)&&_COMPILER_VERSION>=700
212/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
213 (default) */
214extern char *ctermid_r(char *);
215#endif
216
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000217#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000218#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000220#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000221#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000226#endif
227#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000228extern int chdir(char *);
229extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000230#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000231extern int chdir(const char *);
232extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000233#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000234#ifdef __BORLANDC__
235extern int chmod(const char *, int);
236#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000237extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000238#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000239/*#ifdef HAVE_FCHMOD
240extern int fchmod(int, mode_t);
241#endif*/
242/*#ifdef HAVE_LCHMOD
243extern int lchmod(const char *, mode_t);
244#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000245extern int chown(const char *, uid_t, gid_t);
246extern char *getcwd(char *, int);
247extern char *strerror(int);
248extern int link(const char *, const char *);
249extern int rename(const char *, const char *);
250extern int stat(const char *, struct stat *);
251extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000253extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000254#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000256extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000259
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000260#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000261
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#ifdef HAVE_UTIME_H
263#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000264#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000266#ifdef HAVE_SYS_UTIME_H
267#include <sys/utime.h>
268#define HAVE_UTIME_H /* pretend we do for the rest of this file */
269#endif /* HAVE_SYS_UTIME_H */
270
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#ifdef HAVE_SYS_TIMES_H
272#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274
275#ifdef HAVE_SYS_PARAM_H
276#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000277#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278
279#ifdef HAVE_SYS_UTSNAME_H
280#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000281#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#define NAMLEN(dirent) strlen((dirent)->d_name)
286#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000287#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#include <direct.h>
289#define NAMLEN(dirent) strlen((dirent)->d_name)
290#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000292#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000293#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000294#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000295#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000296#endif
297#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000298#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000299#endif
300#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000302#endif
303#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000304
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000305#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000306#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000307#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000308#endif
309#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000311#endif
312#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000313#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000314#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000315#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000316#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000317#endif
318#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000319#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000320#endif
321#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000322#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000323#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000325#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000326#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000327#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000328#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000329#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
330#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000331static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000332#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000333#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000334
Guido van Rossumd48f2521997-12-05 22:19:34 +0000335#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000336#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000337#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338
Tim Petersbc2e10e2002-03-03 23:17:02 +0000339#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000340#if defined(PATH_MAX) && PATH_MAX > 1024
341#define MAXPATHLEN PATH_MAX
342#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000343#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000344#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000345#endif /* MAXPATHLEN */
346
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000347#ifdef UNION_WAIT
348/* Emulate some macros on systems that have a union instead of macros */
349
350#ifndef WIFEXITED
351#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
352#endif
353
354#ifndef WEXITSTATUS
355#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
356#endif
357
358#ifndef WTERMSIG
359#define WTERMSIG(u_wait) ((u_wait).w_termsig)
360#endif
361
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000362#define WAIT_TYPE union wait
363#define WAIT_STATUS_INT(s) (s.w_status)
364
365#else /* !UNION_WAIT */
366#define WAIT_TYPE int
367#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000368#endif /* UNION_WAIT */
369
Greg Wardb48bc172000-03-01 21:51:56 +0000370/* Don't use the "_r" form if we don't need it (also, won't have a
371 prototype for it, at least on Solaris -- maybe others as well?). */
372#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
373#define USE_CTERMID_R
374#endif
375
Fred Drake699f3522000-06-29 21:12:41 +0000376/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000377#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000378#undef FSTAT
379#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000380#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000381# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700382# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000383# define FSTAT win32_fstat
384# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000385#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000386# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700387# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000388# define FSTAT fstat
389# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000390#endif
391
Tim Peters11b23062003-04-23 02:39:17 +0000392#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000393#include <sys/mkdev.h>
394#else
395#if defined(MAJOR_IN_SYSMACROS)
396#include <sys/sysmacros.h>
397#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000398#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
399#include <sys/mkdev.h>
400#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000401#endif
Fred Drake699f3522000-06-29 21:12:41 +0000402
Larry Hastings9cf065c2012-06-22 16:30:09 -0700403
404#ifdef MS_WINDOWS
405static int
406win32_warn_bytes_api()
407{
408 return PyErr_WarnEx(PyExc_DeprecationWarning,
409 "The Windows bytes API has been deprecated, "
410 "use Unicode filenames instead",
411 1);
412}
413#endif
414
415
416#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400417/*
418 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
419 * without the int cast, the value gets interpreted as uint (4291925331),
420 * which doesn't play nicely with all the initializer lines in this file that
421 * look like this:
422 * int dir_fd = DEFAULT_DIR_FD;
423 */
424#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700425#else
426#define DEFAULT_DIR_FD (-100)
427#endif
428
429static int
430_fd_converter(PyObject *o, int *p, int default_value) {
431 long long_value;
432 if (o == Py_None) {
433 *p = default_value;
434 return 1;
435 }
436 if (PyFloat_Check(o)) {
437 PyErr_SetString(PyExc_TypeError,
438 "integer argument expected, got float" );
439 return 0;
440 }
441 long_value = PyLong_AsLong(o);
442 if (long_value == -1 && PyErr_Occurred())
443 return 0;
444 if (long_value > INT_MAX) {
445 PyErr_SetString(PyExc_OverflowError,
446 "signed integer is greater than maximum");
447 return 0;
448 }
449 if (long_value < INT_MIN) {
450 PyErr_SetString(PyExc_OverflowError,
451 "signed integer is less than minimum");
452 return 0;
453 }
454 *p = (int)long_value;
455 return 1;
456}
457
458static int
459dir_fd_converter(PyObject *o, void *p) {
460 return _fd_converter(o, (int *)p, DEFAULT_DIR_FD);
461}
462
463
464
465/*
466 * A PyArg_ParseTuple "converter" function
467 * that handles filesystem paths in the manner
468 * preferred by the os module.
469 *
470 * path_converter accepts (Unicode) strings and their
471 * subclasses, and bytes and their subclasses. What
472 * it does with the argument depends on the platform:
473 *
474 * * On Windows, if we get a (Unicode) string we
475 * extract the wchar_t * and return it; if we get
476 * bytes we extract the char * and return that.
477 *
478 * * On all other platforms, strings are encoded
479 * to bytes using PyUnicode_FSConverter, then we
480 * extract the char * from the bytes object and
481 * return that.
482 *
483 * path_converter also optionally accepts signed
484 * integers (representing open file descriptors) instead
485 * of path strings.
486 *
487 * Input fields:
488 * path.nullable
489 * If nonzero, the path is permitted to be None.
490 * path.allow_fd
491 * If nonzero, the path is permitted to be a file handle
492 * (a signed int) instead of a string.
493 * path.function_name
494 * If non-NULL, path_converter will use that as the name
495 * of the function in error messages.
496 * (If path.argument_name is NULL it omits the function name.)
497 * path.argument_name
498 * If non-NULL, path_converter will use that as the name
499 * of the parameter in error messages.
500 * (If path.argument_name is NULL it uses "path".)
501 *
502 * Output fields:
503 * path.wide
504 * Points to the path if it was expressed as Unicode
505 * and was not encoded. (Only used on Windows.)
506 * path.narrow
507 * Points to the path if it was expressed as bytes,
508 * or it was Unicode and was encoded to bytes.
509 * path.fd
510 * Contains a file descriptor if path.accept_fd was true
511 * and the caller provided a signed integer instead of any
512 * sort of string.
513 *
514 * WARNING: if your "path" parameter is optional, and is
515 * unspecified, path_converter will never get called.
516 * So if you set allow_fd, you *MUST* initialize path.fd = -1
517 * yourself!
518 * path.length
519 * The length of the path in characters, if specified as
520 * a string.
521 * path.object
522 * The original object passed in.
523 * path.cleanup
524 * For internal use only. May point to a temporary object.
525 * (Pay no attention to the man behind the curtain.)
526 *
527 * At most one of path.wide or path.narrow will be non-NULL.
528 * If path was None and path.nullable was set,
529 * or if path was an integer and path.allow_fd was set,
530 * both path.wide and path.narrow will be NULL
531 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200532 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700533 * path_converter takes care to not write to the path_t
534 * unless it's successful. However it must reset the
535 * "cleanup" field each time it's called.
536 *
537 * Use as follows:
538 * path_t path;
539 * memset(&path, 0, sizeof(path));
540 * PyArg_ParseTuple(args, "O&", path_converter, &path);
541 * // ... use values from path ...
542 * path_cleanup(&path);
543 *
544 * (Note that if PyArg_Parse fails you don't need to call
545 * path_cleanup(). However it is safe to do so.)
546 */
547typedef struct {
548 char *function_name;
549 char *argument_name;
550 int nullable;
551 int allow_fd;
552 wchar_t *wide;
553 char *narrow;
554 int fd;
555 Py_ssize_t length;
556 PyObject *object;
557 PyObject *cleanup;
558} path_t;
559
560static void
561path_cleanup(path_t *path) {
562 if (path->cleanup) {
563 Py_DECREF(path->cleanup);
564 path->cleanup = NULL;
565 }
566}
567
568static int
569path_converter(PyObject *o, void *p) {
570 path_t *path = (path_t *)p;
571 PyObject *unicode, *bytes;
572 Py_ssize_t length;
573 char *narrow;
574
575#define FORMAT_EXCEPTION(exc, fmt) \
576 PyErr_Format(exc, "%s%s" fmt, \
577 path->function_name ? path->function_name : "", \
578 path->function_name ? ": " : "", \
579 path->argument_name ? path->argument_name : "path")
580
581 /* Py_CLEANUP_SUPPORTED support */
582 if (o == NULL) {
583 path_cleanup(path);
584 return 1;
585 }
586
587 /* ensure it's always safe to call path_cleanup() */
588 path->cleanup = NULL;
589
590 if (o == Py_None) {
591 if (!path->nullable) {
592 FORMAT_EXCEPTION(PyExc_TypeError,
593 "can't specify None for %s argument");
594 return 0;
595 }
596 path->wide = NULL;
597 path->narrow = NULL;
598 path->length = 0;
599 path->object = o;
600 path->fd = -1;
601 return 1;
602 }
603
604 unicode = PyUnicode_FromObject(o);
605 if (unicode) {
606#ifdef MS_WINDOWS
607 wchar_t *wide;
608 length = PyUnicode_GET_SIZE(unicode);
609 if (length > 32767) {
610 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
611 Py_DECREF(unicode);
612 return 0;
613 }
614
615 wide = PyUnicode_AsUnicode(unicode);
616 if (!wide) {
617 Py_DECREF(unicode);
618 return 0;
619 }
620
621 path->wide = wide;
622 path->narrow = NULL;
623 path->length = length;
624 path->object = o;
625 path->fd = -1;
626 path->cleanup = unicode;
627 return Py_CLEANUP_SUPPORTED;
628#else
629 int converted = PyUnicode_FSConverter(unicode, &bytes);
630 Py_DECREF(unicode);
631 if (!converted)
632 bytes = NULL;
633#endif
634 }
635 else {
636 PyErr_Clear();
637 bytes = PyBytes_FromObject(o);
638 if (!bytes) {
639 PyErr_Clear();
640 if (path->allow_fd) {
641 int fd;
642 /*
643 * note: _fd_converter always permits None.
644 * but we've already done our None check.
645 * so o cannot be None at this point.
646 */
647 int result = _fd_converter(o, &fd, -1);
648 if (result) {
649 path->wide = NULL;
650 path->narrow = NULL;
651 path->length = 0;
652 path->object = o;
653 path->fd = fd;
654 return result;
655 }
656 }
657 }
658 }
659
660 if (!bytes) {
661 if (!PyErr_Occurred())
662 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
663 return 0;
664 }
665
666#ifdef MS_WINDOWS
667 if (win32_warn_bytes_api()) {
668 Py_DECREF(bytes);
669 return 0;
670 }
671#endif
672
673 length = PyBytes_GET_SIZE(bytes);
674#ifdef MS_WINDOWS
675 if (length > MAX_PATH) {
676 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
677 Py_DECREF(bytes);
678 return 0;
679 }
680#endif
681
682 narrow = PyBytes_AS_STRING(bytes);
683 if (length != strlen(narrow)) {
684 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
685 Py_DECREF(bytes);
686 return 0;
687 }
688
689 path->wide = NULL;
690 path->narrow = narrow;
691 path->length = length;
692 path->object = o;
693 path->fd = -1;
694 path->cleanup = bytes;
695 return Py_CLEANUP_SUPPORTED;
696}
697
698static void
699argument_unavailable_error(char *function_name, char *argument_name) {
700 PyErr_Format(PyExc_NotImplementedError,
701 "%s%s%s unavailable on this platform",
702 (function_name != NULL) ? function_name : "",
703 (function_name != NULL) ? ": ": "",
704 argument_name);
705}
706
707static int
708dir_fd_unavailable(PyObject *o, void *p) {
709 int *dir_fd = (int *)p;
710 int return_value = _fd_converter(o, dir_fd, DEFAULT_DIR_FD);
711 if (!return_value)
712 return 0;
713 if (*dir_fd == DEFAULT_DIR_FD)
714 return 1;
715 argument_unavailable_error(NULL, "dir_fd");
716 return 0;
717}
718
719static int
720fd_specified(char *function_name, int fd) {
721 if (fd == -1)
722 return 0;
723
724 argument_unavailable_error(function_name, "fd");
725 return 1;
726}
727
728static int
729follow_symlinks_specified(char *function_name, int follow_symlinks) {
730 if (follow_symlinks)
731 return 0;
732
733 argument_unavailable_error(function_name, "follow_symlinks");
734 return 1;
735}
736
737static int
738path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
739 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
740 PyErr_Format(PyExc_ValueError,
741 "%s: can't specify dir_fd without matching path",
742 function_name);
743 return 1;
744 }
745 return 0;
746}
747
748static int
749dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
750 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
751 PyErr_Format(PyExc_ValueError,
752 "%s: can't specify both dir_fd and fd",
753 function_name);
754 return 1;
755 }
756 return 0;
757}
758
759static int
760fd_and_follow_symlinks_invalid(char *function_name, int fd,
761 int follow_symlinks) {
762 if ((fd > 0) && (!follow_symlinks)) {
763 PyErr_Format(PyExc_ValueError,
764 "%s: cannot use fd and follow_symlinks together",
765 function_name);
766 return 1;
767 }
768 return 0;
769}
770
771static int
772dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
773 int follow_symlinks) {
774 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
775 PyErr_Format(PyExc_ValueError,
776 "%s: cannot use dir_fd and follow_symlinks together",
777 function_name);
778 return 1;
779 }
780 return 0;
781}
782
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200783/* A helper used by a number of POSIX-only functions */
784#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000785static int
786_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000787{
788#if !defined(HAVE_LARGEFILE_SUPPORT)
789 *((off_t*)addr) = PyLong_AsLong(arg);
790#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000791 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000792#endif
793 if (PyErr_Occurred())
794 return 0;
795 return 1;
796}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200797#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000798
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000799#if defined _MSC_VER && _MSC_VER >= 1400
800/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
801 * valid and throw an assertion if it isn't.
802 * Normally, an invalid fd is likely to be a C program error and therefore
803 * an assertion can be useful, but it does contradict the POSIX standard
804 * which for write(2) states:
805 * "Otherwise, -1 shall be returned and errno set to indicate the error."
806 * "[EBADF] The fildes argument is not a valid file descriptor open for
807 * writing."
808 * Furthermore, python allows the user to enter any old integer
809 * as a fd and should merely raise a python exception on error.
810 * The Microsoft CRT doesn't provide an official way to check for the
811 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000812 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000813 * internal structures involved.
814 * The structures below must be updated for each version of visual studio
815 * according to the file internal.h in the CRT source, until MS comes
816 * up with a less hacky way to do this.
817 * (all of this is to avoid globally modifying the CRT behaviour using
818 * _set_invalid_parameter_handler() and _CrtSetReportMode())
819 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000820/* The actual size of the structure is determined at runtime.
821 * Only the first items must be present.
822 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000823typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000824 intptr_t osfhnd;
825 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000826} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000827
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000828extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000829#define IOINFO_L2E 5
830#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
831#define IOINFO_ARRAYS 64
832#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
833#define FOPEN 0x01
834#define _NO_CONSOLE_FILENO (intptr_t)-2
835
836/* This function emulates what the windows CRT does to validate file handles */
837int
838_PyVerify_fd(int fd)
839{
Victor Stinner8c62be82010-05-06 00:08:46 +0000840 const int i1 = fd >> IOINFO_L2E;
841 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000842
Antoine Pitrou22e41552010-08-15 18:07:50 +0000843 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000844
Victor Stinner8c62be82010-05-06 00:08:46 +0000845 /* Determine the actual size of the ioinfo structure,
846 * as used by the CRT loaded in memory
847 */
848 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
849 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
850 }
851 if (sizeof_ioinfo == 0) {
852 /* This should not happen... */
853 goto fail;
854 }
855
856 /* See that it isn't a special CLEAR fileno */
857 if (fd != _NO_CONSOLE_FILENO) {
858 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
859 * we check pointer validity and other info
860 */
861 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
862 /* finally, check that the file is open */
863 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
864 if (info->osfile & FOPEN) {
865 return 1;
866 }
867 }
868 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000869 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000870 errno = EBADF;
871 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000872}
873
874/* the special case of checking dup2. The target fd must be in a sensible range */
875static int
876_PyVerify_fd_dup2(int fd1, int fd2)
877{
Victor Stinner8c62be82010-05-06 00:08:46 +0000878 if (!_PyVerify_fd(fd1))
879 return 0;
880 if (fd2 == _NO_CONSOLE_FILENO)
881 return 0;
882 if ((unsigned)fd2 < _NHANDLE_)
883 return 1;
884 else
885 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000886}
887#else
888/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
889#define _PyVerify_fd_dup2(A, B) (1)
890#endif
891
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000892#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000893/* The following structure was copied from
894 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
895 include doesn't seem to be present in the Windows SDK (at least as included
896 with Visual Studio Express). */
897typedef struct _REPARSE_DATA_BUFFER {
898 ULONG ReparseTag;
899 USHORT ReparseDataLength;
900 USHORT Reserved;
901 union {
902 struct {
903 USHORT SubstituteNameOffset;
904 USHORT SubstituteNameLength;
905 USHORT PrintNameOffset;
906 USHORT PrintNameLength;
907 ULONG Flags;
908 WCHAR PathBuffer[1];
909 } SymbolicLinkReparseBuffer;
910
911 struct {
912 USHORT SubstituteNameOffset;
913 USHORT SubstituteNameLength;
914 USHORT PrintNameOffset;
915 USHORT PrintNameLength;
916 WCHAR PathBuffer[1];
917 } MountPointReparseBuffer;
918
919 struct {
920 UCHAR DataBuffer[1];
921 } GenericReparseBuffer;
922 };
923} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
924
925#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
926 GenericReparseBuffer)
927#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
928
929static int
Brian Curtind25aef52011-06-13 15:16:04 -0500930win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000931{
932 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
933 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
934 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000935
936 if (0 == DeviceIoControl(
937 reparse_point_handle,
938 FSCTL_GET_REPARSE_POINT,
939 NULL, 0, /* in buffer */
940 target_buffer, sizeof(target_buffer),
941 &n_bytes_returned,
942 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500943 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000944
945 if (reparse_tag)
946 *reparse_tag = rdb->ReparseTag;
947
Brian Curtind25aef52011-06-13 15:16:04 -0500948 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000949}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100950
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000951#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000952
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000953/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000954#ifdef WITH_NEXT_FRAMEWORK
955/* On Darwin/MacOSX a shared library or framework has no access to
956** environ directly, we must obtain it with _NSGetEnviron().
957*/
958#include <crt_externs.h>
959static char **environ;
960#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000961extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000962#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000963
Barry Warsaw53699e91996-12-10 23:23:01 +0000964static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000965convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000966{
Victor Stinner8c62be82010-05-06 00:08:46 +0000967 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000968#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000969 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000970#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000971 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000972#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000973#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000974 APIRET rc;
975 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
976#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000977
Victor Stinner8c62be82010-05-06 00:08:46 +0000978 d = PyDict_New();
979 if (d == NULL)
980 return NULL;
981#ifdef WITH_NEXT_FRAMEWORK
982 if (environ == NULL)
983 environ = *_NSGetEnviron();
984#endif
985#ifdef MS_WINDOWS
986 /* _wenviron must be initialized in this way if the program is started
987 through main() instead of wmain(). */
988 _wgetenv(L"");
989 if (_wenviron == NULL)
990 return d;
991 /* This part ignores errors */
992 for (e = _wenviron; *e != NULL; e++) {
993 PyObject *k;
994 PyObject *v;
995 wchar_t *p = wcschr(*e, L'=');
996 if (p == NULL)
997 continue;
998 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
999 if (k == NULL) {
1000 PyErr_Clear();
1001 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001002 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001003 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1004 if (v == NULL) {
1005 PyErr_Clear();
1006 Py_DECREF(k);
1007 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001008 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001009 if (PyDict_GetItem(d, k) == NULL) {
1010 if (PyDict_SetItem(d, k, v) != 0)
1011 PyErr_Clear();
1012 }
1013 Py_DECREF(k);
1014 Py_DECREF(v);
1015 }
1016#else
1017 if (environ == NULL)
1018 return d;
1019 /* This part ignores errors */
1020 for (e = environ; *e != NULL; e++) {
1021 PyObject *k;
1022 PyObject *v;
1023 char *p = strchr(*e, '=');
1024 if (p == NULL)
1025 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001026 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001027 if (k == NULL) {
1028 PyErr_Clear();
1029 continue;
1030 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001031 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001032 if (v == NULL) {
1033 PyErr_Clear();
1034 Py_DECREF(k);
1035 continue;
1036 }
1037 if (PyDict_GetItem(d, k) == NULL) {
1038 if (PyDict_SetItem(d, k, v) != 0)
1039 PyErr_Clear();
1040 }
1041 Py_DECREF(k);
1042 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001043 }
1044#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001045#if defined(PYOS_OS2)
1046 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
1047 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
1048 PyObject *v = PyBytes_FromString(buffer);
1049 PyDict_SetItemString(d, "BEGINLIBPATH", v);
1050 Py_DECREF(v);
1051 }
1052 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
1053 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
1054 PyObject *v = PyBytes_FromString(buffer);
1055 PyDict_SetItemString(d, "ENDLIBPATH", v);
1056 Py_DECREF(v);
1057 }
1058#endif
1059 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001060}
1061
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001062/* Set a POSIX-specific error from errno, and return NULL */
1063
Barry Warsawd58d7641998-07-23 16:14:40 +00001064static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001065posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001066{
Victor Stinner8c62be82010-05-06 00:08:46 +00001067 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001068}
Barry Warsawd58d7641998-07-23 16:14:40 +00001069static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001070posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +00001071{
Victor Stinner8c62be82010-05-06 00:08:46 +00001072 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +00001073}
1074
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001075
Mark Hammondef8b6542001-05-13 08:04:26 +00001076static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +00001077posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +00001078{
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001079 PyObject *name_str, *rc;
1080 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
1081 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +00001082 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001083 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
1084 name_str);
1085 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +00001086 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +00001087}
1088
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001089#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001090static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001091win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001092{
Victor Stinner8c62be82010-05-06 00:08:46 +00001093 /* XXX We should pass the function name along in the future.
1094 (winreg.c also wants to pass the function name.)
1095 This would however require an additional param to the
1096 Windows error object, which is non-trivial.
1097 */
1098 errno = GetLastError();
1099 if (filename)
1100 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1101 else
1102 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001103}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001104
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001105static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001106win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001107{
Victor Stinner8c62be82010-05-06 00:08:46 +00001108 /* XXX - see win32_error for comments on 'function' */
1109 errno = GetLastError();
1110 if (filename)
1111 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
1112 else
1113 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001114}
1115
Victor Stinnereb5657a2011-09-30 01:44:27 +02001116static PyObject *
1117win32_error_object(char* function, PyObject* filename)
1118{
1119 /* XXX - see win32_error for comments on 'function' */
1120 errno = GetLastError();
1121 if (filename)
1122 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1123 PyExc_WindowsError,
1124 errno,
1125 filename);
1126 else
1127 return PyErr_SetFromWindowsErr(errno);
1128}
1129
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001130#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001131
Larry Hastings9cf065c2012-06-22 16:30:09 -07001132/*
1133 * Some functions return Win32 errors, others only ever use posix_error
1134 * (this is for backwards compatibility with exceptions)
1135 */
1136static PyObject *
1137path_posix_error(char *function_name, path_t *path)
1138{
1139 if (path->narrow)
1140 return posix_error_with_filename(path->narrow);
1141 return posix_error();
1142}
1143
1144static PyObject *
1145path_error(char *function_name, path_t *path)
1146{
1147#ifdef MS_WINDOWS
1148 if (path->narrow)
1149 return win32_error(function_name, path->narrow);
1150 if (path->wide)
1151 return win32_error_unicode(function_name, path->wide);
1152 return win32_error(function_name, NULL);
1153#else
1154 return path_posix_error(function_name, path);
1155#endif
1156}
1157
Guido van Rossumd48f2521997-12-05 22:19:34 +00001158#if defined(PYOS_OS2)
1159/**********************************************************************
1160 * Helper Function to Trim and Format OS/2 Messages
1161 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001162static void
Guido van Rossumd48f2521997-12-05 22:19:34 +00001163os2_formatmsg(char *msgbuf, int msglen, char *reason)
1164{
1165 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
1166
1167 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
1168 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
1169
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001170 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +00001171 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
1172 }
1173
1174 /* Add Optional Reason Text */
1175 if (reason) {
1176 strcat(msgbuf, " : ");
1177 strcat(msgbuf, reason);
1178 }
1179}
1180
1181/**********************************************************************
1182 * Decode an OS/2 Operating System Error Code
1183 *
1184 * A convenience function to lookup an OS/2 error code and return a
1185 * text message we can use to raise a Python exception.
1186 *
1187 * Notes:
1188 * The messages for errors returned from the OS/2 kernel reside in
1189 * the file OSO001.MSG in the \OS2 directory hierarchy.
1190 *
1191 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001192static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +00001193os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
1194{
1195 APIRET rc;
1196 ULONG msglen;
1197
1198 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
1199 Py_BEGIN_ALLOW_THREADS
1200 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
1201 errorcode, "oso001.msg", &msglen);
1202 Py_END_ALLOW_THREADS
1203
1204 if (rc == NO_ERROR)
1205 os2_formatmsg(msgbuf, msglen, reason);
1206 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +00001207 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +00001208 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001209
1210 return msgbuf;
1211}
1212
1213/* Set an OS/2-specific error and return NULL. OS/2 kernel
1214 errors are not in a global variable e.g. 'errno' nor are
1215 they congruent with posix error numbers. */
1216
Victor Stinner8c62be82010-05-06 00:08:46 +00001217static PyObject *
1218os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001219{
1220 char text[1024];
1221 PyObject *v;
1222
1223 os2_strerror(text, sizeof(text), code, "");
1224
1225 v = Py_BuildValue("(is)", code, text);
1226 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +00001227 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001228 Py_DECREF(v);
1229 }
1230 return NULL; /* Signal to Python that an Exception is Pending */
1231}
1232
1233#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001234
1235/* POSIX generic methods */
1236
Barry Warsaw53699e91996-12-10 23:23:01 +00001237static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001238posix_fildes(PyObject *fdobj, int (*func)(int))
1239{
Victor Stinner8c62be82010-05-06 00:08:46 +00001240 int fd;
1241 int res;
1242 fd = PyObject_AsFileDescriptor(fdobj);
1243 if (fd < 0)
1244 return NULL;
1245 if (!_PyVerify_fd(fd))
1246 return posix_error();
1247 Py_BEGIN_ALLOW_THREADS
1248 res = (*func)(fd);
1249 Py_END_ALLOW_THREADS
1250 if (res < 0)
1251 return posix_error();
1252 Py_INCREF(Py_None);
1253 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001254}
Guido van Rossum21142a01999-01-08 21:05:37 +00001255
1256static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001257posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001258{
Victor Stinner8c62be82010-05-06 00:08:46 +00001259 PyObject *opath1 = NULL;
1260 char *path1;
1261 int res;
1262 if (!PyArg_ParseTuple(args, format,
1263 PyUnicode_FSConverter, &opath1))
1264 return NULL;
1265 path1 = PyBytes_AsString(opath1);
1266 Py_BEGIN_ALLOW_THREADS
1267 res = (*func)(path1);
1268 Py_END_ALLOW_THREADS
1269 if (res < 0)
1270 return posix_error_with_allocated_filename(opath1);
1271 Py_DECREF(opath1);
1272 Py_INCREF(Py_None);
1273 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001274}
1275
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001276
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001277#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001278static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +00001279win32_1str(PyObject* args, char* func,
1280 char* format, BOOL (__stdcall *funcA)(LPCSTR),
1281 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001282{
Victor Stinner8c62be82010-05-06 00:08:46 +00001283 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001284 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +00001285 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001286
Victor Stinnereb5657a2011-09-30 01:44:27 +02001287 if (PyArg_ParseTuple(args, wformat, &uni))
1288 {
1289 wchar_t *wstr = PyUnicode_AsUnicode(uni);
1290 if (wstr == NULL)
1291 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001292 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001293 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00001294 Py_END_ALLOW_THREADS
1295 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001296 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +00001297 Py_INCREF(Py_None);
1298 return Py_None;
1299 }
Victor Stinnereb5657a2011-09-30 01:44:27 +02001300 PyErr_Clear();
1301
Victor Stinner8c62be82010-05-06 00:08:46 +00001302 if (!PyArg_ParseTuple(args, format, &ansi))
1303 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001304 if (win32_warn_bytes_api())
1305 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001306 Py_BEGIN_ALLOW_THREADS
1307 result = funcA(ansi);
1308 Py_END_ALLOW_THREADS
1309 if (!result)
1310 return win32_error(func, ansi);
1311 Py_INCREF(Py_None);
1312 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001313
1314}
1315
1316/* This is a reimplementation of the C library's chdir function,
1317 but one that produces Win32 errors instead of DOS error codes.
1318 chdir is essentially a wrapper around SetCurrentDirectory; however,
1319 it also needs to set "magic" environment variables indicating
1320 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001321static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001322win32_chdir(LPCSTR path)
1323{
Victor Stinner8c62be82010-05-06 00:08:46 +00001324 char new_path[MAX_PATH+1];
1325 int result;
1326 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001327
Victor Stinner8c62be82010-05-06 00:08:46 +00001328 if(!SetCurrentDirectoryA(path))
1329 return FALSE;
1330 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1331 if (!result)
1332 return FALSE;
1333 /* In the ANSI API, there should not be any paths longer
1334 than MAX_PATH. */
1335 assert(result <= MAX_PATH+1);
1336 if (strncmp(new_path, "\\\\", 2) == 0 ||
1337 strncmp(new_path, "//", 2) == 0)
1338 /* UNC path, nothing to do. */
1339 return TRUE;
1340 env[1] = new_path[0];
1341 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001342}
1343
1344/* The Unicode version differs from the ANSI version
1345 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001346static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001347win32_wchdir(LPCWSTR path)
1348{
Victor Stinner8c62be82010-05-06 00:08:46 +00001349 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1350 int result;
1351 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001352
Victor Stinner8c62be82010-05-06 00:08:46 +00001353 if(!SetCurrentDirectoryW(path))
1354 return FALSE;
1355 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1356 if (!result)
1357 return FALSE;
1358 if (result > MAX_PATH+1) {
1359 new_path = malloc(result * sizeof(wchar_t));
1360 if (!new_path) {
1361 SetLastError(ERROR_OUTOFMEMORY);
1362 return FALSE;
1363 }
1364 result = GetCurrentDirectoryW(result, new_path);
1365 if (!result) {
1366 free(new_path);
1367 return FALSE;
1368 }
1369 }
1370 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1371 wcsncmp(new_path, L"//", 2) == 0)
1372 /* UNC path, nothing to do. */
1373 return TRUE;
1374 env[1] = new_path[0];
1375 result = SetEnvironmentVariableW(env, new_path);
1376 if (new_path != _new_path)
1377 free(new_path);
1378 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001379}
1380#endif
1381
Martin v. Löwis14694662006-02-03 12:54:16 +00001382#ifdef MS_WINDOWS
1383/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1384 - time stamps are restricted to second resolution
1385 - file modification times suffer from forth-and-back conversions between
1386 UTC and local time
1387 Therefore, we implement our own stat, based on the Win32 API directly.
1388*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001389#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001390
1391struct win32_stat{
1392 int st_dev;
1393 __int64 st_ino;
1394 unsigned short st_mode;
1395 int st_nlink;
1396 int st_uid;
1397 int st_gid;
1398 int st_rdev;
1399 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001400 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001401 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001402 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001403 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001404 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001405 int st_ctime_nsec;
1406};
1407
1408static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1409
1410static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001411FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001412{
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1414 /* Cannot simply cast and dereference in_ptr,
1415 since it might not be aligned properly */
1416 __int64 in;
1417 memcpy(&in, in_ptr, sizeof(in));
1418 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001419 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001420}
1421
Thomas Wouters477c8d52006-05-27 19:21:47 +00001422static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001423time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001424{
Victor Stinner8c62be82010-05-06 00:08:46 +00001425 /* XXX endianness */
1426 __int64 out;
1427 out = time_in + secs_between_epochs;
1428 out = out * 10000000 + nsec_in / 100;
1429 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001430}
1431
Martin v. Löwis14694662006-02-03 12:54:16 +00001432/* Below, we *know* that ugo+r is 0444 */
1433#if _S_IREAD != 0400
1434#error Unsupported C library
1435#endif
1436static int
1437attributes_to_mode(DWORD attr)
1438{
Victor Stinner8c62be82010-05-06 00:08:46 +00001439 int m = 0;
1440 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1441 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1442 else
1443 m |= _S_IFREG;
1444 if (attr & FILE_ATTRIBUTE_READONLY)
1445 m |= 0444;
1446 else
1447 m |= 0666;
1448 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001449}
1450
1451static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001452attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001453{
Victor Stinner8c62be82010-05-06 00:08:46 +00001454 memset(result, 0, sizeof(*result));
1455 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1456 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1457 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1458 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1459 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001460 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001461 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001462 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1463 /* first clear the S_IFMT bits */
1464 result->st_mode ^= (result->st_mode & 0170000);
1465 /* now set the bits that make this a symlink */
1466 result->st_mode |= 0120000;
1467 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001468
Victor Stinner8c62be82010-05-06 00:08:46 +00001469 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001470}
1471
Guido van Rossumd8faa362007-04-27 19:54:29 +00001472static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001473attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001474{
Victor Stinner8c62be82010-05-06 00:08:46 +00001475 HANDLE hFindFile;
1476 WIN32_FIND_DATAA FileData;
1477 hFindFile = FindFirstFileA(pszFile, &FileData);
1478 if (hFindFile == INVALID_HANDLE_VALUE)
1479 return FALSE;
1480 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001481 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001482 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001483 info->dwFileAttributes = FileData.dwFileAttributes;
1484 info->ftCreationTime = FileData.ftCreationTime;
1485 info->ftLastAccessTime = FileData.ftLastAccessTime;
1486 info->ftLastWriteTime = FileData.ftLastWriteTime;
1487 info->nFileSizeHigh = FileData.nFileSizeHigh;
1488 info->nFileSizeLow = FileData.nFileSizeLow;
1489/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001490 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1491 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001492 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001493}
1494
1495static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001496attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001497{
Victor Stinner8c62be82010-05-06 00:08:46 +00001498 HANDLE hFindFile;
1499 WIN32_FIND_DATAW FileData;
1500 hFindFile = FindFirstFileW(pszFile, &FileData);
1501 if (hFindFile == INVALID_HANDLE_VALUE)
1502 return FALSE;
1503 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001504 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001505 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001506 info->dwFileAttributes = FileData.dwFileAttributes;
1507 info->ftCreationTime = FileData.ftCreationTime;
1508 info->ftLastAccessTime = FileData.ftLastAccessTime;
1509 info->ftLastWriteTime = FileData.ftLastWriteTime;
1510 info->nFileSizeHigh = FileData.nFileSizeHigh;
1511 info->nFileSizeLow = FileData.nFileSizeLow;
1512/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001513 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1514 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001515 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001516}
1517
Brian Curtind25aef52011-06-13 15:16:04 -05001518/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1519static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001520static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1521 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001522static int
Brian Curtind25aef52011-06-13 15:16:04 -05001523check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001524{
Brian Curtind25aef52011-06-13 15:16:04 -05001525 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001526 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1527 DWORD);
1528
Brian Curtind25aef52011-06-13 15:16:04 -05001529 /* only recheck */
1530 if (!has_GetFinalPathNameByHandle)
1531 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001532 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001533 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1534 "GetFinalPathNameByHandleA");
1535 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1536 "GetFinalPathNameByHandleW");
1537 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1538 Py_GetFinalPathNameByHandleW;
1539 }
1540 return has_GetFinalPathNameByHandle;
1541}
1542
1543static BOOL
1544get_target_path(HANDLE hdl, wchar_t **target_path)
1545{
1546 int buf_size, result_length;
1547 wchar_t *buf;
1548
1549 /* We have a good handle to the target, use it to determine
1550 the target path name (then we'll call lstat on it). */
1551 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1552 VOLUME_NAME_DOS);
1553 if(!buf_size)
1554 return FALSE;
1555
1556 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001557 if (!buf) {
1558 SetLastError(ERROR_OUTOFMEMORY);
1559 return FALSE;
1560 }
1561
Brian Curtind25aef52011-06-13 15:16:04 -05001562 result_length = Py_GetFinalPathNameByHandleW(hdl,
1563 buf, buf_size, VOLUME_NAME_DOS);
1564
1565 if(!result_length) {
1566 free(buf);
1567 return FALSE;
1568 }
1569
1570 if(!CloseHandle(hdl)) {
1571 free(buf);
1572 return FALSE;
1573 }
1574
1575 buf[result_length] = 0;
1576
1577 *target_path = buf;
1578 return TRUE;
1579}
1580
1581static int
1582win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1583 BOOL traverse);
1584static int
1585win32_xstat_impl(const char *path, struct win32_stat *result,
1586 BOOL traverse)
1587{
Victor Stinner26de69d2011-06-17 15:15:38 +02001588 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001589 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001590 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001591 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001592 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001593 const char *dot;
1594
Brian Curtind25aef52011-06-13 15:16:04 -05001595 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001596 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1597 traverse reparse point. */
1598 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001599 }
1600
Brian Curtinf5e76d02010-11-24 13:14:05 +00001601 hFile = CreateFileA(
1602 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001603 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001604 0, /* share mode */
1605 NULL, /* security attributes */
1606 OPEN_EXISTING,
1607 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001608 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1609 Because of this, calls like GetFinalPathNameByHandle will return
1610 the symlink path agin and not the actual final path. */
1611 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1612 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001613 NULL);
1614
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001615 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001616 /* Either the target doesn't exist, or we don't have access to
1617 get a handle to it. If the former, we need to return an error.
1618 If the latter, we can use attributes_from_dir. */
1619 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001620 return -1;
1621 /* Could not get attributes on open file. Fall back to
1622 reading the directory. */
1623 if (!attributes_from_dir(path, &info, &reparse_tag))
1624 /* Very strange. This should not fail now */
1625 return -1;
1626 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1627 if (traverse) {
1628 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001629 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001630 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001631 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001632 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001633 } else {
1634 if (!GetFileInformationByHandle(hFile, &info)) {
1635 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001636 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001637 }
1638 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001639 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1640 return -1;
1641
1642 /* Close the outer open file handle now that we're about to
1643 reopen it with different flags. */
1644 if (!CloseHandle(hFile))
1645 return -1;
1646
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001647 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001648 /* In order to call GetFinalPathNameByHandle we need to open
1649 the file without the reparse handling flag set. */
1650 hFile2 = CreateFileA(
1651 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1652 NULL, OPEN_EXISTING,
1653 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1654 NULL);
1655 if (hFile2 == INVALID_HANDLE_VALUE)
1656 return -1;
1657
1658 if (!get_target_path(hFile2, &target_path))
1659 return -1;
1660
1661 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001662 free(target_path);
1663 return code;
1664 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001665 } else
1666 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001667 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001668 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001669
1670 /* Set S_IEXEC if it is an .exe, .bat, ... */
1671 dot = strrchr(path, '.');
1672 if (dot) {
1673 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1674 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1675 result->st_mode |= 0111;
1676 }
1677 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001678}
1679
1680static int
Brian Curtind25aef52011-06-13 15:16:04 -05001681win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1682 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001683{
1684 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001685 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001686 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001687 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001688 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001689 const wchar_t *dot;
1690
Brian Curtind25aef52011-06-13 15:16:04 -05001691 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001692 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1693 traverse reparse point. */
1694 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001695 }
1696
Brian Curtinf5e76d02010-11-24 13:14:05 +00001697 hFile = CreateFileW(
1698 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001699 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001700 0, /* share mode */
1701 NULL, /* security attributes */
1702 OPEN_EXISTING,
1703 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001704 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1705 Because of this, calls like GetFinalPathNameByHandle will return
1706 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001707 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001708 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001709 NULL);
1710
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001711 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001712 /* Either the target doesn't exist, or we don't have access to
1713 get a handle to it. If the former, we need to return an error.
1714 If the latter, we can use attributes_from_dir. */
1715 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001716 return -1;
1717 /* Could not get attributes on open file. Fall back to
1718 reading the directory. */
1719 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1720 /* Very strange. This should not fail now */
1721 return -1;
1722 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1723 if (traverse) {
1724 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001725 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001726 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001727 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001728 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001729 } else {
1730 if (!GetFileInformationByHandle(hFile, &info)) {
1731 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001732 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001733 }
1734 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001735 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1736 return -1;
1737
1738 /* Close the outer open file handle now that we're about to
1739 reopen it with different flags. */
1740 if (!CloseHandle(hFile))
1741 return -1;
1742
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001743 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001744 /* In order to call GetFinalPathNameByHandle we need to open
1745 the file without the reparse handling flag set. */
1746 hFile2 = CreateFileW(
1747 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1748 NULL, OPEN_EXISTING,
1749 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1750 NULL);
1751 if (hFile2 == INVALID_HANDLE_VALUE)
1752 return -1;
1753
1754 if (!get_target_path(hFile2, &target_path))
1755 return -1;
1756
1757 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001758 free(target_path);
1759 return code;
1760 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001761 } else
1762 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001763 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001764 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001765
1766 /* Set S_IEXEC if it is an .exe, .bat, ... */
1767 dot = wcsrchr(path, '.');
1768 if (dot) {
1769 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1770 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1771 result->st_mode |= 0111;
1772 }
1773 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001774}
1775
1776static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001777win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001778{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001779 /* Protocol violation: we explicitly clear errno, instead of
1780 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001781 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001782 errno = 0;
1783 return code;
1784}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001785
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001786static int
1787win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1788{
1789 /* Protocol violation: we explicitly clear errno, instead of
1790 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001791 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001792 errno = 0;
1793 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001794}
Brian Curtind25aef52011-06-13 15:16:04 -05001795/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001796
1797 In Posix, stat automatically traverses symlinks and returns the stat
1798 structure for the target. In Windows, the equivalent GetFileAttributes by
1799 default does not traverse symlinks and instead returns attributes for
1800 the symlink.
1801
1802 Therefore, win32_lstat will get the attributes traditionally, and
1803 win32_stat will first explicitly resolve the symlink target and then will
1804 call win32_lstat on that result.
1805
Ezio Melotti4969f702011-03-15 05:59:46 +02001806 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001807
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001808static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001809win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001810{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001811 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001812}
1813
Victor Stinner8c62be82010-05-06 00:08:46 +00001814static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001815win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001816{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001817 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001818}
1819
1820static int
1821win32_stat(const char* path, struct win32_stat *result)
1822{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001823 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001824}
1825
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001826static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001827win32_stat_w(const wchar_t* path, struct win32_stat *result)
1828{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001829 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001830}
1831
1832static int
1833win32_fstat(int file_number, struct win32_stat *result)
1834{
Victor Stinner8c62be82010-05-06 00:08:46 +00001835 BY_HANDLE_FILE_INFORMATION info;
1836 HANDLE h;
1837 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001838
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001839 if (!_PyVerify_fd(file_number))
1840 h = INVALID_HANDLE_VALUE;
1841 else
1842 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001843
Victor Stinner8c62be82010-05-06 00:08:46 +00001844 /* Protocol violation: we explicitly clear errno, instead of
1845 setting it to a POSIX error. Callers should use GetLastError. */
1846 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001847
Victor Stinner8c62be82010-05-06 00:08:46 +00001848 if (h == INVALID_HANDLE_VALUE) {
1849 /* This is really a C library error (invalid file handle).
1850 We set the Win32 error to the closes one matching. */
1851 SetLastError(ERROR_INVALID_HANDLE);
1852 return -1;
1853 }
1854 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001855
Victor Stinner8c62be82010-05-06 00:08:46 +00001856 type = GetFileType(h);
1857 if (type == FILE_TYPE_UNKNOWN) {
1858 DWORD error = GetLastError();
1859 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001860 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001861 }
1862 /* else: valid but unknown file */
1863 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001864
Victor Stinner8c62be82010-05-06 00:08:46 +00001865 if (type != FILE_TYPE_DISK) {
1866 if (type == FILE_TYPE_CHAR)
1867 result->st_mode = _S_IFCHR;
1868 else if (type == FILE_TYPE_PIPE)
1869 result->st_mode = _S_IFIFO;
1870 return 0;
1871 }
1872
1873 if (!GetFileInformationByHandle(h, &info)) {
1874 return -1;
1875 }
1876
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001877 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001878 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001879 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1880 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001881}
1882
1883#endif /* MS_WINDOWS */
1884
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001885PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001886"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001887This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001888 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001889or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1890\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001891Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1892or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001893\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001894See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001895
1896static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001897 {"st_mode", "protection bits"},
1898 {"st_ino", "inode"},
1899 {"st_dev", "device"},
1900 {"st_nlink", "number of hard links"},
1901 {"st_uid", "user ID of owner"},
1902 {"st_gid", "group ID of owner"},
1903 {"st_size", "total size, in bytes"},
1904 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1905 {NULL, "integer time of last access"},
1906 {NULL, "integer time of last modification"},
1907 {NULL, "integer time of last change"},
1908 {"st_atime", "time of last access"},
1909 {"st_mtime", "time of last modification"},
1910 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001911 {"st_atime_ns", "time of last access in nanoseconds"},
1912 {"st_mtime_ns", "time of last modification in nanoseconds"},
1913 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001914#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001915 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001916#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001917#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001918 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001919#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001920#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001921 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001922#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001923#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001924 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001925#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001926#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001927 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001928#endif
1929#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001930 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001931#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001932 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001933};
1934
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001935#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001936#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001937#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001938#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001939#endif
1940
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001941#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001942#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1943#else
1944#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1945#endif
1946
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001947#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001948#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1949#else
1950#define ST_RDEV_IDX ST_BLOCKS_IDX
1951#endif
1952
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001953#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1954#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1955#else
1956#define ST_FLAGS_IDX ST_RDEV_IDX
1957#endif
1958
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001959#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001960#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001961#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001962#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001963#endif
1964
1965#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1966#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1967#else
1968#define ST_BIRTHTIME_IDX ST_GEN_IDX
1969#endif
1970
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001971static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001972 "stat_result", /* name */
1973 stat_result__doc__, /* doc */
1974 stat_result_fields,
1975 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001976};
1977
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001978PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001979"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1980This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001981 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001982or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001983\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001984See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001985
1986static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001987 {"f_bsize", },
1988 {"f_frsize", },
1989 {"f_blocks", },
1990 {"f_bfree", },
1991 {"f_bavail", },
1992 {"f_files", },
1993 {"f_ffree", },
1994 {"f_favail", },
1995 {"f_flag", },
1996 {"f_namemax",},
1997 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001998};
1999
2000static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002001 "statvfs_result", /* name */
2002 statvfs_result__doc__, /* doc */
2003 statvfs_result_fields,
2004 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002005};
2006
Ross Lagerwall7807c352011-03-17 20:20:30 +02002007#if defined(HAVE_WAITID) && !defined(__APPLE__)
2008PyDoc_STRVAR(waitid_result__doc__,
2009"waitid_result: Result from waitid.\n\n\
2010This object may be accessed either as a tuple of\n\
2011 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2012or via the attributes si_pid, si_uid, and so on.\n\
2013\n\
2014See os.waitid for more information.");
2015
2016static PyStructSequence_Field waitid_result_fields[] = {
2017 {"si_pid", },
2018 {"si_uid", },
2019 {"si_signo", },
2020 {"si_status", },
2021 {"si_code", },
2022 {0}
2023};
2024
2025static PyStructSequence_Desc waitid_result_desc = {
2026 "waitid_result", /* name */
2027 waitid_result__doc__, /* doc */
2028 waitid_result_fields,
2029 5
2030};
2031static PyTypeObject WaitidResultType;
2032#endif
2033
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002034static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002035static PyTypeObject StatResultType;
2036static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002037#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002038static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002039#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002040static newfunc structseq_new;
2041
2042static PyObject *
2043statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2044{
Victor Stinner8c62be82010-05-06 00:08:46 +00002045 PyStructSequence *result;
2046 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002047
Victor Stinner8c62be82010-05-06 00:08:46 +00002048 result = (PyStructSequence*)structseq_new(type, args, kwds);
2049 if (!result)
2050 return NULL;
2051 /* If we have been initialized from a tuple,
2052 st_?time might be set to None. Initialize it
2053 from the int slots. */
2054 for (i = 7; i <= 9; i++) {
2055 if (result->ob_item[i+3] == Py_None) {
2056 Py_DECREF(Py_None);
2057 Py_INCREF(result->ob_item[i]);
2058 result->ob_item[i+3] = result->ob_item[i];
2059 }
2060 }
2061 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002062}
2063
2064
2065
2066/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002067static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002068
2069PyDoc_STRVAR(stat_float_times__doc__,
2070"stat_float_times([newval]) -> oldval\n\n\
2071Determine whether os.[lf]stat represents time stamps as float objects.\n\
2072If newval is True, future calls to stat() return floats, if it is False,\n\
2073future calls return ints. \n\
2074If newval is omitted, return the current setting.\n");
2075
2076static PyObject*
2077stat_float_times(PyObject* self, PyObject *args)
2078{
Victor Stinner8c62be82010-05-06 00:08:46 +00002079 int newval = -1;
2080 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2081 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002082 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2083 "stat_float_times() is deprecated",
2084 1))
2085 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002086 if (newval == -1)
2087 /* Return old value */
2088 return PyBool_FromLong(_stat_float_times);
2089 _stat_float_times = newval;
2090 Py_INCREF(Py_None);
2091 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002092}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002093
Larry Hastings6fe20b32012-04-19 15:07:49 -07002094static PyObject *billion = NULL;
2095
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002096static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002097fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002098{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002099 PyObject *s = _PyLong_FromTime_t(sec);
2100 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2101 PyObject *s_in_ns = NULL;
2102 PyObject *ns_total = NULL;
2103 PyObject *float_s = NULL;
2104
2105 if (!(s && ns_fractional))
2106 goto exit;
2107
2108 s_in_ns = PyNumber_Multiply(s, billion);
2109 if (!s_in_ns)
2110 goto exit;
2111
2112 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2113 if (!ns_total)
2114 goto exit;
2115
Victor Stinner4195b5c2012-02-08 23:03:19 +01002116 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002117 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2118 if (!float_s)
2119 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002120 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002121 else {
2122 float_s = s;
2123 Py_INCREF(float_s);
2124 }
2125
2126 PyStructSequence_SET_ITEM(v, index, s);
2127 PyStructSequence_SET_ITEM(v, index+3, float_s);
2128 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2129 s = NULL;
2130 float_s = NULL;
2131 ns_total = NULL;
2132exit:
2133 Py_XDECREF(s);
2134 Py_XDECREF(ns_fractional);
2135 Py_XDECREF(s_in_ns);
2136 Py_XDECREF(ns_total);
2137 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002138}
2139
Tim Peters5aa91602002-01-30 05:46:57 +00002140/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002141 (used by posix_stat() and posix_fstat()) */
2142static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002143_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002144{
Victor Stinner8c62be82010-05-06 00:08:46 +00002145 unsigned long ansec, mnsec, cnsec;
2146 PyObject *v = PyStructSequence_New(&StatResultType);
2147 if (v == NULL)
2148 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002149
Victor Stinner8c62be82010-05-06 00:08:46 +00002150 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002151#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002152 PyStructSequence_SET_ITEM(v, 1,
2153 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002154#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002155 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002156#endif
2157#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002158 PyStructSequence_SET_ITEM(v, 2,
2159 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002160#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002161 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002162#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002163 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
2164 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
2165 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00002166#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002167 PyStructSequence_SET_ITEM(v, 6,
2168 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002169#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002170 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002171#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002172
Martin v. Löwis14694662006-02-03 12:54:16 +00002173#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002174 ansec = st->st_atim.tv_nsec;
2175 mnsec = st->st_mtim.tv_nsec;
2176 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002177#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002178 ansec = st->st_atimespec.tv_nsec;
2179 mnsec = st->st_mtimespec.tv_nsec;
2180 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002181#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002182 ansec = st->st_atime_nsec;
2183 mnsec = st->st_mtime_nsec;
2184 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002185#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002186 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002187#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002188 fill_time(v, 7, st->st_atime, ansec);
2189 fill_time(v, 8, st->st_mtime, mnsec);
2190 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002191
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002192#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002193 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2194 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002195#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002196#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002197 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2198 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002199#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002200#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002201 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2202 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002203#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002204#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002205 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2206 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002207#endif
2208#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002209 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002210 PyObject *val;
2211 unsigned long bsec,bnsec;
2212 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002213#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002214 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002215#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002216 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002217#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002218 if (_stat_float_times) {
2219 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2220 } else {
2221 val = PyLong_FromLong((long)bsec);
2222 }
2223 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2224 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002225 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002226#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002227#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002228 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2229 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002230#endif
Fred Drake699f3522000-06-29 21:12:41 +00002231
Victor Stinner8c62be82010-05-06 00:08:46 +00002232 if (PyErr_Occurred()) {
2233 Py_DECREF(v);
2234 return NULL;
2235 }
Fred Drake699f3522000-06-29 21:12:41 +00002236
Victor Stinner8c62be82010-05-06 00:08:46 +00002237 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002238}
2239
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002240/* POSIX methods */
2241
Guido van Rossum94f6f721999-01-06 18:42:14 +00002242
2243static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002244posix_do_stat(char *function_name, path_t *path,
2245 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002246{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002247 STRUCT_STAT st;
2248 int result;
2249
2250#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2251 if (follow_symlinks_specified(function_name, follow_symlinks))
2252 return NULL;
2253#endif
2254
2255 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2256 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2257 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2258 return NULL;
2259
2260 Py_BEGIN_ALLOW_THREADS
2261 if (path->fd != -1)
2262 result = FSTAT(path->fd, &st);
2263 else
2264#ifdef MS_WINDOWS
2265 if (path->wide) {
2266 if (follow_symlinks)
2267 result = win32_stat_w(path->wide, &st);
2268 else
2269 result = win32_lstat_w(path->wide, &st);
2270 }
2271 else
2272#endif
2273#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2274 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2275 result = LSTAT(path->narrow, &st);
2276 else
2277#endif
2278#ifdef HAVE_FSTATAT
2279 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2280 result = fstatat(dir_fd, path->narrow, &st,
2281 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2282 else
2283#endif
2284 result = STAT(path->narrow, &st);
2285 Py_END_ALLOW_THREADS
2286
2287 if (result != 0)
2288 return path_error("stat", path);
2289
2290 return _pystat_fromstructstat(&st);
2291}
2292
2293PyDoc_STRVAR(posix_stat__doc__,
2294"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2295Perform a stat system call on the given path.\n\
2296\n\
2297path may be specified as either a string or as an open file descriptor.\n\
2298\n\
2299If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2300 and path should be relative; path will then be relative to that directory.\n\
2301 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2302 it will raise a NotImplementedError.\n\
2303If follow_symlinks is False, and the last element of the path is a symbolic\n\
2304 link, stat will examine the symbolic link itself instead of the file the\n\
2305 link points to.\n\
2306It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2307 an open file descriptor.");
2308
2309static PyObject *
2310posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2311{
2312 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2313 path_t path;
2314 int dir_fd = DEFAULT_DIR_FD;
2315 int follow_symlinks = 1;
2316 PyObject *return_value;
2317
2318 memset(&path, 0, sizeof(path));
2319 path.allow_fd = 1;
2320 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2321 path_converter, &path,
2322#ifdef HAVE_FSTATAT
2323 dir_fd_converter, &dir_fd,
2324#else
2325 dir_fd_unavailable, &dir_fd,
2326#endif
2327 &follow_symlinks))
2328 return NULL;
2329 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2330 path_cleanup(&path);
2331 return return_value;
2332}
2333
2334PyDoc_STRVAR(posix_lstat__doc__,
2335"lstat(path, *, dir_fd=None) -> stat result\n\n\
2336Like stat(), but do not follow symbolic links.\n\
2337Equivalent to stat(path, follow_symlinks=False).");
2338
2339static PyObject *
2340posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2341{
2342 static char *keywords[] = {"path", "dir_fd", NULL};
2343 path_t path;
2344 int dir_fd = DEFAULT_DIR_FD;
2345 int follow_symlinks = 0;
2346 PyObject *return_value;
2347
2348 memset(&path, 0, sizeof(path));
2349 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2350 path_converter, &path,
2351#ifdef HAVE_FSTATAT
2352 dir_fd_converter, &dir_fd
2353#else
2354 dir_fd_unavailable, &dir_fd
2355#endif
2356 ))
2357 return NULL;
2358 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2359 path_cleanup(&path);
2360 return return_value;
2361}
2362
2363PyDoc_STRVAR(posix_access__doc__,
2364"access(path, mode, *, dir_fd=None, effective_ids=False,\
2365 follow_symlinks=True)\n\n\
2366Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2367False otherwise.\n\
2368\n\
2369If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2370 and path should be relative; path will then be relative to that directory.\n\
2371If effective_ids is True, access will use the effective uid/gid instead of\n\
2372 the real uid/gid.\n\
2373If follow_symlinks is False, and the last element of the path is a symbolic\n\
2374 link, access will examine the symbolic link itself instead of the file the\n\
2375 link points to.\n\
2376dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2377 on your platform. If they are unavailable, using them will raise a\n\
2378 NotImplementedError.\n\
2379\n\
2380Note that most operations will use the effective uid/gid, therefore this\n\
2381 routine can be used in a suid/sgid environment to test if the invoking user\n\
2382 has the specified access to the path.\n\
2383The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2384 of R_OK, W_OK, and X_OK.");
2385
2386static PyObject *
2387posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2388{
2389 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2390 "follow_symlinks", NULL};
2391 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002392 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002393 int dir_fd = DEFAULT_DIR_FD;
2394 int effective_ids = 0;
2395 int follow_symlinks = 1;
2396 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002397
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002398#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002399 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002400#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002401 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002402#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002403
2404 memset(&path, 0, sizeof(path));
2405 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2406 path_converter, &path, &mode,
2407#ifdef HAVE_FACCESSAT
2408 dir_fd_converter, &dir_fd,
2409#else
2410 dir_fd_unavailable, &dir_fd,
2411#endif
2412 &effective_ids, &follow_symlinks))
2413 return NULL;
2414
2415#ifndef HAVE_FACCESSAT
2416 if (follow_symlinks_specified("access", follow_symlinks))
2417 goto exit;
2418
2419 if (effective_ids) {
2420 argument_unavailable_error("access", "effective_ids");
2421 goto exit;
2422 }
2423#endif
2424
2425#ifdef MS_WINDOWS
2426 Py_BEGIN_ALLOW_THREADS
2427 if (path.wide != NULL)
2428 attr = GetFileAttributesW(path.wide);
2429 else
2430 attr = GetFileAttributesA(path.narrow);
2431 Py_END_ALLOW_THREADS
2432
2433 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002434 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002435 * * we didn't get a -1, and
2436 * * write access wasn't requested,
2437 * * or the file isn't read-only,
2438 * * or it's a directory.
2439 * (Directories cannot be read-only on Windows.)
2440 */
2441 return_value = PyBool_FromLong(
2442 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002443 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002444 !(attr & FILE_ATTRIBUTE_READONLY) ||
2445 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2446#else
2447
2448 Py_BEGIN_ALLOW_THREADS
2449#ifdef HAVE_FACCESSAT
2450 if ((dir_fd != DEFAULT_DIR_FD) ||
2451 effective_ids ||
2452 !follow_symlinks) {
2453 int flags = 0;
2454 if (!follow_symlinks)
2455 flags |= AT_SYMLINK_NOFOLLOW;
2456 if (effective_ids)
2457 flags |= AT_EACCESS;
2458 result = faccessat(dir_fd, path.narrow, mode, flags);
2459 }
2460 else
2461#endif
2462 result = access(path.narrow, mode);
2463 Py_END_ALLOW_THREADS
2464 return_value = PyBool_FromLong(!result);
2465#endif
2466
2467#ifndef HAVE_FACCESSAT
2468exit:
2469#endif
2470 path_cleanup(&path);
2471 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002472}
2473
Guido van Rossumd371ff11999-01-25 16:12:23 +00002474#ifndef F_OK
2475#define F_OK 0
2476#endif
2477#ifndef R_OK
2478#define R_OK 4
2479#endif
2480#ifndef W_OK
2481#define W_OK 2
2482#endif
2483#ifndef X_OK
2484#define X_OK 1
2485#endif
2486
2487#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002488PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002489"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002490Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002491
2492static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002493posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002494{
Victor Stinner8c62be82010-05-06 00:08:46 +00002495 int id;
2496 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002497
Victor Stinner8c62be82010-05-06 00:08:46 +00002498 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2499 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002500
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002501#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002502 /* file descriptor 0 only, the default input device (stdin) */
2503 if (id == 0) {
2504 ret = ttyname();
2505 }
2506 else {
2507 ret = NULL;
2508 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002509#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002510 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002511#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002512 if (ret == NULL)
2513 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002514 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002515}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002516#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002517
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002518#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002519PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002520"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002521Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002522
2523static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002524posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002525{
Victor Stinner8c62be82010-05-06 00:08:46 +00002526 char *ret;
2527 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002528
Greg Wardb48bc172000-03-01 21:51:56 +00002529#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002530 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002531#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002532 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002533#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002534 if (ret == NULL)
2535 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002536 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002537}
2538#endif
2539
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002540PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002541"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002542Change the current working directory to the specified path.\n\
2543\n\
2544path may always be specified as a string.\n\
2545On some platforms, path may also be specified as an open file descriptor.\n\
2546 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002547
Barry Warsaw53699e91996-12-10 23:23:01 +00002548static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002549posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002550{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002551 path_t path;
2552 int result;
2553 PyObject *return_value = NULL;
2554 static char *keywords[] = {"path", NULL};
2555
2556 memset(&path, 0, sizeof(path));
2557#ifdef HAVE_FCHDIR
2558 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002559#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002560 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2561 path_converter, &path
2562 ))
2563 return NULL;
2564
2565 Py_BEGIN_ALLOW_THREADS
2566#ifdef MS_WINDOWS
2567 if (path.wide)
2568 result = win32_wchdir(path.wide);
2569 else
2570 result = win32_chdir(path.narrow);
2571 result = !result; /* on unix, success = 0, on windows, success = !0 */
2572#elif defined(PYOS_OS2) && defined(PYCC_GCC)
2573 result = _chdir2(path.narrow);
2574#else
2575#ifdef HAVE_FCHDIR
2576 if (path.fd != -1)
2577 result = fchdir(path.fd);
2578 else
2579#endif
2580 result = chdir(path.narrow);
2581#endif
2582 Py_END_ALLOW_THREADS
2583
2584 if (result) {
2585 return_value = path_error("chdir", &path);
2586 goto exit;
2587 }
2588
2589 return_value = Py_None;
2590 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002591
Larry Hastings9cf065c2012-06-22 16:30:09 -07002592exit:
2593 path_cleanup(&path);
2594 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002595}
2596
Fred Drake4d1e64b2002-04-15 19:40:07 +00002597#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002598PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002599"fchdir(fd)\n\n\
2600Change to the directory of the given file descriptor. fd must be\n\
2601opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002602
2603static PyObject *
2604posix_fchdir(PyObject *self, PyObject *fdobj)
2605{
Victor Stinner8c62be82010-05-06 00:08:46 +00002606 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002607}
2608#endif /* HAVE_FCHDIR */
2609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002610
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002611PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002612"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2613Change the access permissions of a file.\n\
2614\n\
2615path may always be specified as a string.\n\
2616On some platforms, path may also be specified as an open file descriptor.\n\
2617 If this functionality is unavailable, using it raises an exception.\n\
2618If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2619 and path should be relative; path will then be relative to that directory.\n\
2620If follow_symlinks is False, and the last element of the path is a symbolic\n\
2621 link, chmod will modify the symbolic link itself instead of the file the\n\
2622 link points to.\n\
2623It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2624 an open file descriptor.\n\
2625dir_fd and follow_symlinks may not be implemented on your platform.\n\
2626 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002627
Barry Warsaw53699e91996-12-10 23:23:01 +00002628static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002629posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002630{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002631 path_t path;
2632 int mode;
2633 int dir_fd = DEFAULT_DIR_FD;
2634 int follow_symlinks = 1;
2635 int result;
2636 PyObject *return_value = NULL;
2637 static char *keywords[] = {"path", "mode", "dir_fd",
2638 "follow_symlinks", NULL};
2639
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002640#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002641 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002642#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002643
Larry Hastings9cf065c2012-06-22 16:30:09 -07002644#ifdef HAVE_FCHMODAT
2645 int fchmodat_nofollow_unsupported = 0;
2646#endif
2647
2648 memset(&path, 0, sizeof(path));
2649#ifdef HAVE_FCHMOD
2650 path.allow_fd = 1;
2651#endif
2652 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2653 path_converter, &path,
2654 &mode,
2655#ifdef HAVE_FCHMODAT
2656 dir_fd_converter, &dir_fd,
2657#else
2658 dir_fd_unavailable, &dir_fd,
2659#endif
2660 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002661 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002662
2663#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2664 if (follow_symlinks_specified("chmod", follow_symlinks))
2665 goto exit;
2666#endif
2667
2668#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002669 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002670 if (path.wide)
2671 attr = GetFileAttributesW(path.wide);
2672 else
2673 attr = GetFileAttributesA(path.narrow);
2674 if (attr == 0xFFFFFFFF)
2675 result = 0;
2676 else {
2677 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002678 attr &= ~FILE_ATTRIBUTE_READONLY;
2679 else
2680 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002681 if (path.wide)
2682 result = SetFileAttributesW(path.wide, attr);
2683 else
2684 result = SetFileAttributesA(path.narrow, attr);
2685 }
2686 Py_END_ALLOW_THREADS
2687
2688 if (!result) {
2689 return_value = win32_error_object("chmod", path.object);
2690 goto exit;
2691 }
2692#else /* MS_WINDOWS */
2693 Py_BEGIN_ALLOW_THREADS
2694#ifdef HAVE_FCHMOD
2695 if (path.fd != -1)
2696 result = fchmod(path.fd, mode);
2697 else
2698#endif
2699#ifdef HAVE_LCHMOD
2700 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2701 result = lchmod(path.narrow, mode);
2702 else
2703#endif
2704#ifdef HAVE_FCHMODAT
2705 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2706 /*
2707 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2708 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002709 * and then says it isn't implemented yet.
2710 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002711 *
2712 * Once it is supported, os.chmod will automatically
2713 * support dir_fd and follow_symlinks=False. (Hopefully.)
2714 * Until then, we need to be careful what exception we raise.
2715 */
2716 result = fchmodat(dir_fd, path.narrow, mode,
2717 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2718 /*
2719 * But wait! We can't throw the exception without allowing threads,
2720 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2721 */
2722 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002723 result &&
2724 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2725 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002726 }
2727 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002728#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002729 result = chmod(path.narrow, mode);
2730 Py_END_ALLOW_THREADS
2731
2732 if (result) {
2733#ifdef HAVE_FCHMODAT
2734 if (fchmodat_nofollow_unsupported) {
2735 if (dir_fd != DEFAULT_DIR_FD)
2736 dir_fd_and_follow_symlinks_invalid("chmod",
2737 dir_fd, follow_symlinks);
2738 else
2739 follow_symlinks_specified("chmod", follow_symlinks);
2740 }
2741 else
2742#endif
2743 return_value = path_error("chmod", &path);
2744 goto exit;
2745 }
2746#endif
2747
2748 Py_INCREF(Py_None);
2749 return_value = Py_None;
2750exit:
2751 path_cleanup(&path);
2752 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002753}
2754
Larry Hastings9cf065c2012-06-22 16:30:09 -07002755
Christian Heimes4e30a842007-11-30 22:12:06 +00002756#ifdef HAVE_FCHMOD
2757PyDoc_STRVAR(posix_fchmod__doc__,
2758"fchmod(fd, mode)\n\n\
2759Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002760descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002761
2762static PyObject *
2763posix_fchmod(PyObject *self, PyObject *args)
2764{
Victor Stinner8c62be82010-05-06 00:08:46 +00002765 int fd, mode, res;
2766 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2767 return NULL;
2768 Py_BEGIN_ALLOW_THREADS
2769 res = fchmod(fd, mode);
2770 Py_END_ALLOW_THREADS
2771 if (res < 0)
2772 return posix_error();
2773 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002774}
2775#endif /* HAVE_FCHMOD */
2776
2777#ifdef HAVE_LCHMOD
2778PyDoc_STRVAR(posix_lchmod__doc__,
2779"lchmod(path, mode)\n\n\
2780Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002781affects the link itself rather than the target.\n\
2782Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002783
2784static PyObject *
2785posix_lchmod(PyObject *self, PyObject *args)
2786{
Victor Stinner8c62be82010-05-06 00:08:46 +00002787 PyObject *opath;
2788 char *path;
2789 int i;
2790 int res;
2791 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2792 &opath, &i))
2793 return NULL;
2794 path = PyBytes_AsString(opath);
2795 Py_BEGIN_ALLOW_THREADS
2796 res = lchmod(path, i);
2797 Py_END_ALLOW_THREADS
2798 if (res < 0)
2799 return posix_error_with_allocated_filename(opath);
2800 Py_DECREF(opath);
2801 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002802}
2803#endif /* HAVE_LCHMOD */
2804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002805
Thomas Wouterscf297e42007-02-23 15:07:44 +00002806#ifdef HAVE_CHFLAGS
2807PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808"chflags(path, flags, *, follow_symlinks=True)\n\n\
2809Set file flags.\n\
2810\n\
2811If follow_symlinks is False, and the last element of the path is a symbolic\n\
2812 link, chflags will change flags on the symbolic link itself instead of the\n\
2813 file the link points to.\n\
2814follow_symlinks may not be implemented on your platform. If it is\n\
2815unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002816
2817static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002818posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002819{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002820 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002821 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822 int follow_symlinks = 1;
2823 int result;
2824 PyObject *return_value;
2825 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2826
2827 memset(&path, 0, sizeof(path));
2828 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2829 path_converter, &path,
2830 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002831 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002832
2833#ifndef HAVE_LCHFLAGS
2834 if (follow_symlinks_specified("chflags", follow_symlinks))
2835 goto exit;
2836#endif
2837
Victor Stinner8c62be82010-05-06 00:08:46 +00002838 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002839#ifdef HAVE_LCHFLAGS
2840 if (!follow_symlinks)
2841 result = lchflags(path.narrow, flags);
2842 else
2843#endif
2844 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002845 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002846
2847 if (result) {
2848 return_value = path_posix_error("chflags", &path);
2849 goto exit;
2850 }
2851
2852 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002853 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002854
2855exit:
2856 path_cleanup(&path);
2857 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002858}
2859#endif /* HAVE_CHFLAGS */
2860
2861#ifdef HAVE_LCHFLAGS
2862PyDoc_STRVAR(posix_lchflags__doc__,
2863"lchflags(path, flags)\n\n\
2864Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002865This function will not follow symbolic links.\n\
2866Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002867
2868static PyObject *
2869posix_lchflags(PyObject *self, PyObject *args)
2870{
Victor Stinner8c62be82010-05-06 00:08:46 +00002871 PyObject *opath;
2872 char *path;
2873 unsigned long flags;
2874 int res;
2875 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2876 PyUnicode_FSConverter, &opath, &flags))
2877 return NULL;
2878 path = PyBytes_AsString(opath);
2879 Py_BEGIN_ALLOW_THREADS
2880 res = lchflags(path, flags);
2881 Py_END_ALLOW_THREADS
2882 if (res < 0)
2883 return posix_error_with_allocated_filename(opath);
2884 Py_DECREF(opath);
2885 Py_INCREF(Py_None);
2886 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002887}
2888#endif /* HAVE_LCHFLAGS */
2889
Martin v. Löwis244edc82001-10-04 22:44:26 +00002890#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002891PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002892"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002893Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002894
2895static PyObject *
2896posix_chroot(PyObject *self, PyObject *args)
2897{
Victor Stinner8c62be82010-05-06 00:08:46 +00002898 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002899}
2900#endif
2901
Guido van Rossum21142a01999-01-08 21:05:37 +00002902#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002903PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002904"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002905force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002906
2907static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002908posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002909{
Stefan Krah0e803b32010-11-26 16:16:47 +00002910 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002911}
2912#endif /* HAVE_FSYNC */
2913
Ross Lagerwall7807c352011-03-17 20:20:30 +02002914#ifdef HAVE_SYNC
2915PyDoc_STRVAR(posix_sync__doc__,
2916"sync()\n\n\
2917Force write of everything to disk.");
2918
2919static PyObject *
2920posix_sync(PyObject *self, PyObject *noargs)
2921{
2922 Py_BEGIN_ALLOW_THREADS
2923 sync();
2924 Py_END_ALLOW_THREADS
2925 Py_RETURN_NONE;
2926}
2927#endif
2928
Guido van Rossum21142a01999-01-08 21:05:37 +00002929#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002930
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002931#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002932extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2933#endif
2934
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002935PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002936"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002937force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002938 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002939
2940static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002941posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002942{
Stefan Krah0e803b32010-11-26 16:16:47 +00002943 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002944}
2945#endif /* HAVE_FDATASYNC */
2946
2947
Fredrik Lundh10723342000-07-10 16:38:09 +00002948#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002949PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002950"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2951Change the owner and group id of path to the numeric uid and gid.\n\
2952\n\
2953path may always be specified as a string.\n\
2954On some platforms, path may also be specified as an open file descriptor.\n\
2955 If this functionality is unavailable, using it raises an exception.\n\
2956If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2957 and path should be relative; path will then be relative to that directory.\n\
2958If follow_symlinks is False, and the last element of the path is a symbolic\n\
2959 link, chown will modify the symbolic link itself instead of the file the\n\
2960 link points to.\n\
2961It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2962 an open file descriptor.\n\
2963dir_fd and follow_symlinks may not be implemented on your platform.\n\
2964 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002965
Barry Warsaw53699e91996-12-10 23:23:01 +00002966static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002967posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002968{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002969 path_t path;
2970 long uid_l, gid_l;
2971 uid_t uid;
2972 gid_t gid;
2973 int dir_fd = DEFAULT_DIR_FD;
2974 int follow_symlinks = 1;
2975 int result;
2976 PyObject *return_value = NULL;
2977 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2978 "follow_symlinks", NULL};
2979
2980 memset(&path, 0, sizeof(path));
2981#ifdef HAVE_FCHOWN
2982 path.allow_fd = 1;
2983#endif
2984 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
2985 path_converter, &path,
2986 &uid_l, &gid_l,
2987#ifdef HAVE_FCHOWNAT
2988 dir_fd_converter, &dir_fd,
2989#else
2990 dir_fd_unavailable, &dir_fd,
2991#endif
2992 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002993 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002994
2995#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
2996 if (follow_symlinks_specified("chown", follow_symlinks))
2997 goto exit;
2998#endif
2999 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3000 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3001 goto exit;
3002
3003#ifdef __APPLE__
3004 /*
3005 * This is for Mac OS X 10.3, which doesn't have lchown.
3006 * (But we still have an lchown symbol because of weak-linking.)
3007 * It doesn't have fchownat either. So there's no possibility
3008 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003009 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003010 if ((!follow_symlinks) && (lchown == NULL)) {
3011 follow_symlinks_specified("chown", follow_symlinks);
3012 goto exit;
3013 }
3014#endif
3015
Victor Stinner8c62be82010-05-06 00:08:46 +00003016 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003017 uid = (uid_t)uid_l;
3018 gid = (uid_t)gid_l;
3019#ifdef HAVE_FCHOWN
3020 if (path.fd != -1)
3021 result = fchown(path.fd, uid, gid);
3022 else
3023#endif
3024#ifdef HAVE_LCHOWN
3025 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3026 result = lchown(path.narrow, uid, gid);
3027 else
3028#endif
3029#ifdef HAVE_FCHOWNAT
3030 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3031 result = fchownat(dir_fd, path.narrow, uid, gid,
3032 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3033 else
3034#endif
3035 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003036 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003037
3038 if (result) {
3039 return_value = path_posix_error("chown", &path);
3040 goto exit;
3041 }
3042
3043 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003044 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003045
3046exit:
3047 path_cleanup(&path);
3048 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003049}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003050#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003051
Christian Heimes4e30a842007-11-30 22:12:06 +00003052#ifdef HAVE_FCHOWN
3053PyDoc_STRVAR(posix_fchown__doc__,
3054"fchown(fd, uid, gid)\n\n\
3055Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003056fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003057
3058static PyObject *
3059posix_fchown(PyObject *self, PyObject *args)
3060{
Victor Stinner8c62be82010-05-06 00:08:46 +00003061 int fd;
3062 long uid, gid;
3063 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02003064 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003065 return NULL;
3066 Py_BEGIN_ALLOW_THREADS
3067 res = fchown(fd, (uid_t) uid, (gid_t) gid);
3068 Py_END_ALLOW_THREADS
3069 if (res < 0)
3070 return posix_error();
3071 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003072}
3073#endif /* HAVE_FCHOWN */
3074
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003075#ifdef HAVE_LCHOWN
3076PyDoc_STRVAR(posix_lchown__doc__,
3077"lchown(path, uid, gid)\n\n\
3078Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003079This function will not follow symbolic links.\n\
3080Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003081
3082static PyObject *
3083posix_lchown(PyObject *self, PyObject *args)
3084{
Victor Stinner8c62be82010-05-06 00:08:46 +00003085 PyObject *opath;
3086 char *path;
3087 long uid, gid;
3088 int res;
3089 if (!PyArg_ParseTuple(args, "O&ll:lchown",
3090 PyUnicode_FSConverter, &opath,
3091 &uid, &gid))
3092 return NULL;
3093 path = PyBytes_AsString(opath);
3094 Py_BEGIN_ALLOW_THREADS
3095 res = lchown(path, (uid_t) uid, (gid_t) gid);
3096 Py_END_ALLOW_THREADS
3097 if (res < 0)
3098 return posix_error_with_allocated_filename(opath);
3099 Py_DECREF(opath);
3100 Py_INCREF(Py_None);
3101 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003102}
3103#endif /* HAVE_LCHOWN */
3104
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003105
Guido van Rossum36bc6801995-06-14 22:54:23 +00003106#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003107static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003108posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003109{
Victor Stinner8c62be82010-05-06 00:08:46 +00003110 char buf[1026];
3111 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003112
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003113#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003114 if (!use_bytes) {
3115 wchar_t wbuf[1026];
3116 wchar_t *wbuf2 = wbuf;
3117 PyObject *resobj;
3118 DWORD len;
3119 Py_BEGIN_ALLOW_THREADS
3120 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3121 /* If the buffer is large enough, len does not include the
3122 terminating \0. If the buffer is too small, len includes
3123 the space needed for the terminator. */
3124 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
3125 wbuf2 = malloc(len * sizeof(wchar_t));
3126 if (wbuf2)
3127 len = GetCurrentDirectoryW(len, wbuf2);
3128 }
3129 Py_END_ALLOW_THREADS
3130 if (!wbuf2) {
3131 PyErr_NoMemory();
3132 return NULL;
3133 }
3134 if (!len) {
3135 if (wbuf2 != wbuf) free(wbuf2);
3136 return win32_error("getcwdu", NULL);
3137 }
3138 resobj = PyUnicode_FromWideChar(wbuf2, len);
3139 if (wbuf2 != wbuf) free(wbuf2);
3140 return resobj;
3141 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003142
3143 if (win32_warn_bytes_api())
3144 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003145#endif
3146
Victor Stinner8c62be82010-05-06 00:08:46 +00003147 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003148#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003149 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003150#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003151 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003152#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003153 Py_END_ALLOW_THREADS
3154 if (res == NULL)
3155 return posix_error();
3156 if (use_bytes)
3157 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003158 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003159}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003160
3161PyDoc_STRVAR(posix_getcwd__doc__,
3162"getcwd() -> path\n\n\
3163Return a unicode string representing the current working directory.");
3164
3165static PyObject *
3166posix_getcwd_unicode(PyObject *self)
3167{
3168 return posix_getcwd(0);
3169}
3170
3171PyDoc_STRVAR(posix_getcwdb__doc__,
3172"getcwdb() -> path\n\n\
3173Return a bytes string representing the current working directory.");
3174
3175static PyObject *
3176posix_getcwd_bytes(PyObject *self)
3177{
3178 return posix_getcwd(1);
3179}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003180#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003181
Larry Hastings9cf065c2012-06-22 16:30:09 -07003182#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3183#define HAVE_LINK 1
3184#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003185
Guido van Rossumb6775db1994-08-01 11:34:53 +00003186#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003187PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003188"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3189Create a hard link to a file.\n\
3190\n\
3191If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3192 descriptor open to a directory, and the respective path string (src or dst)\n\
3193 should be relative; the path will then be relative to that directory.\n\
3194If follow_symlinks is False, and the last element of src is a symbolic\n\
3195 link, link will create a link to the symbolic link itself instead of the\n\
3196 file the link points to.\n\
3197src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3198 platform. If they are unavailable, using them will raise a\n\
3199 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003200
Barry Warsaw53699e91996-12-10 23:23:01 +00003201static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003202posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003203{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003204 path_t src, dst;
3205 int src_dir_fd = DEFAULT_DIR_FD;
3206 int dst_dir_fd = DEFAULT_DIR_FD;
3207 int follow_symlinks = 1;
3208 PyObject *return_value = NULL;
3209 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3210 "follow_symlinks", NULL};
3211#ifdef MS_WINDOWS
3212 BOOL result;
3213#else
3214 int result;
3215#endif
3216
3217 memset(&src, 0, sizeof(src));
3218 memset(&dst, 0, sizeof(dst));
3219 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3220 path_converter, &src,
3221 path_converter, &dst,
3222 dir_fd_converter, &src_dir_fd,
3223 dir_fd_converter, &dst_dir_fd,
3224 &follow_symlinks))
3225 return NULL;
3226
3227#ifndef HAVE_LINKAT
3228 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3229 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3230 goto exit;
3231 }
3232#endif
3233
3234 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3235 PyErr_SetString(PyExc_NotImplementedError,
3236 "link: src and dst must be the same type");
3237 goto exit;
3238 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003239
Brian Curtin1b9df392010-11-24 20:24:31 +00003240#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003241 Py_BEGIN_ALLOW_THREADS
3242 if (src.wide)
3243 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3244 else
3245 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3246 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003247
Larry Hastings9cf065c2012-06-22 16:30:09 -07003248 if (!result) {
3249 return_value = win32_error_object("link", dst.object);
3250 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003251 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003252#else
3253 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003254#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003255 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3256 (dst_dir_fd != DEFAULT_DIR_FD) ||
3257 (!follow_symlinks))
3258 result = linkat(src_dir_fd, src.narrow,
3259 dst_dir_fd, dst.narrow,
3260 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3261 else
3262#endif
3263 result = link(src.narrow, dst.narrow);
3264 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003265
Larry Hastings9cf065c2012-06-22 16:30:09 -07003266 if (result) {
3267 return_value = path_error("link", &dst);
3268 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003269 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003270#endif
3271
3272 return_value = Py_None;
3273 Py_INCREF(Py_None);
3274
3275exit:
3276 path_cleanup(&src);
3277 path_cleanup(&dst);
3278 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003279}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003280#endif
3281
Brian Curtin1b9df392010-11-24 20:24:31 +00003282
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003283
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003284PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003285"listdir(path='.') -> list_of_filenames\n\n\
3286Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003287The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003288entries '.' and '..' even if they are present in the directory.\n\
3289\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003290path can be specified as either str or bytes. If path is bytes,\n\
3291 the filenames returned will also be bytes; in all other circumstances\n\
3292 the filenames returned will be str.\n\
3293On some platforms, path may also be specified as an open file descriptor;\n\
3294 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003295 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003296
Barry Warsaw53699e91996-12-10 23:23:01 +00003297static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003298posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003299{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003300 path_t path;
3301 PyObject *list = NULL;
3302 static char *keywords[] = {"path", NULL};
3303 int fd = -1;
3304
3305#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3306 PyObject *v;
3307 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3308 BOOL result;
3309 WIN32_FIND_DATA FileData;
3310 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3311 char *bufptr = namebuf;
3312 /* only claim to have space for MAX_PATH */
3313 Py_ssize_t len = sizeof(namebuf)-5;
3314 PyObject *po = NULL;
3315 wchar_t *wnamebuf = NULL;
3316#elif defined(PYOS_OS2)
3317#ifndef MAX_PATH
3318#define MAX_PATH CCHMAXPATH
3319#endif
3320 char *pt;
3321 PyObject *v;
3322 char namebuf[MAX_PATH+5];
3323 HDIR hdir = 1;
3324 ULONG srchcnt = 1;
3325 FILEFINDBUF3 ep;
3326 APIRET rc;
3327#else
3328 PyObject *v;
3329 DIR *dirp = NULL;
3330 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003331 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003332#endif
3333
3334 memset(&path, 0, sizeof(path));
3335 path.nullable = 1;
3336#ifdef HAVE_FDOPENDIR
3337 path.allow_fd = 1;
3338 path.fd = -1;
3339#endif
3340 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3341 path_converter, &path
3342 ))
3343 return NULL;
3344
Victor Stinner8c62be82010-05-06 00:08:46 +00003345 /* XXX Should redo this putting the (now four) versions of opendir
3346 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003347#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003348 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003349 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003350 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003351
Larry Hastings9cf065c2012-06-22 16:30:09 -07003352 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003353 po_wchars = L".";
3354 len = 1;
3355 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003356 po_wchars = path.wide;
3357 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003358 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003359 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003360 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3361 if (!wnamebuf) {
3362 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003363 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003364 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003365 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003366 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003367 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 if (wch != L'/' && wch != L'\\' && wch != L':')
3369 wnamebuf[len++] = L'\\';
3370 wcscpy(wnamebuf + len, L"*.*");
3371 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003372 if ((list = PyList_New(0)) == NULL) {
3373 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003374 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003375 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003376 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003377 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003378 if (hFindFile == INVALID_HANDLE_VALUE) {
3379 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003380 if (error == ERROR_FILE_NOT_FOUND)
3381 goto exit;
3382 Py_DECREF(list);
3383 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003384 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003385 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003386 }
3387 do {
3388 /* Skip over . and .. */
3389 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3390 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003391 v = PyUnicode_FromWideChar(wFileData.cFileName,
3392 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003393 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003394 Py_DECREF(list);
3395 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003396 break;
3397 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003399 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003400 Py_DECREF(list);
3401 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003402 break;
3403 }
3404 Py_DECREF(v);
3405 }
3406 Py_BEGIN_ALLOW_THREADS
3407 result = FindNextFileW(hFindFile, &wFileData);
3408 Py_END_ALLOW_THREADS
3409 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3410 it got to the end of the directory. */
3411 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003412 Py_DECREF(list);
3413 list = win32_error_unicode("FindNextFileW", wnamebuf);
3414 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003415 }
3416 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003417
Larry Hastings9cf065c2012-06-22 16:30:09 -07003418 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003419 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420 strcpy(namebuf, path.narrow);
3421 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003422 if (len > 0) {
3423 char ch = namebuf[len-1];
3424 if (ch != SEP && ch != ALTSEP && ch != ':')
3425 namebuf[len++] = '/';
3426 strcpy(namebuf + len, "*.*");
3427 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003428
Larry Hastings9cf065c2012-06-22 16:30:09 -07003429 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003431
Antoine Pitroub73caab2010-08-09 23:39:31 +00003432 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003433 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003434 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003435 if (hFindFile == INVALID_HANDLE_VALUE) {
3436 int error = GetLastError();
3437 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438 goto exit;
3439 Py_DECREF(list);
3440 list = win32_error("FindFirstFile", namebuf);
3441 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003442 }
3443 do {
3444 /* Skip over . and .. */
3445 if (strcmp(FileData.cFileName, ".") != 0 &&
3446 strcmp(FileData.cFileName, "..") != 0) {
3447 v = PyBytes_FromString(FileData.cFileName);
3448 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003449 Py_DECREF(list);
3450 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003451 break;
3452 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003454 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003455 Py_DECREF(list);
3456 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003457 break;
3458 }
3459 Py_DECREF(v);
3460 }
3461 Py_BEGIN_ALLOW_THREADS
3462 result = FindNextFile(hFindFile, &FileData);
3463 Py_END_ALLOW_THREADS
3464 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3465 it got to the end of the directory. */
3466 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003467 Py_DECREF(list);
3468 list = win32_error("FindNextFile", namebuf);
3469 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003470 }
3471 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003472
Larry Hastings9cf065c2012-06-22 16:30:09 -07003473exit:
3474 if (hFindFile != INVALID_HANDLE_VALUE) {
3475 if (FindClose(hFindFile) == FALSE) {
3476 if (list != NULL) {
3477 Py_DECREF(list);
3478 list = win32_error_object("FindClose", path.object);
3479 }
3480 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003481 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003482 if (wnamebuf)
3483 free(wnamebuf);
3484 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003485
Larry Hastings9cf065c2012-06-22 16:30:09 -07003486 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003487
Tim Peters0bb44a42000-09-15 07:44:49 +00003488#elif defined(PYOS_OS2)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489 if (path.length >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00003490 PyErr_SetString(PyExc_ValueError, "path too long");
Larry Hastings9cf065c2012-06-22 16:30:09 -07003491 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003492 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493 strcpy(namebuf, path.narrow);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003494 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003495 if (*pt == ALTSEP)
3496 *pt = SEP;
3497 if (namebuf[len-1] != SEP)
3498 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003499 strcpy(namebuf + len, "*.*");
3500
Larry Hastings9cf065c2012-06-22 16:30:09 -07003501 if ((list = PyList_New(0)) == NULL) {
3502 goto exit;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00003503 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003504
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003505 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
3506 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003507 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003508 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
3509 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
3510 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003511
3512 if (rc != NO_ERROR) {
3513 errno = ENOENT;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003514 Py_DECREF(list);
3515 list = posix_error_with_filename(path.narrow);
3516 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003517 }
3518
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003519 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003520 do {
3521 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003522 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003523 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003524
3525 strcpy(namebuf, ep.achName);
3526
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003527 /* Leave Case of Name Alone -- In Native Form */
3528 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003529
Christian Heimes72b710a2008-05-26 13:28:38 +00003530 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003531 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 Py_DECREF(list);
3533 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003534 break;
3535 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536 if (PyList_Append(list, v) != 0) {
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003537 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003538 Py_DECREF(list);
3539 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003540 break;
3541 }
3542 Py_DECREF(v);
3543 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
3544 }
3545
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546exit:
3547 path_cleanup(&path);
3548
3549 return list;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003550#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003551
Victor Stinner8c62be82010-05-06 00:08:46 +00003552 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003553#ifdef HAVE_FDOPENDIR
3554 if (path.fd != -1) {
3555 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003556 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003558 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003559
3560 if (fd == -1) {
3561 list = posix_error();
3562 goto exit;
3563 }
3564
Larry Hastingsfdaea062012-06-25 04:42:23 -07003565 return_str = 1;
3566
Larry Hastings9cf065c2012-06-22 16:30:09 -07003567 Py_BEGIN_ALLOW_THREADS
3568 dirp = fdopendir(fd);
3569 Py_END_ALLOW_THREADS
3570 }
3571 else
3572#endif
3573 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003574 char *name;
3575 if (path.narrow) {
3576 name = path.narrow;
3577 /* only return bytes if they specified a bytes object */
3578 return_str = !(PyBytes_Check(path.object));
3579 }
3580 else {
3581 name = ".";
3582 return_str = 1;
3583 }
3584
Larry Hastings9cf065c2012-06-22 16:30:09 -07003585 Py_BEGIN_ALLOW_THREADS
3586 dirp = opendir(name);
3587 Py_END_ALLOW_THREADS
3588 }
3589
3590 if (dirp == NULL) {
3591 list = path_error("listdir", &path);
3592 goto exit;
3593 }
3594 if ((list = PyList_New(0)) == NULL) {
3595 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003596 }
3597 for (;;) {
3598 errno = 0;
3599 Py_BEGIN_ALLOW_THREADS
3600 ep = readdir(dirp);
3601 Py_END_ALLOW_THREADS
3602 if (ep == NULL) {
3603 if (errno == 0) {
3604 break;
3605 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 Py_DECREF(list);
3607 list = path_error("listdir", &path);
3608 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003609 }
3610 }
3611 if (ep->d_name[0] == '.' &&
3612 (NAMLEN(ep) == 1 ||
3613 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3614 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003615 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003616 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3617 else
3618 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003619 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003620 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003621 break;
3622 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003623 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003624 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003626 break;
3627 }
3628 Py_DECREF(v);
3629 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003630
Larry Hastings9cf065c2012-06-22 16:30:09 -07003631exit:
3632 if (dirp != NULL) {
3633 Py_BEGIN_ALLOW_THREADS
3634 if (fd > -1)
3635 rewinddir(dirp);
3636 closedir(dirp);
3637 Py_END_ALLOW_THREADS
3638 }
3639
3640 path_cleanup(&path);
3641
3642 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003643
Tim Peters0bb44a42000-09-15 07:44:49 +00003644#endif /* which OS */
3645} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003646
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003647#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003648/* A helper function for abspath on win32 */
3649static PyObject *
3650posix__getfullpathname(PyObject *self, PyObject *args)
3651{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003652 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003653 char outbuf[MAX_PATH*2];
3654 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003655 PyObject *po;
3656
3657 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3658 {
3659 wchar_t *wpath;
3660 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3661 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003662 DWORD result;
3663 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003664
3665 wpath = PyUnicode_AsUnicode(po);
3666 if (wpath == NULL)
3667 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003668 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003669 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003670 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003671 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003672 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003673 if (!woutbufp)
3674 return PyErr_NoMemory();
3675 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3676 }
3677 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003678 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003679 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003680 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003681 if (woutbufp != woutbuf)
3682 free(woutbufp);
3683 return v;
3684 }
3685 /* Drop the argument parsing error as narrow strings
3686 are also valid. */
3687 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003688
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003689 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3690 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003691 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003692 if (win32_warn_bytes_api())
3693 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003694 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 outbuf, &temp)) {
3696 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003697 return NULL;
3698 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003699 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3700 return PyUnicode_Decode(outbuf, strlen(outbuf),
3701 Py_FileSystemDefaultEncoding, NULL);
3702 }
3703 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003704} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003705
Brian Curtind25aef52011-06-13 15:16:04 -05003706
Brian Curtinf5e76d02010-11-24 13:14:05 +00003707
Brian Curtind40e6f72010-07-08 21:39:08 +00003708/* A helper function for samepath on windows */
3709static PyObject *
3710posix__getfinalpathname(PyObject *self, PyObject *args)
3711{
3712 HANDLE hFile;
3713 int buf_size;
3714 wchar_t *target_path;
3715 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003716 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003717 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003718
Victor Stinnereb5657a2011-09-30 01:44:27 +02003719 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003720 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003721 path = PyUnicode_AsUnicode(po);
3722 if (path == NULL)
3723 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003724
3725 if(!check_GetFinalPathNameByHandle()) {
3726 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3727 NotImplementedError. */
3728 return PyErr_Format(PyExc_NotImplementedError,
3729 "GetFinalPathNameByHandle not available on this platform");
3730 }
3731
3732 hFile = CreateFileW(
3733 path,
3734 0, /* desired access */
3735 0, /* share mode */
3736 NULL, /* security attributes */
3737 OPEN_EXISTING,
3738 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3739 FILE_FLAG_BACKUP_SEMANTICS,
3740 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003741
Victor Stinnereb5657a2011-09-30 01:44:27 +02003742 if(hFile == INVALID_HANDLE_VALUE)
3743 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003744
3745 /* We have a good handle to the target, use it to determine the
3746 target path name. */
3747 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3748
3749 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003750 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003751
3752 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3753 if(!target_path)
3754 return PyErr_NoMemory();
3755
3756 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3757 buf_size, VOLUME_NAME_DOS);
3758 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003759 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003760
3761 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003762 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003763
3764 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003765 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003766 free(target_path);
3767 return result;
3768
3769} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003770
3771static PyObject *
3772posix__getfileinformation(PyObject *self, PyObject *args)
3773{
3774 HANDLE hFile;
3775 BY_HANDLE_FILE_INFORMATION info;
3776 int fd;
3777
3778 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3779 return NULL;
3780
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003781 if (!_PyVerify_fd(fd))
3782 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003783
3784 hFile = (HANDLE)_get_osfhandle(fd);
3785 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003786 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003787
3788 if (!GetFileInformationByHandle(hFile, &info))
3789 return win32_error("_getfileinformation", NULL);
3790
3791 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3792 info.nFileIndexHigh,
3793 info.nFileIndexLow);
3794}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003795
Brian Curtin95d028f2011-06-09 09:10:38 -05003796PyDoc_STRVAR(posix__isdir__doc__,
3797"Return true if the pathname refers to an existing directory.");
3798
Brian Curtin9c669cc2011-06-08 18:17:18 -05003799static PyObject *
3800posix__isdir(PyObject *self, PyObject *args)
3801{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003802 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003803 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003804 DWORD attributes;
3805
3806 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003807 wchar_t *wpath = PyUnicode_AsUnicode(po);
3808 if (wpath == NULL)
3809 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003810
3811 attributes = GetFileAttributesW(wpath);
3812 if (attributes == INVALID_FILE_ATTRIBUTES)
3813 Py_RETURN_FALSE;
3814 goto check;
3815 }
3816 /* Drop the argument parsing error as narrow strings
3817 are also valid. */
3818 PyErr_Clear();
3819
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003820 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003821 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003822 if (win32_warn_bytes_api())
3823 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003824 attributes = GetFileAttributesA(path);
3825 if (attributes == INVALID_FILE_ATTRIBUTES)
3826 Py_RETURN_FALSE;
3827
3828check:
3829 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3830 Py_RETURN_TRUE;
3831 else
3832 Py_RETURN_FALSE;
3833}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003834#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003835
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003836PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003837"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3838Create a directory.\n\
3839\n\
3840If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3841 and path should be relative; path will then be relative to that directory.\n\
3842dir_fd may not be implemented on your platform.\n\
3843 If it is unavailable, using it will raise a NotImplementedError.\n\
3844\n\
3845The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003846
Barry Warsaw53699e91996-12-10 23:23:01 +00003847static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003848posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003849{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003850 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003851 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003852 int dir_fd = DEFAULT_DIR_FD;
3853 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3854 PyObject *return_value = NULL;
3855 int result;
3856
3857 memset(&path, 0, sizeof(path));
3858 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3859 path_converter, &path, &mode,
3860#ifdef HAVE_MKDIRAT
3861 dir_fd_converter, &dir_fd
3862#else
3863 dir_fd_unavailable, &dir_fd
3864#endif
3865 ))
3866 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003867
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003868#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003869 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003870 if (path.wide)
3871 result = CreateDirectoryW(path.wide, NULL);
3872 else
3873 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003874 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003875
Larry Hastings9cf065c2012-06-22 16:30:09 -07003876 if (!result) {
3877 return_value = win32_error_object("mkdir", path.object);
3878 goto exit;
3879 }
3880#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003881 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003882#if HAVE_MKDIRAT
3883 if (dir_fd != DEFAULT_DIR_FD)
3884 result = mkdirat(dir_fd, path.narrow, mode);
3885 else
3886#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003887#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003888 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003889#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003890 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003891#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003892 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003893 if (result < 0) {
3894 return_value = path_error("mkdir", &path);
3895 goto exit;
3896 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003897#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003898 return_value = Py_None;
3899 Py_INCREF(Py_None);
3900exit:
3901 path_cleanup(&path);
3902 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003903}
3904
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003905
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003906/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3907#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003908#include <sys/resource.h>
3909#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003910
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003911
3912#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003913PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003914"nice(inc) -> new_priority\n\n\
3915Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003916
Barry Warsaw53699e91996-12-10 23:23:01 +00003917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003918posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003919{
Victor Stinner8c62be82010-05-06 00:08:46 +00003920 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003921
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3923 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003924
Victor Stinner8c62be82010-05-06 00:08:46 +00003925 /* There are two flavours of 'nice': one that returns the new
3926 priority (as required by almost all standards out there) and the
3927 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3928 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003929
Victor Stinner8c62be82010-05-06 00:08:46 +00003930 If we are of the nice family that returns the new priority, we
3931 need to clear errno before the call, and check if errno is filled
3932 before calling posix_error() on a returnvalue of -1, because the
3933 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003934
Victor Stinner8c62be82010-05-06 00:08:46 +00003935 errno = 0;
3936 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003937#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003938 if (value == 0)
3939 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003940#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003941 if (value == -1 && errno != 0)
3942 /* either nice() or getpriority() returned an error */
3943 return posix_error();
3944 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003945}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003946#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003947
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003948
3949#ifdef HAVE_GETPRIORITY
3950PyDoc_STRVAR(posix_getpriority__doc__,
3951"getpriority(which, who) -> current_priority\n\n\
3952Get program scheduling priority.");
3953
3954static PyObject *
3955posix_getpriority(PyObject *self, PyObject *args)
3956{
3957 int which, who, retval;
3958
3959 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3960 return NULL;
3961 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003962 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003963 if (errno != 0)
3964 return posix_error();
3965 return PyLong_FromLong((long)retval);
3966}
3967#endif /* HAVE_GETPRIORITY */
3968
3969
3970#ifdef HAVE_SETPRIORITY
3971PyDoc_STRVAR(posix_setpriority__doc__,
3972"setpriority(which, who, prio) -> None\n\n\
3973Set program scheduling priority.");
3974
3975static PyObject *
3976posix_setpriority(PyObject *self, PyObject *args)
3977{
3978 int which, who, prio, retval;
3979
3980 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3981 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003982 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003983 if (retval == -1)
3984 return posix_error();
3985 Py_RETURN_NONE;
3986}
3987#endif /* HAVE_SETPRIORITY */
3988
3989
Barry Warsaw53699e91996-12-10 23:23:01 +00003990static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003991internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003992{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003993 char *function_name = is_replace ? "replace" : "rename";
3994 path_t src;
3995 path_t dst;
3996 int src_dir_fd = DEFAULT_DIR_FD;
3997 int dst_dir_fd = DEFAULT_DIR_FD;
3998 int dir_fd_specified;
3999 PyObject *return_value = NULL;
4000 char format[24];
4001 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4002
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004003#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004004 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004005 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004006#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004007 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004008#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004009
4010 memset(&src, 0, sizeof(src));
4011 memset(&dst, 0, sizeof(dst));
4012 strcpy(format, "O&O&|$O&O&:");
4013 strcat(format, function_name);
4014 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4015 path_converter, &src,
4016 path_converter, &dst,
4017 dir_fd_converter, &src_dir_fd,
4018 dir_fd_converter, &dst_dir_fd))
4019 return NULL;
4020
4021 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4022 (dst_dir_fd != DEFAULT_DIR_FD);
4023#ifndef HAVE_RENAMEAT
4024 if (dir_fd_specified) {
4025 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4026 goto exit;
4027 }
4028#endif
4029
4030 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4031 PyErr_Format(PyExc_ValueError,
4032 "%s: src and dst must be the same type", function_name);
4033 goto exit;
4034 }
4035
4036#ifdef MS_WINDOWS
4037 Py_BEGIN_ALLOW_THREADS
4038 if (src.wide)
4039 result = MoveFileExW(src.wide, dst.wide, flags);
4040 else
4041 result = MoveFileExA(src.narrow, dst.narrow, flags);
4042 Py_END_ALLOW_THREADS
4043
4044 if (!result) {
4045 return_value = win32_error_object(function_name, dst.object);
4046 goto exit;
4047 }
4048
4049#else
4050 Py_BEGIN_ALLOW_THREADS
4051#ifdef HAVE_RENAMEAT
4052 if (dir_fd_specified)
4053 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4054 else
4055#endif
4056 result = rename(src.narrow, dst.narrow);
4057 Py_END_ALLOW_THREADS
4058
4059 if (result) {
4060 return_value = path_error(function_name, &dst);
4061 goto exit;
4062 }
4063#endif
4064
4065 Py_INCREF(Py_None);
4066 return_value = Py_None;
4067exit:
4068 path_cleanup(&src);
4069 path_cleanup(&dst);
4070 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004071}
4072
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004073PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004074"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4075Rename a file or directory.\n\
4076\n\
4077If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4078 descriptor open to a directory, and the respective path string (src or dst)\n\
4079 should be relative; the path will then be relative to that directory.\n\
4080src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4081 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004082
4083static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004084posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004085{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004086 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004087}
4088
4089PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004090"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4091Rename a file or directory, overwriting the destination.\n\
4092\n\
4093If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4094 descriptor open to a directory, and the respective path string (src or dst)\n\
4095 should be relative; the path will then be relative to that directory.\n\
4096src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4097 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004098
4099static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004100posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004101{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004102 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004103}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004104
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004105PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004106"rmdir(path, *, dir_fd=None)\n\n\
4107Remove a directory.\n\
4108\n\
4109If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4110 and path should be relative; path will then be relative to that directory.\n\
4111dir_fd may not be implemented on your platform.\n\
4112 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004113
Barry Warsaw53699e91996-12-10 23:23:01 +00004114static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004115posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004116{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004117 path_t path;
4118 int dir_fd = DEFAULT_DIR_FD;
4119 static char *keywords[] = {"path", "dir_fd", NULL};
4120 int result;
4121 PyObject *return_value = NULL;
4122
4123 memset(&path, 0, sizeof(path));
4124 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4125 path_converter, &path,
4126#ifdef HAVE_UNLINKAT
4127 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004128#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004129 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004130#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004131 ))
4132 return NULL;
4133
4134 Py_BEGIN_ALLOW_THREADS
4135#ifdef MS_WINDOWS
4136 if (path.wide)
4137 result = RemoveDirectoryW(path.wide);
4138 else
4139 result = RemoveDirectoryA(path.narrow);
4140 result = !result; /* Windows, success=1, UNIX, success=0 */
4141#else
4142#ifdef HAVE_UNLINKAT
4143 if (dir_fd != DEFAULT_DIR_FD)
4144 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4145 else
4146#endif
4147 result = rmdir(path.narrow);
4148#endif
4149 Py_END_ALLOW_THREADS
4150
4151 if (result) {
4152 return_value = path_error("rmdir", &path);
4153 goto exit;
4154 }
4155
4156 return_value = Py_None;
4157 Py_INCREF(Py_None);
4158
4159exit:
4160 path_cleanup(&path);
4161 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004162}
4163
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004164
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004165#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004166PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004167"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004168Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004169
Barry Warsaw53699e91996-12-10 23:23:01 +00004170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004171posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004172{
Victor Stinner8c62be82010-05-06 00:08:46 +00004173 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004174#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004175 wchar_t *command;
4176 if (!PyArg_ParseTuple(args, "u:system", &command))
4177 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004178
Victor Stinner8c62be82010-05-06 00:08:46 +00004179 Py_BEGIN_ALLOW_THREADS
4180 sts = _wsystem(command);
4181 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004182#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004183 PyObject *command_obj;
4184 char *command;
4185 if (!PyArg_ParseTuple(args, "O&:system",
4186 PyUnicode_FSConverter, &command_obj))
4187 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004188
Victor Stinner8c62be82010-05-06 00:08:46 +00004189 command = PyBytes_AsString(command_obj);
4190 Py_BEGIN_ALLOW_THREADS
4191 sts = system(command);
4192 Py_END_ALLOW_THREADS
4193 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004194#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004195 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004196}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004197#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004198
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004199
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004200PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004201"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004202Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004203
Barry Warsaw53699e91996-12-10 23:23:01 +00004204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004205posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004206{
Victor Stinner8c62be82010-05-06 00:08:46 +00004207 int i;
4208 if (!PyArg_ParseTuple(args, "i:umask", &i))
4209 return NULL;
4210 i = (int)umask(i);
4211 if (i < 0)
4212 return posix_error();
4213 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004214}
4215
Brian Curtind40e6f72010-07-08 21:39:08 +00004216#ifdef MS_WINDOWS
4217
4218/* override the default DeleteFileW behavior so that directory
4219symlinks can be removed with this function, the same as with
4220Unix symlinks */
4221BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4222{
4223 WIN32_FILE_ATTRIBUTE_DATA info;
4224 WIN32_FIND_DATAW find_data;
4225 HANDLE find_data_handle;
4226 int is_directory = 0;
4227 int is_link = 0;
4228
4229 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4230 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004231
Brian Curtind40e6f72010-07-08 21:39:08 +00004232 /* Get WIN32_FIND_DATA structure for the path to determine if
4233 it is a symlink */
4234 if(is_directory &&
4235 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4236 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4237
4238 if(find_data_handle != INVALID_HANDLE_VALUE) {
4239 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4240 FindClose(find_data_handle);
4241 }
4242 }
4243 }
4244
4245 if (is_directory && is_link)
4246 return RemoveDirectoryW(lpFileName);
4247
4248 return DeleteFileW(lpFileName);
4249}
4250#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004251
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004252PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004253"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004254Remove a file (same as remove()).\n\
4255\n\
4256If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4257 and path should be relative; path will then be relative to that directory.\n\
4258dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004259 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004260
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004261PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004262"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004263Remove a file (same as unlink()).\n\
4264\n\
4265If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4266 and path should be relative; path will then be relative to that directory.\n\
4267dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004268 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004269
Barry Warsaw53699e91996-12-10 23:23:01 +00004270static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004271posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004272{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004273 path_t path;
4274 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004275 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004276 int result;
4277 PyObject *return_value = NULL;
4278
4279 memset(&path, 0, sizeof(path));
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004280 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004281 path_converter, &path,
4282#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004283 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004284#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004285 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004286#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004287 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004288 return NULL;
4289
4290 Py_BEGIN_ALLOW_THREADS
4291#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004292 if (path.wide)
4293 result = Py_DeleteFileW(path.wide);
4294 else
4295 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004296 result = !result; /* Windows, success=1, UNIX, success=0 */
4297#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004298#ifdef HAVE_UNLINKAT
4299 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004300 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004301 else
4302#endif /* HAVE_UNLINKAT */
4303 result = unlink(path.narrow);
4304#endif
4305 Py_END_ALLOW_THREADS
4306
4307 if (result) {
4308 return_value = path_error("unlink", &path);
4309 goto exit;
4310 }
4311
4312 return_value = Py_None;
4313 Py_INCREF(Py_None);
4314
4315exit:
4316 path_cleanup(&path);
4317 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004318}
4319
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004320
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004321PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004322"uname() -> uname_result\n\n\
4323Return an object identifying the current operating system.\n\
4324The object behaves like a named tuple with the following fields:\n\
4325 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004326
Larry Hastings605a62d2012-06-24 04:33:36 -07004327static PyStructSequence_Field uname_result_fields[] = {
4328 {"sysname", "operating system name"},
4329 {"nodename", "name of machine on network (implementation-defined)"},
4330 {"release", "operating system release"},
4331 {"version", "operating system version"},
4332 {"machine", "hardware identifier"},
4333 {NULL}
4334};
4335
4336PyDoc_STRVAR(uname_result__doc__,
4337"uname_result: Result from os.uname().\n\n\
4338This object may be accessed either as a tuple of\n\
4339 (sysname, nodename, release, version, machine),\n\
4340or via the attributes sysname, nodename, release, version, and machine.\n\
4341\n\
4342See os.uname for more information.");
4343
4344static PyStructSequence_Desc uname_result_desc = {
4345 "uname_result", /* name */
4346 uname_result__doc__, /* doc */
4347 uname_result_fields,
4348 5
4349};
4350
4351static PyTypeObject UnameResultType;
4352
4353
4354#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004355static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004356posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004357{
Victor Stinner8c62be82010-05-06 00:08:46 +00004358 struct utsname u;
4359 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004360 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004361
Victor Stinner8c62be82010-05-06 00:08:46 +00004362 Py_BEGIN_ALLOW_THREADS
4363 res = uname(&u);
4364 Py_END_ALLOW_THREADS
4365 if (res < 0)
4366 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004367
4368 value = PyStructSequence_New(&UnameResultType);
4369 if (value == NULL)
4370 return NULL;
4371
4372#define SET(i, field) \
4373 { \
4374 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4375 if (!o) { \
4376 Py_DECREF(value); \
4377 return NULL; \
4378 } \
4379 PyStructSequence_SET_ITEM(value, i, o); \
4380 } \
4381
4382 SET(0, u.sysname);
4383 SET(1, u.nodename);
4384 SET(2, u.release);
4385 SET(3, u.version);
4386 SET(4, u.machine);
4387
4388#undef SET
4389
4390 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004391}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004392#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004393
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004394
Larry Hastings9cf065c2012-06-22 16:30:09 -07004395PyDoc_STRVAR(posix_utime__doc__,
4396"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4397Set the access and modified time of path.\n\
4398\n\
4399path may always be specified as a string.\n\
4400On some platforms, path may also be specified as an open file descriptor.\n\
4401 If this functionality is unavailable, using it raises an exception.\n\
4402\n\
4403If times is not None, it must be a tuple (atime, mtime);\n\
4404 atime and mtime should be expressed as float seconds since the epoch.\n\
4405If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4406 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4407 since the epoch.\n\
4408If both times and ns are None, utime uses the current time.\n\
4409Specifying tuples for both times and ns is an error.\n\
4410\n\
4411If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4412 and path should be relative; path will then be relative to that directory.\n\
4413If follow_symlinks is False, and the last element of the path is a symbolic\n\
4414 link, utime will modify the symbolic link itself instead of the file the\n\
4415 link points to.\n\
4416It is an error to use dir_fd or follow_symlinks when specifying path\n\
4417 as an open file descriptor.\n\
4418dir_fd and follow_symlinks may not be available on your platform.\n\
4419 If they are unavailable, using them will raise a NotImplementedError.");
4420
4421typedef struct {
4422 int now;
4423 time_t atime_s;
4424 long atime_ns;
4425 time_t mtime_s;
4426 long mtime_ns;
4427} utime_t;
4428
4429/*
4430 * these macros assume that "utime" is a pointer to a utime_t
4431 * they also intentionally leak the declaration of a pointer named "time"
4432 */
4433#define UTIME_TO_TIMESPEC \
4434 struct timespec ts[2]; \
4435 struct timespec *time; \
4436 if (utime->now) \
4437 time = NULL; \
4438 else { \
4439 ts[0].tv_sec = utime->atime_s; \
4440 ts[0].tv_nsec = utime->atime_ns; \
4441 ts[1].tv_sec = utime->mtime_s; \
4442 ts[1].tv_nsec = utime->mtime_ns; \
4443 time = ts; \
4444 } \
4445
4446#define UTIME_TO_TIMEVAL \
4447 struct timeval tv[2]; \
4448 struct timeval *time; \
4449 if (utime->now) \
4450 time = NULL; \
4451 else { \
4452 tv[0].tv_sec = utime->atime_s; \
4453 tv[0].tv_usec = utime->atime_ns / 1000; \
4454 tv[1].tv_sec = utime->mtime_s; \
4455 tv[1].tv_usec = utime->mtime_ns / 1000; \
4456 time = tv; \
4457 } \
4458
4459#define UTIME_TO_UTIMBUF \
4460 struct utimbuf u[2]; \
4461 struct utimbuf *time; \
4462 if (utime->now) \
4463 time = NULL; \
4464 else { \
4465 u.actime = utime->atime_s; \
4466 u.modtime = utime->mtime_s; \
4467 time = u; \
4468 }
4469
4470#define UTIME_TO_TIME_T \
4471 time_t timet[2]; \
4472 struct timet time; \
4473 if (utime->now) \
4474 time = NULL; \
4475 else { \
4476 timet[0] = utime->atime_s; \
4477 timet[1] = utime->mtime_s; \
4478 time = &timet; \
4479 } \
4480
4481
4482#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4483
4484#if UTIME_HAVE_DIR_FD
4485
4486static int
4487utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4488{
4489#ifdef HAVE_UTIMENSAT
4490 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4491 UTIME_TO_TIMESPEC;
4492 return utimensat(dir_fd, path, time, flags);
4493#elif defined(HAVE_FUTIMESAT)
4494 UTIME_TO_TIMEVAL;
4495 /*
4496 * follow_symlinks will never be false here;
4497 * we only allow !follow_symlinks and dir_fd together
4498 * if we have utimensat()
4499 */
4500 assert(follow_symlinks);
4501 return futimesat(dir_fd, path, time);
4502#endif
4503}
4504
4505#endif
4506
4507#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4508
4509#if UTIME_HAVE_FD
4510
4511static int
4512utime_fd(utime_t *utime, int fd)
4513{
4514#ifdef HAVE_FUTIMENS
4515 UTIME_TO_TIMESPEC;
4516 return futimens(fd, time);
4517#else
4518 UTIME_TO_TIMEVAL;
4519 return futimes(fd, time);
4520#endif
4521}
4522
4523#endif
4524
4525
4526#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4527 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4528
4529#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4530
4531static int
4532utime_nofollow_symlinks(utime_t *utime, char *path)
4533{
4534#ifdef HAVE_UTIMENSAT
4535 UTIME_TO_TIMESPEC;
4536 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4537#else
4538 UTIME_TO_TIMEVAL;
4539 return lutimes(path, time);
4540#endif
4541}
4542
4543#endif
4544
4545#ifndef MS_WINDOWS
4546
4547static int
4548utime_default(utime_t *utime, char *path)
4549{
4550#ifdef HAVE_UTIMENSAT
4551 UTIME_TO_TIMESPEC;
4552 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4553#elif defined(HAVE_UTIMES)
4554 UTIME_TO_TIMEVAL;
4555 return utimes(path, time);
4556#elif defined(HAVE_UTIME_H)
4557 UTIME_TO_UTIMBUF;
4558 return utime(path, time);
4559#else
4560 UTIME_TO_TIME_T;
4561 return utime(path, time);
4562#endif
4563}
4564
4565#endif
4566
Larry Hastings76ad59b2012-05-03 00:30:07 -07004567static int
4568split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4569{
4570 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004571 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004572 divmod = PyNumber_Divmod(py_long, billion);
4573 if (!divmod)
4574 goto exit;
4575 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4576 if ((*s == -1) && PyErr_Occurred())
4577 goto exit;
4578 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004579 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004580 goto exit;
4581
4582 result = 1;
4583exit:
4584 Py_XDECREF(divmod);
4585 return result;
4586}
4587
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588static PyObject *
4589posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004590{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004591 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004592 PyObject *times = NULL;
4593 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004594 int dir_fd = DEFAULT_DIR_FD;
4595 int follow_symlinks = 1;
4596 char *keywords[] = {"path", "times", "ns", "dir_fd",
4597 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004598
Larry Hastings9cf065c2012-06-22 16:30:09 -07004599 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004600
Larry Hastings9cf065c2012-06-22 16:30:09 -07004601#ifdef MS_WINDOWS
4602 HANDLE hFile;
4603 FILETIME atime, mtime;
4604#else
4605 int result;
4606#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004607
Larry Hastings9cf065c2012-06-22 16:30:09 -07004608 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004609
Larry Hastings9cf065c2012-06-22 16:30:09 -07004610 memset(&path, 0, sizeof(path));
4611#if UTIME_HAVE_FD
4612 path.allow_fd = 1;
4613#endif
4614 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4615 "O&|O$OO&p:utime", keywords,
4616 path_converter, &path,
4617 &times, &ns,
4618#if UTIME_HAVE_DIR_FD
4619 dir_fd_converter, &dir_fd,
4620#else
4621 dir_fd_unavailable, &dir_fd,
4622#endif
4623 &follow_symlinks
4624 ))
4625 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004626
Larry Hastings9cf065c2012-06-22 16:30:09 -07004627 if (times && (times != Py_None) && ns) {
4628 PyErr_SetString(PyExc_ValueError,
4629 "utime: you may specify either 'times'"
4630 " or 'ns' but not both");
4631 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004632 }
4633
4634 if (times && (times != Py_None)) {
4635 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004636 PyErr_SetString(PyExc_TypeError,
4637 "utime: 'times' must be either"
4638 " a tuple of two ints or None");
4639 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004640 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004642 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004643 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004644 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004645 &utime.mtime_s, &utime.mtime_ns) == -1) {
4646 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004647 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004648 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004650 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004651 PyErr_SetString(PyExc_TypeError,
4652 "utime: 'ns' must be a tuple of two ints");
4653 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004654 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004655 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004656 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004657 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004658 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004659 &utime.mtime_s, &utime.mtime_ns)) {
4660 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004661 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004662 }
4663 else {
4664 /* times and ns are both None/unspecified. use "now". */
4665 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004666 }
4667
Larry Hastings9cf065c2012-06-22 16:30:09 -07004668#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4669 if (follow_symlinks_specified("utime", follow_symlinks))
4670 goto exit;
4671#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004672
Larry Hastings9cf065c2012-06-22 16:30:09 -07004673 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4674 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4675 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4676 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004677
Larry Hastings9cf065c2012-06-22 16:30:09 -07004678#if !defined(HAVE_UTIMENSAT)
4679 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004680 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004681 "utime: cannot use dir_fd and follow_symlinks "
4682 "together on this platform");
4683 goto exit;
4684 }
4685#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004686
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004687#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004688 Py_BEGIN_ALLOW_THREADS
4689 if (path.wide)
4690 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004691 NULL, OPEN_EXISTING,
4692 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004693 else
4694 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004695 NULL, OPEN_EXISTING,
4696 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004697 Py_END_ALLOW_THREADS
4698 if (hFile == INVALID_HANDLE_VALUE) {
4699 win32_error_object("utime", path.object);
4700 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004701 }
4702
Larry Hastings9cf065c2012-06-22 16:30:09 -07004703 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004704 SYSTEMTIME now;
4705 GetSystemTime(&now);
4706 if (!SystemTimeToFileTime(&now, &mtime) ||
4707 !SystemTimeToFileTime(&now, &atime)) {
4708 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004709 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004710 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004711 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004712 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004713 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4714 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004715 }
4716 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4717 /* Avoid putting the file name into the error here,
4718 as that may confuse the user into believing that
4719 something is wrong with the file, when it also
4720 could be the time stamp that gives a problem. */
4721 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004723 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004724#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004725 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004726
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4728 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4729 result = utime_nofollow_symlinks(&utime, path.narrow);
4730 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004731#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732
4733#if UTIME_HAVE_DIR_FD
4734 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4735 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4736 else
4737#endif
4738
4739#if UTIME_HAVE_FD
4740 if (path.fd != -1)
4741 result = utime_fd(&utime, path.fd);
4742 else
4743#endif
4744
4745 result = utime_default(&utime, path.narrow);
4746
4747 Py_END_ALLOW_THREADS
4748
4749 if (result < 0) {
4750 /* see previous comment about not putting filename in error here */
4751 return_value = posix_error();
4752 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004753 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004754
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004755#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004756
4757 Py_INCREF(Py_None);
4758 return_value = Py_None;
4759
4760exit:
4761 path_cleanup(&path);
4762#ifdef MS_WINDOWS
4763 if (hFile != INVALID_HANDLE_VALUE)
4764 CloseHandle(hFile);
4765#endif
4766 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004767}
4768
Guido van Rossum3b066191991-06-04 19:40:25 +00004769/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004770
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004771PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004772"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004773Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004774
Barry Warsaw53699e91996-12-10 23:23:01 +00004775static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004776posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004777{
Victor Stinner8c62be82010-05-06 00:08:46 +00004778 int sts;
4779 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4780 return NULL;
4781 _exit(sts);
4782 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004783}
4784
Martin v. Löwis114619e2002-10-07 06:44:21 +00004785#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4786static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004787free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004788{
Victor Stinner8c62be82010-05-06 00:08:46 +00004789 Py_ssize_t i;
4790 for (i = 0; i < count; i++)
4791 PyMem_Free(array[i]);
4792 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004793}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004794
Antoine Pitrou69f71142009-05-24 21:25:49 +00004795static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004796int fsconvert_strdup(PyObject *o, char**out)
4797{
Victor Stinner8c62be82010-05-06 00:08:46 +00004798 PyObject *bytes;
4799 Py_ssize_t size;
4800 if (!PyUnicode_FSConverter(o, &bytes))
4801 return 0;
4802 size = PyBytes_GET_SIZE(bytes);
4803 *out = PyMem_Malloc(size+1);
4804 if (!*out)
4805 return 0;
4806 memcpy(*out, PyBytes_AsString(bytes), size+1);
4807 Py_DECREF(bytes);
4808 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004809}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004810#endif
4811
Ross Lagerwall7807c352011-03-17 20:20:30 +02004812#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004813static char**
4814parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4815{
Victor Stinner8c62be82010-05-06 00:08:46 +00004816 char **envlist;
4817 Py_ssize_t i, pos, envc;
4818 PyObject *keys=NULL, *vals=NULL;
4819 PyObject *key, *val, *key2, *val2;
4820 char *p, *k, *v;
4821 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004822
Victor Stinner8c62be82010-05-06 00:08:46 +00004823 i = PyMapping_Size(env);
4824 if (i < 0)
4825 return NULL;
4826 envlist = PyMem_NEW(char *, i + 1);
4827 if (envlist == NULL) {
4828 PyErr_NoMemory();
4829 return NULL;
4830 }
4831 envc = 0;
4832 keys = PyMapping_Keys(env);
4833 vals = PyMapping_Values(env);
4834 if (!keys || !vals)
4835 goto error;
4836 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4837 PyErr_Format(PyExc_TypeError,
4838 "env.keys() or env.values() is not a list");
4839 goto error;
4840 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004841
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 for (pos = 0; pos < i; pos++) {
4843 key = PyList_GetItem(keys, pos);
4844 val = PyList_GetItem(vals, pos);
4845 if (!key || !val)
4846 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004847
Victor Stinner8c62be82010-05-06 00:08:46 +00004848 if (PyUnicode_FSConverter(key, &key2) == 0)
4849 goto error;
4850 if (PyUnicode_FSConverter(val, &val2) == 0) {
4851 Py_DECREF(key2);
4852 goto error;
4853 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004854
4855#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004856 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4857 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004858#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004859 k = PyBytes_AsString(key2);
4860 v = PyBytes_AsString(val2);
4861 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004862
Victor Stinner8c62be82010-05-06 00:08:46 +00004863 p = PyMem_NEW(char, len);
4864 if (p == NULL) {
4865 PyErr_NoMemory();
4866 Py_DECREF(key2);
4867 Py_DECREF(val2);
4868 goto error;
4869 }
4870 PyOS_snprintf(p, len, "%s=%s", k, v);
4871 envlist[envc++] = p;
4872 Py_DECREF(key2);
4873 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004874#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004875 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004876#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004877 }
4878 Py_DECREF(vals);
4879 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004880
Victor Stinner8c62be82010-05-06 00:08:46 +00004881 envlist[envc] = 0;
4882 *envc_ptr = envc;
4883 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004884
4885error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004886 Py_XDECREF(keys);
4887 Py_XDECREF(vals);
4888 while (--envc >= 0)
4889 PyMem_DEL(envlist[envc]);
4890 PyMem_DEL(envlist);
4891 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004892}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004893
Ross Lagerwall7807c352011-03-17 20:20:30 +02004894static char**
4895parse_arglist(PyObject* argv, Py_ssize_t *argc)
4896{
4897 int i;
4898 char **argvlist = PyMem_NEW(char *, *argc+1);
4899 if (argvlist == NULL) {
4900 PyErr_NoMemory();
4901 return NULL;
4902 }
4903 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004904 PyObject* item = PySequence_ITEM(argv, i);
4905 if (item == NULL)
4906 goto fail;
4907 if (!fsconvert_strdup(item, &argvlist[i])) {
4908 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004909 goto fail;
4910 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004911 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004912 }
4913 argvlist[*argc] = NULL;
4914 return argvlist;
4915fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004916 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004917 free_string_array(argvlist, *argc);
4918 return NULL;
4919}
4920#endif
4921
4922#ifdef HAVE_EXECV
4923PyDoc_STRVAR(posix_execv__doc__,
4924"execv(path, args)\n\n\
4925Execute an executable path with arguments, replacing current process.\n\
4926\n\
4927 path: path of executable file\n\
4928 args: tuple or list of strings");
4929
4930static PyObject *
4931posix_execv(PyObject *self, PyObject *args)
4932{
4933 PyObject *opath;
4934 char *path;
4935 PyObject *argv;
4936 char **argvlist;
4937 Py_ssize_t argc;
4938
4939 /* execv has two arguments: (path, argv), where
4940 argv is a list or tuple of strings. */
4941
4942 if (!PyArg_ParseTuple(args, "O&O:execv",
4943 PyUnicode_FSConverter,
4944 &opath, &argv))
4945 return NULL;
4946 path = PyBytes_AsString(opath);
4947 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4948 PyErr_SetString(PyExc_TypeError,
4949 "execv() arg 2 must be a tuple or list");
4950 Py_DECREF(opath);
4951 return NULL;
4952 }
4953 argc = PySequence_Size(argv);
4954 if (argc < 1) {
4955 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4956 Py_DECREF(opath);
4957 return NULL;
4958 }
4959
4960 argvlist = parse_arglist(argv, &argc);
4961 if (argvlist == NULL) {
4962 Py_DECREF(opath);
4963 return NULL;
4964 }
4965
4966 execv(path, argvlist);
4967
4968 /* If we get here it's definitely an error */
4969
4970 free_string_array(argvlist, argc);
4971 Py_DECREF(opath);
4972 return posix_error();
4973}
4974
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004975PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004976"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004977Execute a path with arguments and environment, replacing current process.\n\
4978\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004979 path: path of executable file\n\
4980 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004981 env: dictionary of strings mapping to strings\n\
4982\n\
4983On some platforms, you may specify an open file descriptor for path;\n\
4984 execve will execute the program the file descriptor is open to.\n\
4985 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004986
Barry Warsaw53699e91996-12-10 23:23:01 +00004987static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004988posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004989{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004990 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004991 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004992 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004993 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004994 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004995 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004996
Victor Stinner8c62be82010-05-06 00:08:46 +00004997 /* execve has three arguments: (path, argv, env), where
4998 argv is a list or tuple of strings and env is a dictionary
4999 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005000
Larry Hastings9cf065c2012-06-22 16:30:09 -07005001 memset(&path, 0, sizeof(path));
5002#ifdef HAVE_FEXECVE
5003 path.allow_fd = 1;
5004#endif
5005 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5006 path_converter, &path,
5007 &argv, &env
5008 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005009 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005010
Ross Lagerwall7807c352011-03-17 20:20:30 +02005011 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005012 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005013 "execve: argv must be a tuple or list");
5014 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005015 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005016 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005017 if (!PyMapping_Check(env)) {
5018 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005019 "execve: environment must be a mapping object");
5020 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005021 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005022
Ross Lagerwall7807c352011-03-17 20:20:30 +02005023 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005025 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005026 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005027
Victor Stinner8c62be82010-05-06 00:08:46 +00005028 envlist = parse_envlist(env, &envc);
5029 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005030 goto fail;
5031
Larry Hastings9cf065c2012-06-22 16:30:09 -07005032#ifdef HAVE_FEXECVE
5033 if (path.fd > -1)
5034 fexecve(path.fd, argvlist, envlist);
5035 else
5036#endif
5037 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005038
5039 /* If we get here it's definitely an error */
5040
Larry Hastings9cf065c2012-06-22 16:30:09 -07005041 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005042
5043 while (--envc >= 0)
5044 PyMem_DEL(envlist[envc]);
5045 PyMem_DEL(envlist);
5046 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005047 if (argvlist)
5048 free_string_array(argvlist, argc);
5049 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005050 return NULL;
5051}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005052#endif /* HAVE_EXECV */
5053
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005054
Guido van Rossuma1065681999-01-25 23:20:23 +00005055#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005056PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005057"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005058Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005059\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005060 mode: mode of process creation\n\
5061 path: path of executable file\n\
5062 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005063
5064static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005065posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005066{
Victor Stinner8c62be82010-05-06 00:08:46 +00005067 PyObject *opath;
5068 char *path;
5069 PyObject *argv;
5070 char **argvlist;
5071 int mode, i;
5072 Py_ssize_t argc;
5073 Py_intptr_t spawnval;
5074 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005075
Victor Stinner8c62be82010-05-06 00:08:46 +00005076 /* spawnv has three arguments: (mode, path, argv), where
5077 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005078
Victor Stinner8c62be82010-05-06 00:08:46 +00005079 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5080 PyUnicode_FSConverter,
5081 &opath, &argv))
5082 return NULL;
5083 path = PyBytes_AsString(opath);
5084 if (PyList_Check(argv)) {
5085 argc = PyList_Size(argv);
5086 getitem = PyList_GetItem;
5087 }
5088 else if (PyTuple_Check(argv)) {
5089 argc = PyTuple_Size(argv);
5090 getitem = PyTuple_GetItem;
5091 }
5092 else {
5093 PyErr_SetString(PyExc_TypeError,
5094 "spawnv() arg 2 must be a tuple or list");
5095 Py_DECREF(opath);
5096 return NULL;
5097 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005098
Victor Stinner8c62be82010-05-06 00:08:46 +00005099 argvlist = PyMem_NEW(char *, argc+1);
5100 if (argvlist == NULL) {
5101 Py_DECREF(opath);
5102 return PyErr_NoMemory();
5103 }
5104 for (i = 0; i < argc; i++) {
5105 if (!fsconvert_strdup((*getitem)(argv, i),
5106 &argvlist[i])) {
5107 free_string_array(argvlist, i);
5108 PyErr_SetString(
5109 PyExc_TypeError,
5110 "spawnv() arg 2 must contain only strings");
5111 Py_DECREF(opath);
5112 return NULL;
5113 }
5114 }
5115 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005116
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005117#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005118 Py_BEGIN_ALLOW_THREADS
5119 spawnval = spawnv(mode, path, argvlist);
5120 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005121#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005122 if (mode == _OLD_P_OVERLAY)
5123 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005124
Victor Stinner8c62be82010-05-06 00:08:46 +00005125 Py_BEGIN_ALLOW_THREADS
5126 spawnval = _spawnv(mode, path, argvlist);
5127 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005128#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005129
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 free_string_array(argvlist, argc);
5131 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005132
Victor Stinner8c62be82010-05-06 00:08:46 +00005133 if (spawnval == -1)
5134 return posix_error();
5135 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005136#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005137 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005138#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005139 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005140#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005141}
5142
5143
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005144PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005145"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005146Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005147\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005148 mode: mode of process creation\n\
5149 path: path of executable file\n\
5150 args: tuple or list of arguments\n\
5151 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005152
5153static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005154posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005155{
Victor Stinner8c62be82010-05-06 00:08:46 +00005156 PyObject *opath;
5157 char *path;
5158 PyObject *argv, *env;
5159 char **argvlist;
5160 char **envlist;
5161 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005162 int mode;
5163 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 Py_intptr_t spawnval;
5165 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5166 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005167
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 /* spawnve has four arguments: (mode, path, argv, env), where
5169 argv is a list or tuple of strings and env is a dictionary
5170 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005171
Victor Stinner8c62be82010-05-06 00:08:46 +00005172 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5173 PyUnicode_FSConverter,
5174 &opath, &argv, &env))
5175 return NULL;
5176 path = PyBytes_AsString(opath);
5177 if (PyList_Check(argv)) {
5178 argc = PyList_Size(argv);
5179 getitem = PyList_GetItem;
5180 }
5181 else if (PyTuple_Check(argv)) {
5182 argc = PyTuple_Size(argv);
5183 getitem = PyTuple_GetItem;
5184 }
5185 else {
5186 PyErr_SetString(PyExc_TypeError,
5187 "spawnve() arg 2 must be a tuple or list");
5188 goto fail_0;
5189 }
5190 if (!PyMapping_Check(env)) {
5191 PyErr_SetString(PyExc_TypeError,
5192 "spawnve() arg 3 must be a mapping object");
5193 goto fail_0;
5194 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005195
Victor Stinner8c62be82010-05-06 00:08:46 +00005196 argvlist = PyMem_NEW(char *, argc+1);
5197 if (argvlist == NULL) {
5198 PyErr_NoMemory();
5199 goto fail_0;
5200 }
5201 for (i = 0; i < argc; i++) {
5202 if (!fsconvert_strdup((*getitem)(argv, i),
5203 &argvlist[i]))
5204 {
5205 lastarg = i;
5206 goto fail_1;
5207 }
5208 }
5209 lastarg = argc;
5210 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005211
Victor Stinner8c62be82010-05-06 00:08:46 +00005212 envlist = parse_envlist(env, &envc);
5213 if (envlist == NULL)
5214 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005215
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005216#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005217 Py_BEGIN_ALLOW_THREADS
5218 spawnval = spawnve(mode, path, argvlist, envlist);
5219 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005220#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005221 if (mode == _OLD_P_OVERLAY)
5222 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005223
Victor Stinner8c62be82010-05-06 00:08:46 +00005224 Py_BEGIN_ALLOW_THREADS
5225 spawnval = _spawnve(mode, path, argvlist, envlist);
5226 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005227#endif
Tim Peters25059d32001-12-07 20:35:43 +00005228
Victor Stinner8c62be82010-05-06 00:08:46 +00005229 if (spawnval == -1)
5230 (void) posix_error();
5231 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005232#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005233 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005234#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005235 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005236#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005237
Victor Stinner8c62be82010-05-06 00:08:46 +00005238 while (--envc >= 0)
5239 PyMem_DEL(envlist[envc]);
5240 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005241 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005242 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005243 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005244 Py_DECREF(opath);
5245 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005246}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005247
5248/* OS/2 supports spawnvp & spawnvpe natively */
5249#if defined(PYOS_OS2)
5250PyDoc_STRVAR(posix_spawnvp__doc__,
5251"spawnvp(mode, file, args)\n\n\
5252Execute the program 'file' in a new process, using the environment\n\
5253search path to find the file.\n\
5254\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005255 mode: mode of process creation\n\
5256 file: executable file name\n\
5257 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005258
5259static PyObject *
5260posix_spawnvp(PyObject *self, PyObject *args)
5261{
Victor Stinner8c62be82010-05-06 00:08:46 +00005262 PyObject *opath;
5263 char *path;
5264 PyObject *argv;
5265 char **argvlist;
5266 int mode, i, argc;
5267 Py_intptr_t spawnval;
5268 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005269
Victor Stinner8c62be82010-05-06 00:08:46 +00005270 /* spawnvp has three arguments: (mode, path, argv), where
5271 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005272
Victor Stinner8c62be82010-05-06 00:08:46 +00005273 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5274 PyUnicode_FSConverter,
5275 &opath, &argv))
5276 return NULL;
5277 path = PyBytes_AsString(opath);
5278 if (PyList_Check(argv)) {
5279 argc = PyList_Size(argv);
5280 getitem = PyList_GetItem;
5281 }
5282 else if (PyTuple_Check(argv)) {
5283 argc = PyTuple_Size(argv);
5284 getitem = PyTuple_GetItem;
5285 }
5286 else {
5287 PyErr_SetString(PyExc_TypeError,
5288 "spawnvp() arg 2 must be a tuple or list");
5289 Py_DECREF(opath);
5290 return NULL;
5291 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005292
Victor Stinner8c62be82010-05-06 00:08:46 +00005293 argvlist = PyMem_NEW(char *, argc+1);
5294 if (argvlist == NULL) {
5295 Py_DECREF(opath);
5296 return PyErr_NoMemory();
5297 }
5298 for (i = 0; i < argc; i++) {
5299 if (!fsconvert_strdup((*getitem)(argv, i),
5300 &argvlist[i])) {
5301 free_string_array(argvlist, i);
5302 PyErr_SetString(
5303 PyExc_TypeError,
5304 "spawnvp() arg 2 must contain only strings");
5305 Py_DECREF(opath);
5306 return NULL;
5307 }
5308 }
5309 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005310
Victor Stinner8c62be82010-05-06 00:08:46 +00005311 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005312#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005313 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005314#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005316#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005317 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005318
Victor Stinner8c62be82010-05-06 00:08:46 +00005319 free_string_array(argvlist, argc);
5320 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005321
Victor Stinner8c62be82010-05-06 00:08:46 +00005322 if (spawnval == -1)
5323 return posix_error();
5324 else
5325 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005326}
5327
5328
5329PyDoc_STRVAR(posix_spawnvpe__doc__,
5330"spawnvpe(mode, file, args, env)\n\n\
5331Execute the program 'file' in a new process, using the environment\n\
5332search path to find the file.\n\
5333\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005334 mode: mode of process creation\n\
5335 file: executable file name\n\
5336 args: tuple or list of arguments\n\
5337 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005338
5339static PyObject *
5340posix_spawnvpe(PyObject *self, PyObject *args)
5341{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005342 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005343 char *path;
5344 PyObject *argv, *env;
5345 char **argvlist;
5346 char **envlist;
5347 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005348 int mode;
5349 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005350 Py_intptr_t spawnval;
5351 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5352 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005353
Victor Stinner8c62be82010-05-06 00:08:46 +00005354 /* spawnvpe has four arguments: (mode, path, argv, env), where
5355 argv is a list or tuple of strings and env is a dictionary
5356 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005357
Victor Stinner8c62be82010-05-06 00:08:46 +00005358 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5359 PyUnicode_FSConverter,
5360 &opath, &argv, &env))
5361 return NULL;
5362 path = PyBytes_AsString(opath);
5363 if (PyList_Check(argv)) {
5364 argc = PyList_Size(argv);
5365 getitem = PyList_GetItem;
5366 }
5367 else if (PyTuple_Check(argv)) {
5368 argc = PyTuple_Size(argv);
5369 getitem = PyTuple_GetItem;
5370 }
5371 else {
5372 PyErr_SetString(PyExc_TypeError,
5373 "spawnvpe() arg 2 must be a tuple or list");
5374 goto fail_0;
5375 }
5376 if (!PyMapping_Check(env)) {
5377 PyErr_SetString(PyExc_TypeError,
5378 "spawnvpe() arg 3 must be a mapping object");
5379 goto fail_0;
5380 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005381
Victor Stinner8c62be82010-05-06 00:08:46 +00005382 argvlist = PyMem_NEW(char *, argc+1);
5383 if (argvlist == NULL) {
5384 PyErr_NoMemory();
5385 goto fail_0;
5386 }
5387 for (i = 0; i < argc; i++) {
5388 if (!fsconvert_strdup((*getitem)(argv, i),
5389 &argvlist[i]))
5390 {
5391 lastarg = i;
5392 goto fail_1;
5393 }
5394 }
5395 lastarg = argc;
5396 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005397
Victor Stinner8c62be82010-05-06 00:08:46 +00005398 envlist = parse_envlist(env, &envc);
5399 if (envlist == NULL)
5400 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005401
Victor Stinner8c62be82010-05-06 00:08:46 +00005402 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005403#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005404 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005405#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005406 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005407#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005408 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005409
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 if (spawnval == -1)
5411 (void) posix_error();
5412 else
5413 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005414
Victor Stinner8c62be82010-05-06 00:08:46 +00005415 while (--envc >= 0)
5416 PyMem_DEL(envlist[envc]);
5417 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005418 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005419 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005420 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005421 Py_DECREF(opath);
5422 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005423}
5424#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005425#endif /* HAVE_SPAWNV */
5426
5427
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005428#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005429PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005430"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005431Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5432\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005433Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005434
5435static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005436posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005437{
Victor Stinner8c62be82010-05-06 00:08:46 +00005438 pid_t pid;
5439 int result = 0;
5440 _PyImport_AcquireLock();
5441 pid = fork1();
5442 if (pid == 0) {
5443 /* child: this clobbers and resets the import lock. */
5444 PyOS_AfterFork();
5445 } else {
5446 /* parent: release the import lock. */
5447 result = _PyImport_ReleaseLock();
5448 }
5449 if (pid == -1)
5450 return posix_error();
5451 if (result < 0) {
5452 /* Don't clobber the OSError if the fork failed. */
5453 PyErr_SetString(PyExc_RuntimeError,
5454 "not holding the import lock");
5455 return NULL;
5456 }
5457 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005458}
5459#endif
5460
5461
Guido van Rossumad0ee831995-03-01 10:34:45 +00005462#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005463PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005464"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005465Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005466Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005467
Barry Warsaw53699e91996-12-10 23:23:01 +00005468static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005469posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005470{
Victor Stinner8c62be82010-05-06 00:08:46 +00005471 pid_t pid;
5472 int result = 0;
5473 _PyImport_AcquireLock();
5474 pid = fork();
5475 if (pid == 0) {
5476 /* child: this clobbers and resets the import lock. */
5477 PyOS_AfterFork();
5478 } else {
5479 /* parent: release the import lock. */
5480 result = _PyImport_ReleaseLock();
5481 }
5482 if (pid == -1)
5483 return posix_error();
5484 if (result < 0) {
5485 /* Don't clobber the OSError if the fork failed. */
5486 PyErr_SetString(PyExc_RuntimeError,
5487 "not holding the import lock");
5488 return NULL;
5489 }
5490 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005491}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005492#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005493
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005494#ifdef HAVE_SCHED_H
5495
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005496#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5497
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005498PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5499"sched_get_priority_max(policy)\n\n\
5500Get the maximum scheduling priority for *policy*.");
5501
5502static PyObject *
5503posix_sched_get_priority_max(PyObject *self, PyObject *args)
5504{
5505 int policy, max;
5506
5507 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5508 return NULL;
5509 max = sched_get_priority_max(policy);
5510 if (max < 0)
5511 return posix_error();
5512 return PyLong_FromLong(max);
5513}
5514
5515PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5516"sched_get_priority_min(policy)\n\n\
5517Get the minimum scheduling priority for *policy*.");
5518
5519static PyObject *
5520posix_sched_get_priority_min(PyObject *self, PyObject *args)
5521{
5522 int policy, min;
5523
5524 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5525 return NULL;
5526 min = sched_get_priority_min(policy);
5527 if (min < 0)
5528 return posix_error();
5529 return PyLong_FromLong(min);
5530}
5531
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005532#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5533
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005534#ifdef HAVE_SCHED_SETSCHEDULER
5535
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005536PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5537"sched_getscheduler(pid)\n\n\
5538Get the scheduling policy for the process with a PID of *pid*.\n\
5539Passing a PID of 0 returns the scheduling policy for the calling process.");
5540
5541static PyObject *
5542posix_sched_getscheduler(PyObject *self, PyObject *args)
5543{
5544 pid_t pid;
5545 int policy;
5546
5547 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5548 return NULL;
5549 policy = sched_getscheduler(pid);
5550 if (policy < 0)
5551 return posix_error();
5552 return PyLong_FromLong(policy);
5553}
5554
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005555#endif
5556
5557#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5558
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005559static PyObject *
5560sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5561{
5562 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005563 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005564
5565 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5566 return NULL;
5567 res = PyStructSequence_New(type);
5568 if (!res)
5569 return NULL;
5570 Py_INCREF(priority);
5571 PyStructSequence_SET_ITEM(res, 0, priority);
5572 return res;
5573}
5574
5575PyDoc_STRVAR(sched_param__doc__,
5576"sched_param(sched_priority): A scheduling parameter.\n\n\
5577Current has only one field: sched_priority");
5578
5579static PyStructSequence_Field sched_param_fields[] = {
5580 {"sched_priority", "the scheduling priority"},
5581 {0}
5582};
5583
5584static PyStructSequence_Desc sched_param_desc = {
5585 "sched_param", /* name */
5586 sched_param__doc__, /* doc */
5587 sched_param_fields,
5588 1
5589};
5590
5591static int
5592convert_sched_param(PyObject *param, struct sched_param *res)
5593{
5594 long priority;
5595
5596 if (Py_TYPE(param) != &SchedParamType) {
5597 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5598 return 0;
5599 }
5600 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5601 if (priority == -1 && PyErr_Occurred())
5602 return 0;
5603 if (priority > INT_MAX || priority < INT_MIN) {
5604 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5605 return 0;
5606 }
5607 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5608 return 1;
5609}
5610
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005611#endif
5612
5613#ifdef HAVE_SCHED_SETSCHEDULER
5614
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005615PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5616"sched_setscheduler(pid, policy, param)\n\n\
5617Set the scheduling policy, *policy*, for *pid*.\n\
5618If *pid* is 0, the calling process is changed.\n\
5619*param* is an instance of sched_param.");
5620
5621static PyObject *
5622posix_sched_setscheduler(PyObject *self, PyObject *args)
5623{
5624 pid_t pid;
5625 int policy;
5626 struct sched_param param;
5627
5628 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5629 &pid, &policy, &convert_sched_param, &param))
5630 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005631
5632 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005633 ** sched_setscheduler() returns 0 in Linux, but the previous
5634 ** scheduling policy under Solaris/Illumos, and others.
5635 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005636 */
5637 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005638 return posix_error();
5639 Py_RETURN_NONE;
5640}
5641
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005642#endif
5643
5644#ifdef HAVE_SCHED_SETPARAM
5645
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005646PyDoc_STRVAR(posix_sched_getparam__doc__,
5647"sched_getparam(pid) -> sched_param\n\n\
5648Returns scheduling parameters for the process with *pid* as an instance of the\n\
5649sched_param class. A PID of 0 means the calling process.");
5650
5651static PyObject *
5652posix_sched_getparam(PyObject *self, PyObject *args)
5653{
5654 pid_t pid;
5655 struct sched_param param;
5656 PyObject *res, *priority;
5657
5658 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5659 return NULL;
5660 if (sched_getparam(pid, &param))
5661 return posix_error();
5662 res = PyStructSequence_New(&SchedParamType);
5663 if (!res)
5664 return NULL;
5665 priority = PyLong_FromLong(param.sched_priority);
5666 if (!priority) {
5667 Py_DECREF(res);
5668 return NULL;
5669 }
5670 PyStructSequence_SET_ITEM(res, 0, priority);
5671 return res;
5672}
5673
5674PyDoc_STRVAR(posix_sched_setparam__doc__,
5675"sched_setparam(pid, param)\n\n\
5676Set scheduling parameters for a process with PID *pid*.\n\
5677A PID of 0 means the calling process.");
5678
5679static PyObject *
5680posix_sched_setparam(PyObject *self, PyObject *args)
5681{
5682 pid_t pid;
5683 struct sched_param param;
5684
5685 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5686 &pid, &convert_sched_param, &param))
5687 return NULL;
5688 if (sched_setparam(pid, &param))
5689 return posix_error();
5690 Py_RETURN_NONE;
5691}
5692
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005693#endif
5694
5695#ifdef HAVE_SCHED_RR_GET_INTERVAL
5696
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005697PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5698"sched_rr_get_interval(pid) -> float\n\n\
5699Return the round-robin quantum for the process with PID *pid* in seconds.");
5700
5701static PyObject *
5702posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5703{
5704 pid_t pid;
5705 struct timespec interval;
5706
5707 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5708 return NULL;
5709 if (sched_rr_get_interval(pid, &interval))
5710 return posix_error();
5711 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5712}
5713
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005714#endif
5715
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005716PyDoc_STRVAR(posix_sched_yield__doc__,
5717"sched_yield()\n\n\
5718Voluntarily relinquish the CPU.");
5719
5720static PyObject *
5721posix_sched_yield(PyObject *self, PyObject *noargs)
5722{
5723 if (sched_yield())
5724 return posix_error();
5725 Py_RETURN_NONE;
5726}
5727
Benjamin Peterson2740af82011-08-02 17:41:34 -05005728#ifdef HAVE_SCHED_SETAFFINITY
5729
Antoine Pitrou84869872012-08-04 16:16:35 +02005730/* The minimum number of CPUs allocated in a cpu_set_t */
5731static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005732
5733PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5734"sched_setaffinity(pid, cpu_set)\n\n\
5735Set the affinity of the process with PID *pid* to *cpu_set*.");
5736
5737static PyObject *
5738posix_sched_setaffinity(PyObject *self, PyObject *args)
5739{
5740 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005741 int ncpus;
5742 size_t setsize;
5743 cpu_set_t *mask = NULL;
5744 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005745
Antoine Pitrou84869872012-08-04 16:16:35 +02005746 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5747 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005748 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005749
5750 iterator = PyObject_GetIter(iterable);
5751 if (iterator == NULL)
5752 return NULL;
5753
5754 ncpus = NCPUS_START;
5755 setsize = CPU_ALLOC_SIZE(ncpus);
5756 mask = CPU_ALLOC(ncpus);
5757 if (mask == NULL) {
5758 PyErr_NoMemory();
5759 goto error;
5760 }
5761 CPU_ZERO_S(setsize, mask);
5762
5763 while ((item = PyIter_Next(iterator))) {
5764 long cpu;
5765 if (!PyLong_Check(item)) {
5766 PyErr_Format(PyExc_TypeError,
5767 "expected an iterator of ints, "
5768 "but iterator yielded %R",
5769 Py_TYPE(item));
5770 Py_DECREF(item);
5771 goto error;
5772 }
5773 cpu = PyLong_AsLong(item);
5774 Py_DECREF(item);
5775 if (cpu < 0) {
5776 if (!PyErr_Occurred())
5777 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5778 goto error;
5779 }
5780 if (cpu > INT_MAX - 1) {
5781 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5782 goto error;
5783 }
5784 if (cpu >= ncpus) {
5785 /* Grow CPU mask to fit the CPU number */
5786 int newncpus = ncpus;
5787 cpu_set_t *newmask;
5788 size_t newsetsize;
5789 while (newncpus <= cpu) {
5790 if (newncpus > INT_MAX / 2)
5791 newncpus = cpu + 1;
5792 else
5793 newncpus = newncpus * 2;
5794 }
5795 newmask = CPU_ALLOC(newncpus);
5796 if (newmask == NULL) {
5797 PyErr_NoMemory();
5798 goto error;
5799 }
5800 newsetsize = CPU_ALLOC_SIZE(newncpus);
5801 CPU_ZERO_S(newsetsize, newmask);
5802 memcpy(newmask, mask, setsize);
5803 CPU_FREE(mask);
5804 setsize = newsetsize;
5805 mask = newmask;
5806 ncpus = newncpus;
5807 }
5808 CPU_SET_S(cpu, setsize, mask);
5809 }
5810 Py_CLEAR(iterator);
5811
5812 if (sched_setaffinity(pid, setsize, mask)) {
5813 posix_error();
5814 goto error;
5815 }
5816 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005817 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005818
5819error:
5820 if (mask)
5821 CPU_FREE(mask);
5822 Py_XDECREF(iterator);
5823 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005824}
5825
5826PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5827"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5828Return the affinity of the process with PID *pid*.\n\
5829The returned cpu_set will be of size *ncpus*.");
5830
5831static PyObject *
5832posix_sched_getaffinity(PyObject *self, PyObject *args)
5833{
5834 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005835 int cpu, ncpus, count;
5836 size_t setsize;
5837 cpu_set_t *mask = NULL;
5838 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005839
Antoine Pitrou84869872012-08-04 16:16:35 +02005840 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5841 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005842 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005843
5844 ncpus = NCPUS_START;
5845 while (1) {
5846 setsize = CPU_ALLOC_SIZE(ncpus);
5847 mask = CPU_ALLOC(ncpus);
5848 if (mask == NULL)
5849 return PyErr_NoMemory();
5850 if (sched_getaffinity(pid, setsize, mask) == 0)
5851 break;
5852 CPU_FREE(mask);
5853 if (errno != EINVAL)
5854 return posix_error();
5855 if (ncpus > INT_MAX / 2) {
5856 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5857 "a large enough CPU set");
5858 return NULL;
5859 }
5860 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005861 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005862
5863 res = PySet_New(NULL);
5864 if (res == NULL)
5865 goto error;
5866 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5867 if (CPU_ISSET_S(cpu, setsize, mask)) {
5868 PyObject *cpu_num = PyLong_FromLong(cpu);
5869 --count;
5870 if (cpu_num == NULL)
5871 goto error;
5872 if (PySet_Add(res, cpu_num)) {
5873 Py_DECREF(cpu_num);
5874 goto error;
5875 }
5876 Py_DECREF(cpu_num);
5877 }
5878 }
5879 CPU_FREE(mask);
5880 return res;
5881
5882error:
5883 if (mask)
5884 CPU_FREE(mask);
5885 Py_XDECREF(res);
5886 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005887}
5888
Benjamin Peterson2740af82011-08-02 17:41:34 -05005889#endif /* HAVE_SCHED_SETAFFINITY */
5890
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005891#endif /* HAVE_SCHED_H */
5892
Neal Norwitzb59798b2003-03-21 01:43:31 +00005893/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005894/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5895#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005896#define DEV_PTY_FILE "/dev/ptc"
5897#define HAVE_DEV_PTMX
5898#else
5899#define DEV_PTY_FILE "/dev/ptmx"
5900#endif
5901
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005902#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005903#ifdef HAVE_PTY_H
5904#include <pty.h>
5905#else
5906#ifdef HAVE_LIBUTIL_H
5907#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005908#else
5909#ifdef HAVE_UTIL_H
5910#include <util.h>
5911#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005912#endif /* HAVE_LIBUTIL_H */
5913#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005914#ifdef HAVE_STROPTS_H
5915#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005916#endif
5917#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005918
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005919#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005920PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005921"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005922Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005923
5924static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005925posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005926{
Victor Stinner8c62be82010-05-06 00:08:46 +00005927 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005928#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005929 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005930#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005931#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005933#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005934 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005935#endif
5936#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005937
Thomas Wouters70c21a12000-07-14 14:28:33 +00005938#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005939 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5940 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005941#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005942 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5943 if (slave_name == NULL)
5944 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005945
Victor Stinner8c62be82010-05-06 00:08:46 +00005946 slave_fd = open(slave_name, O_RDWR);
5947 if (slave_fd < 0)
5948 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005949#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005950 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5951 if (master_fd < 0)
5952 return posix_error();
5953 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5954 /* change permission of slave */
5955 if (grantpt(master_fd) < 0) {
5956 PyOS_setsig(SIGCHLD, sig_saved);
5957 return posix_error();
5958 }
5959 /* unlock slave */
5960 if (unlockpt(master_fd) < 0) {
5961 PyOS_setsig(SIGCHLD, sig_saved);
5962 return posix_error();
5963 }
5964 PyOS_setsig(SIGCHLD, sig_saved);
5965 slave_name = ptsname(master_fd); /* get name of slave */
5966 if (slave_name == NULL)
5967 return posix_error();
5968 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5969 if (slave_fd < 0)
5970 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005971#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005972 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5973 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005974#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005975 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005976#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005977#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005978#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005979
Victor Stinner8c62be82010-05-06 00:08:46 +00005980 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005981
Fred Drake8cef4cf2000-06-28 16:40:38 +00005982}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005983#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005984
5985#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005986PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005987"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005988Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5989Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005990To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005991
5992static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005993posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005994{
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 int master_fd = -1, result = 0;
5996 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005997
Victor Stinner8c62be82010-05-06 00:08:46 +00005998 _PyImport_AcquireLock();
5999 pid = forkpty(&master_fd, NULL, NULL, NULL);
6000 if (pid == 0) {
6001 /* child: this clobbers and resets the import lock. */
6002 PyOS_AfterFork();
6003 } else {
6004 /* parent: release the import lock. */
6005 result = _PyImport_ReleaseLock();
6006 }
6007 if (pid == -1)
6008 return posix_error();
6009 if (result < 0) {
6010 /* Don't clobber the OSError if the fork failed. */
6011 PyErr_SetString(PyExc_RuntimeError,
6012 "not holding the import lock");
6013 return NULL;
6014 }
6015 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006016}
6017#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006018
Ross Lagerwall7807c352011-03-17 20:20:30 +02006019
Guido van Rossumad0ee831995-03-01 10:34:45 +00006020#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006021PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006022"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006023Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006024
Barry Warsaw53699e91996-12-10 23:23:01 +00006025static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006026posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006027{
Victor Stinner8c62be82010-05-06 00:08:46 +00006028 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006029}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006030#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006031
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006032
Guido van Rossumad0ee831995-03-01 10:34:45 +00006033#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006034PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006035"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006036Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006037
Barry Warsaw53699e91996-12-10 23:23:01 +00006038static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006039posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006040{
Victor Stinner8c62be82010-05-06 00:08:46 +00006041 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006042}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006043#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006044
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006045
Guido van Rossumad0ee831995-03-01 10:34:45 +00006046#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006047PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006048"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006050
Barry Warsaw53699e91996-12-10 23:23:01 +00006051static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006052posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006053{
Victor Stinner8c62be82010-05-06 00:08:46 +00006054 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006055}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006056#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006057
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006058
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006059PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006060"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006061Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006062
Barry Warsaw53699e91996-12-10 23:23:01 +00006063static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006064posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006065{
Victor Stinner8c62be82010-05-06 00:08:46 +00006066 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006067}
6068
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006069#ifdef HAVE_GETGROUPLIST
6070PyDoc_STRVAR(posix_getgrouplist__doc__,
6071"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6072Returns a list of groups to which a user belongs.\n\n\
6073 user: username to lookup\n\
6074 group: base group id of the user");
6075
6076static PyObject *
6077posix_getgrouplist(PyObject *self, PyObject *args)
6078{
6079#ifdef NGROUPS_MAX
6080#define MAX_GROUPS NGROUPS_MAX
6081#else
6082 /* defined to be 16 on Solaris7, so this should be a small number */
6083#define MAX_GROUPS 64
6084#endif
6085
6086 const char *user;
6087 int i, ngroups;
6088 PyObject *list;
6089#ifdef __APPLE__
6090 int *groups, basegid;
6091#else
6092 gid_t *groups, basegid;
6093#endif
6094 ngroups = MAX_GROUPS;
6095
6096 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
6097 return NULL;
6098
6099#ifdef __APPLE__
6100 groups = PyMem_Malloc(ngroups * sizeof(int));
6101#else
6102 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6103#endif
6104 if (groups == NULL)
6105 return PyErr_NoMemory();
6106
6107 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6108 PyMem_Del(groups);
6109 return posix_error();
6110 }
6111
6112 list = PyList_New(ngroups);
6113 if (list == NULL) {
6114 PyMem_Del(groups);
6115 return NULL;
6116 }
6117
6118 for (i = 0; i < ngroups; i++) {
6119 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
6120 if (o == NULL) {
6121 Py_DECREF(list);
6122 PyMem_Del(groups);
6123 return NULL;
6124 }
6125 PyList_SET_ITEM(list, i, o);
6126 }
6127
6128 PyMem_Del(groups);
6129
6130 return list;
6131}
6132#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006133
Fred Drakec9680921999-12-13 16:37:25 +00006134#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006135PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006136"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006137Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006138
6139static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006140posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006141{
6142 PyObject *result = NULL;
6143
Fred Drakec9680921999-12-13 16:37:25 +00006144#ifdef NGROUPS_MAX
6145#define MAX_GROUPS NGROUPS_MAX
6146#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006147 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006148#define MAX_GROUPS 64
6149#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006150 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006151
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006152 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006153 * This is a helper variable to store the intermediate result when
6154 * that happens.
6155 *
6156 * To keep the code readable the OSX behaviour is unconditional,
6157 * according to the POSIX spec this should be safe on all unix-y
6158 * systems.
6159 */
6160 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006161 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006162
Victor Stinner8c62be82010-05-06 00:08:46 +00006163 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006164 if (n < 0) {
6165 if (errno == EINVAL) {
6166 n = getgroups(0, NULL);
6167 if (n == -1) {
6168 return posix_error();
6169 }
6170 if (n == 0) {
6171 /* Avoid malloc(0) */
6172 alt_grouplist = grouplist;
6173 } else {
6174 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6175 if (alt_grouplist == NULL) {
6176 errno = EINVAL;
6177 return posix_error();
6178 }
6179 n = getgroups(n, alt_grouplist);
6180 if (n == -1) {
6181 PyMem_Free(alt_grouplist);
6182 return posix_error();
6183 }
6184 }
6185 } else {
6186 return posix_error();
6187 }
6188 }
6189 result = PyList_New(n);
6190 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006191 int i;
6192 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006193 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006194 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006195 Py_DECREF(result);
6196 result = NULL;
6197 break;
Fred Drakec9680921999-12-13 16:37:25 +00006198 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006199 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006200 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006201 }
6202
6203 if (alt_grouplist != grouplist) {
6204 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006205 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006206
Fred Drakec9680921999-12-13 16:37:25 +00006207 return result;
6208}
6209#endif
6210
Antoine Pitroub7572f02009-12-02 20:46:48 +00006211#ifdef HAVE_INITGROUPS
6212PyDoc_STRVAR(posix_initgroups__doc__,
6213"initgroups(username, gid) -> None\n\n\
6214Call the system initgroups() to initialize the group access list with all of\n\
6215the groups of which the specified username is a member, plus the specified\n\
6216group id.");
6217
6218static PyObject *
6219posix_initgroups(PyObject *self, PyObject *args)
6220{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006221 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006222 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006223 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006224 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006225
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006226 if (!PyArg_ParseTuple(args, "O&l:initgroups",
6227 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006228 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006229 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006230
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006231 res = initgroups(username, (gid_t) gid);
6232 Py_DECREF(oname);
6233 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006234 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006235
Victor Stinner8c62be82010-05-06 00:08:46 +00006236 Py_INCREF(Py_None);
6237 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006238}
6239#endif
6240
Martin v. Löwis606edc12002-06-13 21:09:11 +00006241#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006242PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006243"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006244Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006245
6246static PyObject *
6247posix_getpgid(PyObject *self, PyObject *args)
6248{
Victor Stinner8c62be82010-05-06 00:08:46 +00006249 pid_t pid, pgid;
6250 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6251 return NULL;
6252 pgid = getpgid(pid);
6253 if (pgid < 0)
6254 return posix_error();
6255 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006256}
6257#endif /* HAVE_GETPGID */
6258
6259
Guido van Rossumb6775db1994-08-01 11:34:53 +00006260#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006261PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006262"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006263Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006264
Barry Warsaw53699e91996-12-10 23:23:01 +00006265static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006266posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006267{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006268#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006269 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006270#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006271 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006272#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006273}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006274#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006276
Guido van Rossumb6775db1994-08-01 11:34:53 +00006277#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006278PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006279"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006280Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006281
Barry Warsaw53699e91996-12-10 23:23:01 +00006282static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006283posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006284{
Guido van Rossum64933891994-10-20 21:56:42 +00006285#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006286 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006287#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006289#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006290 return posix_error();
6291 Py_INCREF(Py_None);
6292 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006293}
6294
Guido van Rossumb6775db1994-08-01 11:34:53 +00006295#endif /* HAVE_SETPGRP */
6296
Guido van Rossumad0ee831995-03-01 10:34:45 +00006297#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006298
6299#ifdef MS_WINDOWS
6300#include <tlhelp32.h>
6301
6302static PyObject*
6303win32_getppid()
6304{
6305 HANDLE snapshot;
6306 pid_t mypid;
6307 PyObject* result = NULL;
6308 BOOL have_record;
6309 PROCESSENTRY32 pe;
6310
6311 mypid = getpid(); /* This function never fails */
6312
6313 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6314 if (snapshot == INVALID_HANDLE_VALUE)
6315 return PyErr_SetFromWindowsErr(GetLastError());
6316
6317 pe.dwSize = sizeof(pe);
6318 have_record = Process32First(snapshot, &pe);
6319 while (have_record) {
6320 if (mypid == (pid_t)pe.th32ProcessID) {
6321 /* We could cache the ulong value in a static variable. */
6322 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6323 break;
6324 }
6325
6326 have_record = Process32Next(snapshot, &pe);
6327 }
6328
6329 /* If our loop exits and our pid was not found (result will be NULL)
6330 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6331 * error anyway, so let's raise it. */
6332 if (!result)
6333 result = PyErr_SetFromWindowsErr(GetLastError());
6334
6335 CloseHandle(snapshot);
6336
6337 return result;
6338}
6339#endif /*MS_WINDOWS*/
6340
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006341PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006342"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006343Return the parent's process id. If the parent process has already exited,\n\
6344Windows machines will still return its id; others systems will return the id\n\
6345of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006346
Barry Warsaw53699e91996-12-10 23:23:01 +00006347static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006348posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006349{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006350#ifdef MS_WINDOWS
6351 return win32_getppid();
6352#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006353 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006354#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006355}
6356#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006357
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006358
Fred Drake12c6e2d1999-12-14 21:25:03 +00006359#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006360PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006361"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006362Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006363
6364static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006365posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006366{
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006368#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006369 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006370 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006371
6372 if (GetUserNameW(user_name, &num_chars)) {
6373 /* num_chars is the number of unicode chars plus null terminator */
6374 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006375 }
6376 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006377 result = PyErr_SetFromWindowsErr(GetLastError());
6378#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006379 char *name;
6380 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006381
Victor Stinner8c62be82010-05-06 00:08:46 +00006382 errno = 0;
6383 name = getlogin();
6384 if (name == NULL) {
6385 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006386 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006387 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006388 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006389 }
6390 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006391 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006392 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006393#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006394 return result;
6395}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006396#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006397
Guido van Rossumad0ee831995-03-01 10:34:45 +00006398#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006399PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006400"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006401Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006402
Barry Warsaw53699e91996-12-10 23:23:01 +00006403static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006404posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006405{
Victor Stinner8c62be82010-05-06 00:08:46 +00006406 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006407}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006408#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006410
Guido van Rossumad0ee831995-03-01 10:34:45 +00006411#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006412PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006413"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006414Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006415
Barry Warsaw53699e91996-12-10 23:23:01 +00006416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006417posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006418{
Victor Stinner8c62be82010-05-06 00:08:46 +00006419 pid_t pid;
6420 int sig;
6421 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6422 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006423#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006424 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6425 APIRET rc;
6426 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006427 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006428
6429 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6430 APIRET rc;
6431 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006432 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006433
6434 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006435 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006436#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006437 if (kill(pid, sig) == -1)
6438 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006439#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 Py_INCREF(Py_None);
6441 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006442}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006443#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006444
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006445#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006446PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006447"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006448Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006449
6450static PyObject *
6451posix_killpg(PyObject *self, PyObject *args)
6452{
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 int sig;
6454 pid_t pgid;
6455 /* XXX some man pages make the `pgid` parameter an int, others
6456 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6457 take the same type. Moreover, pid_t is always at least as wide as
6458 int (else compilation of this module fails), which is safe. */
6459 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6460 return NULL;
6461 if (killpg(pgid, sig) == -1)
6462 return posix_error();
6463 Py_INCREF(Py_None);
6464 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006465}
6466#endif
6467
Brian Curtineb24d742010-04-12 17:16:38 +00006468#ifdef MS_WINDOWS
6469PyDoc_STRVAR(win32_kill__doc__,
6470"kill(pid, sig)\n\n\
6471Kill a process with a signal.");
6472
6473static PyObject *
6474win32_kill(PyObject *self, PyObject *args)
6475{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006476 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 DWORD pid, sig, err;
6478 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006479
Victor Stinner8c62be82010-05-06 00:08:46 +00006480 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6481 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006482
Victor Stinner8c62be82010-05-06 00:08:46 +00006483 /* Console processes which share a common console can be sent CTRL+C or
6484 CTRL+BREAK events, provided they handle said events. */
6485 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6486 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6487 err = GetLastError();
6488 PyErr_SetFromWindowsErr(err);
6489 }
6490 else
6491 Py_RETURN_NONE;
6492 }
Brian Curtineb24d742010-04-12 17:16:38 +00006493
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6495 attempt to open and terminate the process. */
6496 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6497 if (handle == NULL) {
6498 err = GetLastError();
6499 return PyErr_SetFromWindowsErr(err);
6500 }
Brian Curtineb24d742010-04-12 17:16:38 +00006501
Victor Stinner8c62be82010-05-06 00:08:46 +00006502 if (TerminateProcess(handle, sig) == 0) {
6503 err = GetLastError();
6504 result = PyErr_SetFromWindowsErr(err);
6505 } else {
6506 Py_INCREF(Py_None);
6507 result = Py_None;
6508 }
Brian Curtineb24d742010-04-12 17:16:38 +00006509
Victor Stinner8c62be82010-05-06 00:08:46 +00006510 CloseHandle(handle);
6511 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006512}
6513#endif /* MS_WINDOWS */
6514
Guido van Rossumc0125471996-06-28 18:55:32 +00006515#ifdef HAVE_PLOCK
6516
6517#ifdef HAVE_SYS_LOCK_H
6518#include <sys/lock.h>
6519#endif
6520
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006521PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006522"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006523Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006524
Barry Warsaw53699e91996-12-10 23:23:01 +00006525static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006526posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006527{
Victor Stinner8c62be82010-05-06 00:08:46 +00006528 int op;
6529 if (!PyArg_ParseTuple(args, "i:plock", &op))
6530 return NULL;
6531 if (plock(op) == -1)
6532 return posix_error();
6533 Py_INCREF(Py_None);
6534 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006535}
6536#endif
6537
Guido van Rossumb6775db1994-08-01 11:34:53 +00006538#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006539PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006540"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006541Set the current process's user id.");
6542
Barry Warsaw53699e91996-12-10 23:23:01 +00006543static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006544posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006545{
Victor Stinner8c62be82010-05-06 00:08:46 +00006546 long uid_arg;
6547 uid_t uid;
6548 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6549 return NULL;
6550 uid = uid_arg;
6551 if (uid != uid_arg) {
6552 PyErr_SetString(PyExc_OverflowError, "user id too big");
6553 return NULL;
6554 }
6555 if (setuid(uid) < 0)
6556 return posix_error();
6557 Py_INCREF(Py_None);
6558 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006559}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006560#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006561
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006562
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006563#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006564PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006565"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006566Set the current process's effective user id.");
6567
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006568static PyObject *
6569posix_seteuid (PyObject *self, PyObject *args)
6570{
Victor Stinner8c62be82010-05-06 00:08:46 +00006571 long euid_arg;
6572 uid_t euid;
6573 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6574 return NULL;
6575 euid = euid_arg;
6576 if (euid != euid_arg) {
6577 PyErr_SetString(PyExc_OverflowError, "user id too big");
6578 return NULL;
6579 }
6580 if (seteuid(euid) < 0) {
6581 return posix_error();
6582 } else {
6583 Py_INCREF(Py_None);
6584 return Py_None;
6585 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006586}
6587#endif /* HAVE_SETEUID */
6588
6589#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006590PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006591"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006592Set the current process's effective group id.");
6593
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006594static PyObject *
6595posix_setegid (PyObject *self, PyObject *args)
6596{
Victor Stinner8c62be82010-05-06 00:08:46 +00006597 long egid_arg;
6598 gid_t egid;
6599 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6600 return NULL;
6601 egid = egid_arg;
6602 if (egid != egid_arg) {
6603 PyErr_SetString(PyExc_OverflowError, "group id too big");
6604 return NULL;
6605 }
6606 if (setegid(egid) < 0) {
6607 return posix_error();
6608 } else {
6609 Py_INCREF(Py_None);
6610 return Py_None;
6611 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006612}
6613#endif /* HAVE_SETEGID */
6614
6615#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006616PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006617"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006618Set the current process's real and effective user ids.");
6619
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006620static PyObject *
6621posix_setreuid (PyObject *self, PyObject *args)
6622{
Victor Stinner8c62be82010-05-06 00:08:46 +00006623 long ruid_arg, euid_arg;
6624 uid_t ruid, euid;
6625 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6626 return NULL;
6627 if (ruid_arg == -1)
6628 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6629 else
6630 ruid = ruid_arg; /* otherwise, assign from our long */
6631 if (euid_arg == -1)
6632 euid = (uid_t)-1;
6633 else
6634 euid = euid_arg;
6635 if ((euid_arg != -1 && euid != euid_arg) ||
6636 (ruid_arg != -1 && ruid != ruid_arg)) {
6637 PyErr_SetString(PyExc_OverflowError, "user id too big");
6638 return NULL;
6639 }
6640 if (setreuid(ruid, euid) < 0) {
6641 return posix_error();
6642 } else {
6643 Py_INCREF(Py_None);
6644 return Py_None;
6645 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006646}
6647#endif /* HAVE_SETREUID */
6648
6649#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006650PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006651"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006652Set the current process's real and effective group ids.");
6653
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006654static PyObject *
6655posix_setregid (PyObject *self, PyObject *args)
6656{
Victor Stinner8c62be82010-05-06 00:08:46 +00006657 long rgid_arg, egid_arg;
6658 gid_t rgid, egid;
6659 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6660 return NULL;
6661 if (rgid_arg == -1)
6662 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6663 else
6664 rgid = rgid_arg; /* otherwise, assign from our long */
6665 if (egid_arg == -1)
6666 egid = (gid_t)-1;
6667 else
6668 egid = egid_arg;
6669 if ((egid_arg != -1 && egid != egid_arg) ||
6670 (rgid_arg != -1 && rgid != rgid_arg)) {
6671 PyErr_SetString(PyExc_OverflowError, "group id too big");
6672 return NULL;
6673 }
6674 if (setregid(rgid, egid) < 0) {
6675 return posix_error();
6676 } else {
6677 Py_INCREF(Py_None);
6678 return Py_None;
6679 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006680}
6681#endif /* HAVE_SETREGID */
6682
Guido van Rossumb6775db1994-08-01 11:34:53 +00006683#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006684PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006685"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006686Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006687
Barry Warsaw53699e91996-12-10 23:23:01 +00006688static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006689posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006690{
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 long gid_arg;
6692 gid_t gid;
6693 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6694 return NULL;
6695 gid = gid_arg;
6696 if (gid != gid_arg) {
6697 PyErr_SetString(PyExc_OverflowError, "group id too big");
6698 return NULL;
6699 }
6700 if (setgid(gid) < 0)
6701 return posix_error();
6702 Py_INCREF(Py_None);
6703 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006704}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006705#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006706
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006707#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006708PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006709"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006710Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006711
6712static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006713posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006714{
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 int i, len;
6716 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006717
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 if (!PySequence_Check(groups)) {
6719 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6720 return NULL;
6721 }
6722 len = PySequence_Size(groups);
6723 if (len > MAX_GROUPS) {
6724 PyErr_SetString(PyExc_ValueError, "too many groups");
6725 return NULL;
6726 }
6727 for(i = 0; i < len; i++) {
6728 PyObject *elem;
6729 elem = PySequence_GetItem(groups, i);
6730 if (!elem)
6731 return NULL;
6732 if (!PyLong_Check(elem)) {
6733 PyErr_SetString(PyExc_TypeError,
6734 "groups must be integers");
6735 Py_DECREF(elem);
6736 return NULL;
6737 } else {
6738 unsigned long x = PyLong_AsUnsignedLong(elem);
6739 if (PyErr_Occurred()) {
6740 PyErr_SetString(PyExc_TypeError,
6741 "group id too big");
6742 Py_DECREF(elem);
6743 return NULL;
6744 }
6745 grouplist[i] = x;
6746 /* read back the value to see if it fitted in gid_t */
6747 if (grouplist[i] != x) {
6748 PyErr_SetString(PyExc_TypeError,
6749 "group id too big");
6750 Py_DECREF(elem);
6751 return NULL;
6752 }
6753 }
6754 Py_DECREF(elem);
6755 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006756
Victor Stinner8c62be82010-05-06 00:08:46 +00006757 if (setgroups(len, grouplist) < 0)
6758 return posix_error();
6759 Py_INCREF(Py_None);
6760 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006761}
6762#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006763
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006764#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6765static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006766wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006767{
Victor Stinner8c62be82010-05-06 00:08:46 +00006768 PyObject *result;
6769 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006770 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006771
Victor Stinner8c62be82010-05-06 00:08:46 +00006772 if (pid == -1)
6773 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006774
Victor Stinner8c62be82010-05-06 00:08:46 +00006775 if (struct_rusage == NULL) {
6776 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6777 if (m == NULL)
6778 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006779 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006780 Py_DECREF(m);
6781 if (struct_rusage == NULL)
6782 return NULL;
6783 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006784
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6786 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6787 if (!result)
6788 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006789
6790#ifndef doubletime
6791#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6792#endif
6793
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006795 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006797 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006798#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6800 SET_INT(result, 2, ru->ru_maxrss);
6801 SET_INT(result, 3, ru->ru_ixrss);
6802 SET_INT(result, 4, ru->ru_idrss);
6803 SET_INT(result, 5, ru->ru_isrss);
6804 SET_INT(result, 6, ru->ru_minflt);
6805 SET_INT(result, 7, ru->ru_majflt);
6806 SET_INT(result, 8, ru->ru_nswap);
6807 SET_INT(result, 9, ru->ru_inblock);
6808 SET_INT(result, 10, ru->ru_oublock);
6809 SET_INT(result, 11, ru->ru_msgsnd);
6810 SET_INT(result, 12, ru->ru_msgrcv);
6811 SET_INT(result, 13, ru->ru_nsignals);
6812 SET_INT(result, 14, ru->ru_nvcsw);
6813 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006814#undef SET_INT
6815
Victor Stinner8c62be82010-05-06 00:08:46 +00006816 if (PyErr_Occurred()) {
6817 Py_DECREF(result);
6818 return NULL;
6819 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006820
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006822}
6823#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6824
6825#ifdef HAVE_WAIT3
6826PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006827"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006828Wait for completion of a child process.");
6829
6830static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006831posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006832{
Victor Stinner8c62be82010-05-06 00:08:46 +00006833 pid_t pid;
6834 int options;
6835 struct rusage ru;
6836 WAIT_TYPE status;
6837 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006838
Victor Stinner4195b5c2012-02-08 23:03:19 +01006839 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006840 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006841
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 Py_BEGIN_ALLOW_THREADS
6843 pid = wait3(&status, options, &ru);
6844 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006845
Victor Stinner4195b5c2012-02-08 23:03:19 +01006846 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006847}
6848#endif /* HAVE_WAIT3 */
6849
6850#ifdef HAVE_WAIT4
6851PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006852"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006853Wait for completion of a given child process.");
6854
6855static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006856posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006857{
Victor Stinner8c62be82010-05-06 00:08:46 +00006858 pid_t pid;
6859 int options;
6860 struct rusage ru;
6861 WAIT_TYPE status;
6862 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006863
Victor Stinner4195b5c2012-02-08 23:03:19 +01006864 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006866
Victor Stinner8c62be82010-05-06 00:08:46 +00006867 Py_BEGIN_ALLOW_THREADS
6868 pid = wait4(pid, &status, options, &ru);
6869 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006870
Victor Stinner4195b5c2012-02-08 23:03:19 +01006871 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006872}
6873#endif /* HAVE_WAIT4 */
6874
Ross Lagerwall7807c352011-03-17 20:20:30 +02006875#if defined(HAVE_WAITID) && !defined(__APPLE__)
6876PyDoc_STRVAR(posix_waitid__doc__,
6877"waitid(idtype, id, options) -> waitid_result\n\n\
6878Wait for the completion of one or more child processes.\n\n\
6879idtype can be P_PID, P_PGID or P_ALL.\n\
6880id specifies the pid to wait on.\n\
6881options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6882or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6883Returns either waitid_result or None if WNOHANG is specified and there are\n\
6884no children in a waitable state.");
6885
6886static PyObject *
6887posix_waitid(PyObject *self, PyObject *args)
6888{
6889 PyObject *result;
6890 idtype_t idtype;
6891 id_t id;
6892 int options, res;
6893 siginfo_t si;
6894 si.si_pid = 0;
6895 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6896 return NULL;
6897 Py_BEGIN_ALLOW_THREADS
6898 res = waitid(idtype, id, &si, options);
6899 Py_END_ALLOW_THREADS
6900 if (res == -1)
6901 return posix_error();
6902
6903 if (si.si_pid == 0)
6904 Py_RETURN_NONE;
6905
6906 result = PyStructSequence_New(&WaitidResultType);
6907 if (!result)
6908 return NULL;
6909
6910 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6911 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6912 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6913 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6914 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6915 if (PyErr_Occurred()) {
6916 Py_DECREF(result);
6917 return NULL;
6918 }
6919
6920 return result;
6921}
6922#endif
6923
Guido van Rossumb6775db1994-08-01 11:34:53 +00006924#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006925PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006926"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006927Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006928
Barry Warsaw53699e91996-12-10 23:23:01 +00006929static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006930posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006931{
Victor Stinner8c62be82010-05-06 00:08:46 +00006932 pid_t pid;
6933 int options;
6934 WAIT_TYPE status;
6935 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006936
Victor Stinner8c62be82010-05-06 00:08:46 +00006937 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6938 return NULL;
6939 Py_BEGIN_ALLOW_THREADS
6940 pid = waitpid(pid, &status, options);
6941 Py_END_ALLOW_THREADS
6942 if (pid == -1)
6943 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006944
Victor Stinner8c62be82010-05-06 00:08:46 +00006945 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006946}
6947
Tim Petersab034fa2002-02-01 11:27:43 +00006948#elif defined(HAVE_CWAIT)
6949
6950/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006951PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006952"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006953"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006954
6955static PyObject *
6956posix_waitpid(PyObject *self, PyObject *args)
6957{
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 Py_intptr_t pid;
6959 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006960
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6962 return NULL;
6963 Py_BEGIN_ALLOW_THREADS
6964 pid = _cwait(&status, pid, options);
6965 Py_END_ALLOW_THREADS
6966 if (pid == -1)
6967 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006968
Victor Stinner8c62be82010-05-06 00:08:46 +00006969 /* shift the status left a byte so this is more like the POSIX waitpid */
6970 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006971}
6972#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006973
Guido van Rossumad0ee831995-03-01 10:34:45 +00006974#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006975PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006976"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006977Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006978
Barry Warsaw53699e91996-12-10 23:23:01 +00006979static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006980posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006981{
Victor Stinner8c62be82010-05-06 00:08:46 +00006982 pid_t pid;
6983 WAIT_TYPE status;
6984 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006985
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 Py_BEGIN_ALLOW_THREADS
6987 pid = wait(&status);
6988 Py_END_ALLOW_THREADS
6989 if (pid == -1)
6990 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006991
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006993}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006994#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006995
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006996
Larry Hastings9cf065c2012-06-22 16:30:09 -07006997#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6998PyDoc_STRVAR(readlink__doc__,
6999"readlink(path, *, dir_fd=None) -> path\n\n\
7000Return a string representing the path to which the symbolic link points.\n\
7001\n\
7002If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7003 and path should be relative; path will then be relative to that directory.\n\
7004dir_fd may not be implemented on your platform.\n\
7005 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007006#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007007
Guido van Rossumb6775db1994-08-01 11:34:53 +00007008#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007009
Barry Warsaw53699e91996-12-10 23:23:01 +00007010static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007011posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007012{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007013 path_t path;
7014 int dir_fd = DEFAULT_DIR_FD;
7015 char buffer[MAXPATHLEN];
7016 ssize_t length;
7017 PyObject *return_value = NULL;
7018 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007019
Larry Hastings9cf065c2012-06-22 16:30:09 -07007020 memset(&path, 0, sizeof(path));
7021 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7022 path_converter, &path,
7023#ifdef HAVE_READLINKAT
7024 dir_fd_converter, &dir_fd
7025#else
7026 dir_fd_unavailable, &dir_fd
7027#endif
7028 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007029 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007030
Victor Stinner8c62be82010-05-06 00:08:46 +00007031 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007032#ifdef HAVE_READLINKAT
7033 if (dir_fd != DEFAULT_DIR_FD)
7034 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007035 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007036#endif
7037 length = readlink(path.narrow, buffer, sizeof(buffer));
7038 Py_END_ALLOW_THREADS
7039
7040 if (length < 0) {
7041 return_value = path_posix_error("readlink", &path);
7042 goto exit;
7043 }
7044
7045 if (PyUnicode_Check(path.object))
7046 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7047 else
7048 return_value = PyBytes_FromStringAndSize(buffer, length);
7049exit:
7050 path_cleanup(&path);
7051 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007052}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007053
7054
Guido van Rossumb6775db1994-08-01 11:34:53 +00007055#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007057
Larry Hastings9cf065c2012-06-22 16:30:09 -07007058#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007059PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007060"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7061Create a symbolic link pointing to src named dst.\n\n\
7062target_is_directory is required on Windows if the target is to be\n\
7063 interpreted as a directory. (On Windows, symlink requires\n\
7064 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7065 target_is_directory is ignored on non-Windows platforms.\n\
7066\n\
7067If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7068 and path should be relative; path will then be relative to that directory.\n\
7069dir_fd may not be implemented on your platform.\n\
7070 If it is unavailable, using it will raise a NotImplementedError.");
7071
7072#if defined(MS_WINDOWS)
7073
7074/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7075static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7076static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7077static int
7078check_CreateSymbolicLink()
7079{
7080 HINSTANCE hKernel32;
7081 /* only recheck */
7082 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7083 return 1;
7084 hKernel32 = GetModuleHandleW(L"KERNEL32");
7085 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7086 "CreateSymbolicLinkW");
7087 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7088 "CreateSymbolicLinkA");
7089 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7090}
7091
7092#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007093
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007094static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007095posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007096{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007097 path_t src;
7098 path_t dst;
7099 int dir_fd = DEFAULT_DIR_FD;
7100 int target_is_directory = 0;
7101 static char *keywords[] = {"src", "dst", "target_is_directory",
7102 "dir_fd", NULL};
7103 PyObject *return_value;
7104#ifdef MS_WINDOWS
7105 DWORD result;
7106#else
7107 int result;
7108#endif
7109
7110 memset(&src, 0, sizeof(src));
7111 src.argument_name = "src";
7112 memset(&dst, 0, sizeof(dst));
7113 dst.argument_name = "dst";
7114
7115#ifdef MS_WINDOWS
7116 if (!check_CreateSymbolicLink()) {
7117 PyErr_SetString(PyExc_NotImplementedError,
7118 "CreateSymbolicLink functions not found");
7119 return NULL;
7120 }
7121 if (!win32_can_symlink) {
7122 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
7123 return NULL;
7124 }
7125#endif
7126
7127 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7128 keywords,
7129 path_converter, &src,
7130 path_converter, &dst,
7131 &target_is_directory,
7132#ifdef HAVE_SYMLINKAT
7133 dir_fd_converter, &dir_fd
7134#else
7135 dir_fd_unavailable, &dir_fd
7136#endif
7137 ))
7138 return NULL;
7139
7140 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7141 PyErr_SetString(PyExc_ValueError,
7142 "symlink: src and dst must be the same type");
7143 return_value = NULL;
7144 goto exit;
7145 }
7146
7147#ifdef MS_WINDOWS
7148 Py_BEGIN_ALLOW_THREADS
7149 if (dst.wide)
7150 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7151 target_is_directory);
7152 else
7153 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7154 target_is_directory);
7155 Py_END_ALLOW_THREADS
7156
7157 if (!result) {
7158 return_value = win32_error_object("symlink", src.object);
7159 goto exit;
7160 }
7161
7162#else
7163
7164 Py_BEGIN_ALLOW_THREADS
7165#if HAVE_SYMLINKAT
7166 if (dir_fd != DEFAULT_DIR_FD)
7167 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7168 else
7169#endif
7170 result = symlink(src.narrow, dst.narrow);
7171 Py_END_ALLOW_THREADS
7172
7173 if (result) {
7174 return_value = path_error("symlink", &dst);
7175 goto exit;
7176 }
7177#endif
7178
7179 return_value = Py_None;
7180 Py_INCREF(Py_None);
7181 goto exit; /* silence "unused label" warning */
7182exit:
7183 path_cleanup(&src);
7184 path_cleanup(&dst);
7185 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007186}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007187
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007188#endif /* HAVE_SYMLINK */
7189
Larry Hastings9cf065c2012-06-22 16:30:09 -07007190
Brian Curtind40e6f72010-07-08 21:39:08 +00007191#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7192
Brian Curtind40e6f72010-07-08 21:39:08 +00007193static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007194win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007195{
7196 wchar_t *path;
7197 DWORD n_bytes_returned;
7198 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007199 PyObject *po, *result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007200 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007201 HANDLE reparse_point_handle;
7202
7203 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7204 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7205 wchar_t *print_name;
7206
Larry Hastings9cf065c2012-06-22 16:30:09 -07007207 static char *keywords[] = {"path", "dir_fd", NULL};
7208
7209 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7210 &po,
7211 dir_fd_unavailable, &dir_fd
7212 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007213 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007214
Victor Stinnereb5657a2011-09-30 01:44:27 +02007215 path = PyUnicode_AsUnicode(po);
7216 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007217 return NULL;
7218
7219 /* First get a handle to the reparse point */
7220 Py_BEGIN_ALLOW_THREADS
7221 reparse_point_handle = CreateFileW(
7222 path,
7223 0,
7224 0,
7225 0,
7226 OPEN_EXISTING,
7227 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7228 0);
7229 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007230
Brian Curtind40e6f72010-07-08 21:39:08 +00007231 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007232 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007233
Brian Curtind40e6f72010-07-08 21:39:08 +00007234 Py_BEGIN_ALLOW_THREADS
7235 /* New call DeviceIoControl to read the reparse point */
7236 io_result = DeviceIoControl(
7237 reparse_point_handle,
7238 FSCTL_GET_REPARSE_POINT,
7239 0, 0, /* in buffer */
7240 target_buffer, sizeof(target_buffer),
7241 &n_bytes_returned,
7242 0 /* we're not using OVERLAPPED_IO */
7243 );
7244 CloseHandle(reparse_point_handle);
7245 Py_END_ALLOW_THREADS
7246
7247 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007248 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007249
7250 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7251 {
7252 PyErr_SetString(PyExc_ValueError,
7253 "not a symbolic link");
7254 return NULL;
7255 }
Brian Curtin74e45612010-07-09 15:58:59 +00007256 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7257 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7258
7259 result = PyUnicode_FromWideChar(print_name,
7260 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007261 return result;
7262}
7263
7264#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7265
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007266
Larry Hastings605a62d2012-06-24 04:33:36 -07007267static PyStructSequence_Field times_result_fields[] = {
7268 {"user", "user time"},
7269 {"system", "system time"},
7270 {"children_user", "user time of children"},
7271 {"children_system", "system time of children"},
7272 {"elapsed", "elapsed time since an arbitrary point in the past"},
7273 {NULL}
7274};
7275
7276PyDoc_STRVAR(times_result__doc__,
7277"times_result: Result from os.times().\n\n\
7278This object may be accessed either as a tuple of\n\
7279 (user, system, children_user, children_system, elapsed),\n\
7280or via the attributes user, system, children_user, children_system,\n\
7281and elapsed.\n\
7282\n\
7283See os.times for more information.");
7284
7285static PyStructSequence_Desc times_result_desc = {
7286 "times_result", /* name */
7287 times_result__doc__, /* doc */
7288 times_result_fields,
7289 5
7290};
7291
7292static PyTypeObject TimesResultType;
7293
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007294#ifdef MS_WINDOWS
7295#define HAVE_TIMES /* mandatory, for the method table */
7296#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007297
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007298#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007299
7300static PyObject *
7301build_times_result(double user, double system,
7302 double children_user, double children_system,
7303 double elapsed)
7304{
7305 PyObject *value = PyStructSequence_New(&TimesResultType);
7306 if (value == NULL)
7307 return NULL;
7308
7309#define SET(i, field) \
7310 { \
7311 PyObject *o = PyFloat_FromDouble(field); \
7312 if (!o) { \
7313 Py_DECREF(value); \
7314 return NULL; \
7315 } \
7316 PyStructSequence_SET_ITEM(value, i, o); \
7317 } \
7318
7319 SET(0, user);
7320 SET(1, system);
7321 SET(2, children_user);
7322 SET(3, children_system);
7323 SET(4, elapsed);
7324
7325#undef SET
7326
7327 return value;
7328}
7329
7330PyDoc_STRVAR(posix_times__doc__,
7331"times() -> times_result\n\n\
7332Return an object containing floating point numbers indicating process\n\
7333times. The object behaves like a named tuple with these fields:\n\
7334 (utime, stime, cutime, cstime, elapsed_time)");
7335
Guido van Rossumd48f2521997-12-05 22:19:34 +00007336#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7337static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007338system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007339{
7340 ULONG value = 0;
7341
7342 Py_BEGIN_ALLOW_THREADS
7343 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7344 Py_END_ALLOW_THREADS
7345
7346 return value;
7347}
7348
7349static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007350posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007351{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007352 /* Currently Only Uptime is Provided -- Others Later */
Larry Hastings605a62d2012-06-24 04:33:36 -07007353 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007354 (double)0 /* t.tms_utime / HZ */,
7355 (double)0 /* t.tms_stime / HZ */,
7356 (double)0 /* t.tms_cutime / HZ */,
7357 (double)0 /* t.tms_cstime / HZ */,
7358 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007359}
Larry Hastings605a62d2012-06-24 04:33:36 -07007360#elif defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007361static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007362posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007363{
Victor Stinner8c62be82010-05-06 00:08:46 +00007364 FILETIME create, exit, kernel, user;
7365 HANDLE hProc;
7366 hProc = GetCurrentProcess();
7367 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7368 /* The fields of a FILETIME structure are the hi and lo part
7369 of a 64-bit value expressed in 100 nanosecond units.
7370 1e7 is one second in such units; 1e-7 the inverse.
7371 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7372 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007373 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007374 (double)(user.dwHighDateTime*429.4967296 +
7375 user.dwLowDateTime*1e-7),
7376 (double)(kernel.dwHighDateTime*429.4967296 +
7377 kernel.dwLowDateTime*1e-7),
7378 (double)0,
7379 (double)0,
7380 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007381}
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007382#else /* Neither Windows nor OS/2 */
7383#define NEED_TICKS_PER_SECOND
7384static long ticks_per_second = -1;
7385static PyObject *
7386posix_times(PyObject *self, PyObject *noargs)
7387{
7388 struct tms t;
7389 clock_t c;
7390 errno = 0;
7391 c = times(&t);
7392 if (c == (clock_t) -1)
7393 return posix_error();
7394 return build_times_result(
7395 (double)t.tms_utime / ticks_per_second,
7396 (double)t.tms_stime / ticks_per_second,
7397 (double)t.tms_cutime / ticks_per_second,
7398 (double)t.tms_cstime / ticks_per_second,
7399 (double)c / ticks_per_second);
7400}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007401#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007402
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007403#endif /* HAVE_TIMES */
7404
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007405
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007406#ifdef HAVE_GETSID
7407PyDoc_STRVAR(posix_getsid__doc__,
7408"getsid(pid) -> sid\n\n\
7409Call the system call getsid().");
7410
7411static PyObject *
7412posix_getsid(PyObject *self, PyObject *args)
7413{
Victor Stinner8c62be82010-05-06 00:08:46 +00007414 pid_t pid;
7415 int sid;
7416 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7417 return NULL;
7418 sid = getsid(pid);
7419 if (sid < 0)
7420 return posix_error();
7421 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007422}
7423#endif /* HAVE_GETSID */
7424
7425
Guido van Rossumb6775db1994-08-01 11:34:53 +00007426#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007427PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007428"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007429Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007430
Barry Warsaw53699e91996-12-10 23:23:01 +00007431static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007432posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007433{
Victor Stinner8c62be82010-05-06 00:08:46 +00007434 if (setsid() < 0)
7435 return posix_error();
7436 Py_INCREF(Py_None);
7437 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007438}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007439#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007440
Guido van Rossumb6775db1994-08-01 11:34:53 +00007441#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007442PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007443"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007444Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007445
Barry Warsaw53699e91996-12-10 23:23:01 +00007446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007447posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007448{
Victor Stinner8c62be82010-05-06 00:08:46 +00007449 pid_t pid;
7450 int pgrp;
7451 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7452 return NULL;
7453 if (setpgid(pid, pgrp) < 0)
7454 return posix_error();
7455 Py_INCREF(Py_None);
7456 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007457}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007458#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007459
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007460
Guido van Rossumb6775db1994-08-01 11:34:53 +00007461#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007462PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007463"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007464Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007465
Barry Warsaw53699e91996-12-10 23:23:01 +00007466static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007467posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007468{
Victor Stinner8c62be82010-05-06 00:08:46 +00007469 int fd;
7470 pid_t pgid;
7471 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7472 return NULL;
7473 pgid = tcgetpgrp(fd);
7474 if (pgid < 0)
7475 return posix_error();
7476 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007477}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007478#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007479
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007480
Guido van Rossumb6775db1994-08-01 11:34:53 +00007481#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007482PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007483"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007484Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007485
Barry Warsaw53699e91996-12-10 23:23:01 +00007486static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007487posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007488{
Victor Stinner8c62be82010-05-06 00:08:46 +00007489 int fd;
7490 pid_t pgid;
7491 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7492 return NULL;
7493 if (tcsetpgrp(fd, pgid) < 0)
7494 return posix_error();
7495 Py_INCREF(Py_None);
7496 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007497}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007498#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007499
Guido van Rossum687dd131993-05-17 08:34:16 +00007500/* Functions acting on file descriptors */
7501
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007502PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007503"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7504Open a file for low level IO. Returns a file handle (integer).\n\
7505\n\
7506If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7507 and path should be relative; path will then be relative to that directory.\n\
7508dir_fd may not be implemented on your platform.\n\
7509 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007510
Barry Warsaw53699e91996-12-10 23:23:01 +00007511static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007512posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007513{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007514 path_t path;
7515 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007516 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007517 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007518 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007519 PyObject *return_value = NULL;
7520 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007521
Larry Hastings9cf065c2012-06-22 16:30:09 -07007522 memset(&path, 0, sizeof(path));
7523 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7524 path_converter, &path,
7525 &flags, &mode,
7526#ifdef HAVE_OPENAT
7527 dir_fd_converter, &dir_fd
7528#else
7529 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007530#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007531 ))
7532 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007533
Victor Stinner8c62be82010-05-06 00:08:46 +00007534 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007535#ifdef MS_WINDOWS
7536 if (path.wide)
7537 fd = _wopen(path.wide, flags, mode);
7538 else
7539#endif
7540#ifdef HAVE_OPENAT
7541 if (dir_fd != DEFAULT_DIR_FD)
7542 fd = openat(dir_fd, path.narrow, flags, mode);
7543 else
7544#endif
7545 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007546 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007547
Larry Hastings9cf065c2012-06-22 16:30:09 -07007548 if (fd == -1) {
7549#ifdef MS_WINDOWS
7550 /* force use of posix_error here for exact backwards compatibility */
7551 if (path.wide)
7552 return_value = posix_error();
7553 else
7554#endif
7555 return_value = path_error("open", &path);
7556 goto exit;
7557 }
7558
7559 return_value = PyLong_FromLong((long)fd);
7560
7561exit:
7562 path_cleanup(&path);
7563 return return_value;
7564}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007565
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007566PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007567"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007568Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007569
Barry Warsaw53699e91996-12-10 23:23:01 +00007570static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007571posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007572{
Victor Stinner8c62be82010-05-06 00:08:46 +00007573 int fd, res;
7574 if (!PyArg_ParseTuple(args, "i:close", &fd))
7575 return NULL;
7576 if (!_PyVerify_fd(fd))
7577 return posix_error();
7578 Py_BEGIN_ALLOW_THREADS
7579 res = close(fd);
7580 Py_END_ALLOW_THREADS
7581 if (res < 0)
7582 return posix_error();
7583 Py_INCREF(Py_None);
7584 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007585}
7586
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007587
Victor Stinner8c62be82010-05-06 00:08:46 +00007588PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007589"closerange(fd_low, fd_high)\n\n\
7590Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7591
7592static PyObject *
7593posix_closerange(PyObject *self, PyObject *args)
7594{
Victor Stinner8c62be82010-05-06 00:08:46 +00007595 int fd_from, fd_to, i;
7596 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7597 return NULL;
7598 Py_BEGIN_ALLOW_THREADS
7599 for (i = fd_from; i < fd_to; i++)
7600 if (_PyVerify_fd(i))
7601 close(i);
7602 Py_END_ALLOW_THREADS
7603 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007604}
7605
7606
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007607PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007608"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007609Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007610
Barry Warsaw53699e91996-12-10 23:23:01 +00007611static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007612posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007613{
Victor Stinner8c62be82010-05-06 00:08:46 +00007614 int fd;
7615 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7616 return NULL;
7617 if (!_PyVerify_fd(fd))
7618 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007619 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007620 if (fd < 0)
7621 return posix_error();
7622 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007623}
7624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007625
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007626PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007627"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007628Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007629
Barry Warsaw53699e91996-12-10 23:23:01 +00007630static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007631posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007632{
Victor Stinner8c62be82010-05-06 00:08:46 +00007633 int fd, fd2, res;
7634 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7635 return NULL;
7636 if (!_PyVerify_fd_dup2(fd, fd2))
7637 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007639 if (res < 0)
7640 return posix_error();
7641 Py_INCREF(Py_None);
7642 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007643}
7644
Ross Lagerwall7807c352011-03-17 20:20:30 +02007645#ifdef HAVE_LOCKF
7646PyDoc_STRVAR(posix_lockf__doc__,
7647"lockf(fd, cmd, len)\n\n\
7648Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7649fd is an open file descriptor.\n\
7650cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7651F_TEST.\n\
7652len specifies the section of the file to lock.");
7653
7654static PyObject *
7655posix_lockf(PyObject *self, PyObject *args)
7656{
7657 int fd, cmd, res;
7658 off_t len;
7659 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7660 &fd, &cmd, _parse_off_t, &len))
7661 return NULL;
7662
7663 Py_BEGIN_ALLOW_THREADS
7664 res = lockf(fd, cmd, len);
7665 Py_END_ALLOW_THREADS
7666
7667 if (res < 0)
7668 return posix_error();
7669
7670 Py_RETURN_NONE;
7671}
7672#endif
7673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007674
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007675PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007676"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007677Set the current position of a file descriptor.\n\
7678Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007679
Barry Warsaw53699e91996-12-10 23:23:01 +00007680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007681posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007682{
Victor Stinner8c62be82010-05-06 00:08:46 +00007683 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007684#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007685 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007686#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007687 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007688#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007689 PyObject *posobj;
7690 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007691 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007692#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007693 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7694 switch (how) {
7695 case 0: how = SEEK_SET; break;
7696 case 1: how = SEEK_CUR; break;
7697 case 2: how = SEEK_END; break;
7698 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007699#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007700
Ross Lagerwall8e749672011-03-17 21:54:07 +02007701#if !defined(HAVE_LARGEFILE_SUPPORT)
7702 pos = PyLong_AsLong(posobj);
7703#else
7704 pos = PyLong_AsLongLong(posobj);
7705#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007706 if (PyErr_Occurred())
7707 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007708
Victor Stinner8c62be82010-05-06 00:08:46 +00007709 if (!_PyVerify_fd(fd))
7710 return posix_error();
7711 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007712#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007713 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007714#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007715 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007716#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007717 Py_END_ALLOW_THREADS
7718 if (res < 0)
7719 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007720
7721#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007723#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007724 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007725#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007726}
7727
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007728
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007729PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007730"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007731Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007732
Barry Warsaw53699e91996-12-10 23:23:01 +00007733static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007734posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007735{
Victor Stinner8c62be82010-05-06 00:08:46 +00007736 int fd, size;
7737 Py_ssize_t n;
7738 PyObject *buffer;
7739 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7740 return NULL;
7741 if (size < 0) {
7742 errno = EINVAL;
7743 return posix_error();
7744 }
7745 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7746 if (buffer == NULL)
7747 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007748 if (!_PyVerify_fd(fd)) {
7749 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007751 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007752 Py_BEGIN_ALLOW_THREADS
7753 n = read(fd, PyBytes_AS_STRING(buffer), size);
7754 Py_END_ALLOW_THREADS
7755 if (n < 0) {
7756 Py_DECREF(buffer);
7757 return posix_error();
7758 }
7759 if (n != size)
7760 _PyBytes_Resize(&buffer, n);
7761 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007762}
7763
Ross Lagerwall7807c352011-03-17 20:20:30 +02007764#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7765 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007766static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007767iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7768{
7769 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007770 Py_ssize_t blen, total = 0;
7771
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007772 *iov = PyMem_New(struct iovec, cnt);
7773 if (*iov == NULL) {
7774 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007775 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007776 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007777
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007778 *buf = PyMem_New(Py_buffer, cnt);
7779 if (*buf == NULL) {
7780 PyMem_Del(*iov);
7781 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007782 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007783 }
7784
7785 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007786 PyObject *item = PySequence_GetItem(seq, i);
7787 if (item == NULL)
7788 goto fail;
7789 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7790 Py_DECREF(item);
7791 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007792 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007793 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007794 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007795 blen = (*buf)[i].len;
7796 (*iov)[i].iov_len = blen;
7797 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007798 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007799 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007800
7801fail:
7802 PyMem_Del(*iov);
7803 for (j = 0; j < i; j++) {
7804 PyBuffer_Release(&(*buf)[j]);
7805 }
7806 PyMem_Del(*buf);
7807 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007808}
7809
7810static void
7811iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7812{
7813 int i;
7814 PyMem_Del(iov);
7815 for (i = 0; i < cnt; i++) {
7816 PyBuffer_Release(&buf[i]);
7817 }
7818 PyMem_Del(buf);
7819}
7820#endif
7821
Ross Lagerwall7807c352011-03-17 20:20:30 +02007822#ifdef HAVE_READV
7823PyDoc_STRVAR(posix_readv__doc__,
7824"readv(fd, buffers) -> bytesread\n\n\
7825Read from a file descriptor into a number of writable buffers. buffers\n\
7826is an arbitrary sequence of writable buffers.\n\
7827Returns the total number of bytes read.");
7828
7829static PyObject *
7830posix_readv(PyObject *self, PyObject *args)
7831{
7832 int fd, cnt;
7833 Py_ssize_t n;
7834 PyObject *seq;
7835 struct iovec *iov;
7836 Py_buffer *buf;
7837
7838 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7839 return NULL;
7840 if (!PySequence_Check(seq)) {
7841 PyErr_SetString(PyExc_TypeError,
7842 "readv() arg 2 must be a sequence");
7843 return NULL;
7844 }
7845 cnt = PySequence_Size(seq);
7846
7847 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7848 return NULL;
7849
7850 Py_BEGIN_ALLOW_THREADS
7851 n = readv(fd, iov, cnt);
7852 Py_END_ALLOW_THREADS
7853
7854 iov_cleanup(iov, buf, cnt);
7855 return PyLong_FromSsize_t(n);
7856}
7857#endif
7858
7859#ifdef HAVE_PREAD
7860PyDoc_STRVAR(posix_pread__doc__,
7861"pread(fd, buffersize, offset) -> string\n\n\
7862Read from a file descriptor, fd, at a position of offset. It will read up\n\
7863to buffersize number of bytes. The file offset remains unchanged.");
7864
7865static PyObject *
7866posix_pread(PyObject *self, PyObject *args)
7867{
7868 int fd, size;
7869 off_t offset;
7870 Py_ssize_t n;
7871 PyObject *buffer;
7872 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7873 return NULL;
7874
7875 if (size < 0) {
7876 errno = EINVAL;
7877 return posix_error();
7878 }
7879 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7880 if (buffer == NULL)
7881 return NULL;
7882 if (!_PyVerify_fd(fd)) {
7883 Py_DECREF(buffer);
7884 return posix_error();
7885 }
7886 Py_BEGIN_ALLOW_THREADS
7887 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7888 Py_END_ALLOW_THREADS
7889 if (n < 0) {
7890 Py_DECREF(buffer);
7891 return posix_error();
7892 }
7893 if (n != size)
7894 _PyBytes_Resize(&buffer, n);
7895 return buffer;
7896}
7897#endif
7898
7899PyDoc_STRVAR(posix_write__doc__,
7900"write(fd, string) -> byteswritten\n\n\
7901Write a string to a file descriptor.");
7902
7903static PyObject *
7904posix_write(PyObject *self, PyObject *args)
7905{
7906 Py_buffer pbuf;
7907 int fd;
7908 Py_ssize_t size, len;
7909
7910 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7911 return NULL;
7912 if (!_PyVerify_fd(fd)) {
7913 PyBuffer_Release(&pbuf);
7914 return posix_error();
7915 }
7916 len = pbuf.len;
7917 Py_BEGIN_ALLOW_THREADS
7918#if defined(MS_WIN64) || defined(MS_WINDOWS)
7919 if (len > INT_MAX)
7920 len = INT_MAX;
7921 size = write(fd, pbuf.buf, (int)len);
7922#else
7923 size = write(fd, pbuf.buf, len);
7924#endif
7925 Py_END_ALLOW_THREADS
7926 PyBuffer_Release(&pbuf);
7927 if (size < 0)
7928 return posix_error();
7929 return PyLong_FromSsize_t(size);
7930}
7931
7932#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007933PyDoc_STRVAR(posix_sendfile__doc__,
7934"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7935sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7936 -> byteswritten\n\
7937Copy nbytes bytes from file descriptor in to file descriptor out.");
7938
7939static PyObject *
7940posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7941{
7942 int in, out;
7943 Py_ssize_t ret;
7944 off_t offset;
7945
7946#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7947#ifndef __APPLE__
7948 Py_ssize_t len;
7949#endif
7950 PyObject *headers = NULL, *trailers = NULL;
7951 Py_buffer *hbuf, *tbuf;
7952 off_t sbytes;
7953 struct sf_hdtr sf;
7954 int flags = 0;
7955 sf.headers = NULL;
7956 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007957 static char *keywords[] = {"out", "in",
7958 "offset", "count",
7959 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007960
7961#ifdef __APPLE__
7962 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007963 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007964#else
7965 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007966 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007967#endif
7968 &headers, &trailers, &flags))
7969 return NULL;
7970 if (headers != NULL) {
7971 if (!PySequence_Check(headers)) {
7972 PyErr_SetString(PyExc_TypeError,
7973 "sendfile() headers must be a sequence or None");
7974 return NULL;
7975 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007976 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007977 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007978 if (sf.hdr_cnt > 0 &&
7979 !(i = iov_setup(&(sf.headers), &hbuf,
7980 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007981 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007982#ifdef __APPLE__
7983 sbytes += i;
7984#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007985 }
7986 }
7987 if (trailers != NULL) {
7988 if (!PySequence_Check(trailers)) {
7989 PyErr_SetString(PyExc_TypeError,
7990 "sendfile() trailers must be a sequence or None");
7991 return NULL;
7992 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007993 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007994 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007995 if (sf.trl_cnt > 0 &&
7996 !(i = iov_setup(&(sf.trailers), &tbuf,
7997 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007998 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007999#ifdef __APPLE__
8000 sbytes += i;
8001#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008002 }
8003 }
8004
8005 Py_BEGIN_ALLOW_THREADS
8006#ifdef __APPLE__
8007 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8008#else
8009 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8010#endif
8011 Py_END_ALLOW_THREADS
8012
8013 if (sf.headers != NULL)
8014 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8015 if (sf.trailers != NULL)
8016 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8017
8018 if (ret < 0) {
8019 if ((errno == EAGAIN) || (errno == EBUSY)) {
8020 if (sbytes != 0) {
8021 // some data has been sent
8022 goto done;
8023 }
8024 else {
8025 // no data has been sent; upper application is supposed
8026 // to retry on EAGAIN or EBUSY
8027 return posix_error();
8028 }
8029 }
8030 return posix_error();
8031 }
8032 goto done;
8033
8034done:
8035 #if !defined(HAVE_LARGEFILE_SUPPORT)
8036 return Py_BuildValue("l", sbytes);
8037 #else
8038 return Py_BuildValue("L", sbytes);
8039 #endif
8040
8041#else
8042 Py_ssize_t count;
8043 PyObject *offobj;
8044 static char *keywords[] = {"out", "in",
8045 "offset", "count", NULL};
8046 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8047 keywords, &out, &in, &offobj, &count))
8048 return NULL;
8049#ifdef linux
8050 if (offobj == Py_None) {
8051 Py_BEGIN_ALLOW_THREADS
8052 ret = sendfile(out, in, NULL, count);
8053 Py_END_ALLOW_THREADS
8054 if (ret < 0)
8055 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008056 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008057 }
8058#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008059 if (!_parse_off_t(offobj, &offset))
8060 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008061 Py_BEGIN_ALLOW_THREADS
8062 ret = sendfile(out, in, &offset, count);
8063 Py_END_ALLOW_THREADS
8064 if (ret < 0)
8065 return posix_error();
8066 return Py_BuildValue("n", ret);
8067#endif
8068}
8069#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008070
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008071PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008072"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008073Like stat(), but for an open file descriptor.\n\
8074Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008075
Barry Warsaw53699e91996-12-10 23:23:01 +00008076static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008077posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008078{
Victor Stinner8c62be82010-05-06 00:08:46 +00008079 int fd;
8080 STRUCT_STAT st;
8081 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008082 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008083 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008084#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008085 /* on OpenVMS we must ensure that all bytes are written to the file */
8086 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008087#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008088 Py_BEGIN_ALLOW_THREADS
8089 res = FSTAT(fd, &st);
8090 Py_END_ALLOW_THREADS
8091 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008092#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008093 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008094#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008095 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008096#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008097 }
Tim Peters5aa91602002-01-30 05:46:57 +00008098
Victor Stinner4195b5c2012-02-08 23:03:19 +01008099 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008100}
8101
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008102PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008103"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008104Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008105connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008106
8107static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008108posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008109{
Victor Stinner8c62be82010-05-06 00:08:46 +00008110 int fd;
8111 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8112 return NULL;
8113 if (!_PyVerify_fd(fd))
8114 return PyBool_FromLong(0);
8115 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008116}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008117
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008118#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008119PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008120"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008121Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008122
Barry Warsaw53699e91996-12-10 23:23:01 +00008123static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008124posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008125{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008126#if defined(PYOS_OS2)
8127 HFILE read, write;
8128 APIRET rc;
8129
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008130 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008131 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008132 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008133
8134 return Py_BuildValue("(ii)", read, write);
8135#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008136#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008137 int fds[2];
8138 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008139 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008140 if (res != 0)
8141 return posix_error();
8142 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008143#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008144 HANDLE read, write;
8145 int read_fd, write_fd;
8146 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008147 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008148 if (!ok)
8149 return win32_error("CreatePipe", NULL);
8150 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8151 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8152 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008153#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008154#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008155}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008156#endif /* HAVE_PIPE */
8157
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008158#ifdef HAVE_PIPE2
8159PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008160"pipe2(flags) -> (read_end, write_end)\n\n\
8161Create a pipe with flags set atomically.\n\
8162flags can be constructed by ORing together one or more of these values:\n\
8163O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008164");
8165
8166static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008167posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008168{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008169 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008170 int fds[2];
8171 int res;
8172
Charles-François Natali368f34b2011-06-06 19:49:47 +02008173 flags = PyLong_AsLong(arg);
8174 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008175 return NULL;
8176
8177 res = pipe2(fds, flags);
8178 if (res != 0)
8179 return posix_error();
8180 return Py_BuildValue("(ii)", fds[0], fds[1]);
8181}
8182#endif /* HAVE_PIPE2 */
8183
Ross Lagerwall7807c352011-03-17 20:20:30 +02008184#ifdef HAVE_WRITEV
8185PyDoc_STRVAR(posix_writev__doc__,
8186"writev(fd, buffers) -> byteswritten\n\n\
8187Write the contents of buffers to a file descriptor, where buffers is an\n\
8188arbitrary sequence of buffers.\n\
8189Returns the total bytes written.");
8190
8191static PyObject *
8192posix_writev(PyObject *self, PyObject *args)
8193{
8194 int fd, cnt;
8195 Py_ssize_t res;
8196 PyObject *seq;
8197 struct iovec *iov;
8198 Py_buffer *buf;
8199 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8200 return NULL;
8201 if (!PySequence_Check(seq)) {
8202 PyErr_SetString(PyExc_TypeError,
8203 "writev() arg 2 must be a sequence");
8204 return NULL;
8205 }
8206 cnt = PySequence_Size(seq);
8207
8208 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8209 return NULL;
8210 }
8211
8212 Py_BEGIN_ALLOW_THREADS
8213 res = writev(fd, iov, cnt);
8214 Py_END_ALLOW_THREADS
8215
8216 iov_cleanup(iov, buf, cnt);
8217 return PyLong_FromSsize_t(res);
8218}
8219#endif
8220
8221#ifdef HAVE_PWRITE
8222PyDoc_STRVAR(posix_pwrite__doc__,
8223"pwrite(fd, string, offset) -> byteswritten\n\n\
8224Write string to a file descriptor, fd, from offset, leaving the file\n\
8225offset unchanged.");
8226
8227static PyObject *
8228posix_pwrite(PyObject *self, PyObject *args)
8229{
8230 Py_buffer pbuf;
8231 int fd;
8232 off_t offset;
8233 Py_ssize_t size;
8234
8235 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8236 return NULL;
8237
8238 if (!_PyVerify_fd(fd)) {
8239 PyBuffer_Release(&pbuf);
8240 return posix_error();
8241 }
8242 Py_BEGIN_ALLOW_THREADS
8243 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8244 Py_END_ALLOW_THREADS
8245 PyBuffer_Release(&pbuf);
8246 if (size < 0)
8247 return posix_error();
8248 return PyLong_FromSsize_t(size);
8249}
8250#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008251
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008252#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008253PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008254"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8255Create a FIFO (a POSIX named pipe).\n\
8256\n\
8257If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8258 and path should be relative; path will then be relative to that directory.\n\
8259dir_fd may not be implemented on your platform.\n\
8260 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008261
Barry Warsaw53699e91996-12-10 23:23:01 +00008262static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008263posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008264{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008265 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008266 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008267 int dir_fd = DEFAULT_DIR_FD;
8268 int result;
8269 PyObject *return_value = NULL;
8270 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8271
8272 memset(&path, 0, sizeof(path));
8273 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8274 path_converter, &path,
8275 &mode,
8276#ifdef HAVE_MKFIFOAT
8277 dir_fd_converter, &dir_fd
8278#else
8279 dir_fd_unavailable, &dir_fd
8280#endif
8281 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008282 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008283
Victor Stinner8c62be82010-05-06 00:08:46 +00008284 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008285#ifdef HAVE_MKFIFOAT
8286 if (dir_fd != DEFAULT_DIR_FD)
8287 result = mkfifoat(dir_fd, path.narrow, mode);
8288 else
8289#endif
8290 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008291 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008292
8293 if (result < 0) {
8294 return_value = posix_error();
8295 goto exit;
8296 }
8297
8298 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008299 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008300
8301exit:
8302 path_cleanup(&path);
8303 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008304}
8305#endif
8306
Neal Norwitz11690112002-07-30 01:08:28 +00008307#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008308PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008309"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008310Create a filesystem node (file, device special file or named pipe)\n\
8311named filename. mode specifies both the permissions to use and the\n\
8312type of node to be created, being combined (bitwise OR) with one of\n\
8313S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008314device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008315os.makedev()), otherwise it is ignored.\n\
8316\n\
8317If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8318 and path should be relative; path will then be relative to that directory.\n\
8319dir_fd may not be implemented on your platform.\n\
8320 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008321
8322
8323static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008324posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008325{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008326 path_t path;
8327 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008328 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008329 int dir_fd = DEFAULT_DIR_FD;
8330 int result;
8331 PyObject *return_value = NULL;
8332 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8333
8334 memset(&path, 0, sizeof(path));
8335 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8336 path_converter, &path,
8337 &mode, &device,
8338#ifdef HAVE_MKNODAT
8339 dir_fd_converter, &dir_fd
8340#else
8341 dir_fd_unavailable, &dir_fd
8342#endif
8343 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008344 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008345
Victor Stinner8c62be82010-05-06 00:08:46 +00008346 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008347#ifdef HAVE_MKNODAT
8348 if (dir_fd != DEFAULT_DIR_FD)
8349 result = mknodat(dir_fd, path.narrow, mode, device);
8350 else
8351#endif
8352 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008353 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008354
8355 if (result < 0) {
8356 return_value = posix_error();
8357 goto exit;
8358 }
8359
8360 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008361 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008362
Larry Hastings9cf065c2012-06-22 16:30:09 -07008363exit:
8364 path_cleanup(&path);
8365 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008366}
8367#endif
8368
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008369#ifdef HAVE_DEVICE_MACROS
8370PyDoc_STRVAR(posix_major__doc__,
8371"major(device) -> major number\n\
8372Extracts a device major number from a raw device number.");
8373
8374static PyObject *
8375posix_major(PyObject *self, PyObject *args)
8376{
Victor Stinner8c62be82010-05-06 00:08:46 +00008377 int device;
8378 if (!PyArg_ParseTuple(args, "i:major", &device))
8379 return NULL;
8380 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008381}
8382
8383PyDoc_STRVAR(posix_minor__doc__,
8384"minor(device) -> minor number\n\
8385Extracts a device minor number from a raw device number.");
8386
8387static PyObject *
8388posix_minor(PyObject *self, PyObject *args)
8389{
Victor Stinner8c62be82010-05-06 00:08:46 +00008390 int device;
8391 if (!PyArg_ParseTuple(args, "i:minor", &device))
8392 return NULL;
8393 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008394}
8395
8396PyDoc_STRVAR(posix_makedev__doc__,
8397"makedev(major, minor) -> device number\n\
8398Composes a raw device number from the major and minor device numbers.");
8399
8400static PyObject *
8401posix_makedev(PyObject *self, PyObject *args)
8402{
Victor Stinner8c62be82010-05-06 00:08:46 +00008403 int major, minor;
8404 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8405 return NULL;
8406 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008407}
8408#endif /* device macros */
8409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008410
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008411#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008412PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008413"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008414Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008415
Barry Warsaw53699e91996-12-10 23:23:01 +00008416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008417posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008418{
Victor Stinner8c62be82010-05-06 00:08:46 +00008419 int fd;
8420 off_t length;
8421 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008422
Ross Lagerwall7807c352011-03-17 20:20:30 +02008423 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008424 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008425
Victor Stinner8c62be82010-05-06 00:08:46 +00008426 Py_BEGIN_ALLOW_THREADS
8427 res = ftruncate(fd, length);
8428 Py_END_ALLOW_THREADS
8429 if (res < 0)
8430 return posix_error();
8431 Py_INCREF(Py_None);
8432 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008433}
8434#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008435
Ross Lagerwall7807c352011-03-17 20:20:30 +02008436#ifdef HAVE_TRUNCATE
8437PyDoc_STRVAR(posix_truncate__doc__,
8438"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008439Truncate the file given by path to length bytes.\n\
8440On some platforms, path may also be specified as an open file descriptor.\n\
8441 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008442
8443static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008444posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008445{
Georg Brandl306336b2012-06-24 12:55:33 +02008446 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008447 off_t length;
8448 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008449 PyObject *result = NULL;
8450 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008451
Georg Brandl306336b2012-06-24 12:55:33 +02008452 memset(&path, 0, sizeof(path));
8453#ifdef HAVE_FTRUNCATE
8454 path.allow_fd = 1;
8455#endif
8456 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8457 path_converter, &path,
8458 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008459 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008460
8461 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008462#ifdef HAVE_FTRUNCATE
8463 if (path.fd != -1)
8464 res = ftruncate(path.fd, length);
8465 else
8466#endif
8467 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008468 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008469 if (res < 0)
Georg Brandl306336b2012-06-24 12:55:33 +02008470 result = path_posix_error("truncate", &path);
8471 else {
8472 Py_INCREF(Py_None);
8473 result = Py_None;
8474 }
8475 path_cleanup(&path);
8476 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008477}
8478#endif
8479
8480#ifdef HAVE_POSIX_FALLOCATE
8481PyDoc_STRVAR(posix_posix_fallocate__doc__,
8482"posix_fallocate(fd, offset, len)\n\n\
8483Ensures that enough disk space is allocated for the file specified by fd\n\
8484starting from offset and continuing for len bytes.");
8485
8486static PyObject *
8487posix_posix_fallocate(PyObject *self, PyObject *args)
8488{
8489 off_t len, offset;
8490 int res, fd;
8491
8492 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8493 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8494 return NULL;
8495
8496 Py_BEGIN_ALLOW_THREADS
8497 res = posix_fallocate(fd, offset, len);
8498 Py_END_ALLOW_THREADS
8499 if (res != 0) {
8500 errno = res;
8501 return posix_error();
8502 }
8503 Py_RETURN_NONE;
8504}
8505#endif
8506
8507#ifdef HAVE_POSIX_FADVISE
8508PyDoc_STRVAR(posix_posix_fadvise__doc__,
8509"posix_fadvise(fd, offset, len, advice)\n\n\
8510Announces an intention to access data in a specific pattern thus allowing\n\
8511the kernel to make optimizations.\n\
8512The advice applies to the region of the file specified by fd starting at\n\
8513offset and continuing for len bytes.\n\
8514advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8515POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8516POSIX_FADV_DONTNEED.");
8517
8518static PyObject *
8519posix_posix_fadvise(PyObject *self, PyObject *args)
8520{
8521 off_t len, offset;
8522 int res, fd, advice;
8523
8524 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8525 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8526 return NULL;
8527
8528 Py_BEGIN_ALLOW_THREADS
8529 res = posix_fadvise(fd, offset, len, advice);
8530 Py_END_ALLOW_THREADS
8531 if (res != 0) {
8532 errno = res;
8533 return posix_error();
8534 }
8535 Py_RETURN_NONE;
8536}
8537#endif
8538
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008539#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008540PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008541"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008542Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008543
Fred Drake762e2061999-08-26 17:23:54 +00008544/* Save putenv() parameters as values here, so we can collect them when they
8545 * get re-set with another call for the same key. */
8546static PyObject *posix_putenv_garbage;
8547
Tim Peters5aa91602002-01-30 05:46:57 +00008548static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008549posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008550{
Victor Stinner84ae1182010-05-06 22:05:07 +00008551 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008552#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008553 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008554 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008555
Victor Stinner8c62be82010-05-06 00:08:46 +00008556 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008557 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008558 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008559 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008560
Victor Stinner65170952011-11-22 22:16:17 +01008561 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008562 if (newstr == NULL) {
8563 PyErr_NoMemory();
8564 goto error;
8565 }
Victor Stinner65170952011-11-22 22:16:17 +01008566 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8567 PyErr_Format(PyExc_ValueError,
8568 "the environment variable is longer than %u characters",
8569 _MAX_ENV);
8570 goto error;
8571 }
8572
Victor Stinner8c62be82010-05-06 00:08:46 +00008573 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008574 if (newenv == NULL)
8575 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008576 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008577 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008578 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008579 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008580#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008581 PyObject *os1, *os2;
8582 char *s1, *s2;
8583 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008584
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008585 if (!PyArg_ParseTuple(args,
8586 "O&O&:putenv",
8587 PyUnicode_FSConverter, &os1,
8588 PyUnicode_FSConverter, &os2))
8589 return NULL;
8590 s1 = PyBytes_AsString(os1);
8591 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008592
Victor Stinner65170952011-11-22 22:16:17 +01008593 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008594 if (newstr == NULL) {
8595 PyErr_NoMemory();
8596 goto error;
8597 }
8598
Victor Stinner8c62be82010-05-06 00:08:46 +00008599 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008600 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008601 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008602 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008603 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008604#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008605
Victor Stinner8c62be82010-05-06 00:08:46 +00008606 /* Install the first arg and newstr in posix_putenv_garbage;
8607 * this will cause previous value to be collected. This has to
8608 * happen after the real putenv() call because the old value
8609 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008610 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008611 /* really not much we can do; just leak */
8612 PyErr_Clear();
8613 }
8614 else {
8615 Py_DECREF(newstr);
8616 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008617
Martin v. Löwis011e8422009-05-05 04:43:17 +00008618#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008619 Py_DECREF(os1);
8620 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008621#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008622 Py_RETURN_NONE;
8623
8624error:
8625#ifndef MS_WINDOWS
8626 Py_DECREF(os1);
8627 Py_DECREF(os2);
8628#endif
8629 Py_XDECREF(newstr);
8630 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008631}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008632#endif /* putenv */
8633
Guido van Rossumc524d952001-10-19 01:31:59 +00008634#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008635PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008636"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008637Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008638
8639static PyObject *
8640posix_unsetenv(PyObject *self, PyObject *args)
8641{
Victor Stinner65170952011-11-22 22:16:17 +01008642 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008643#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008644 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008645#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008646
8647 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008648
Victor Stinner65170952011-11-22 22:16:17 +01008649 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008650 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008651
Victor Stinner984890f2011-11-24 13:53:38 +01008652#ifdef HAVE_BROKEN_UNSETENV
8653 unsetenv(PyBytes_AS_STRING(name));
8654#else
Victor Stinner65170952011-11-22 22:16:17 +01008655 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008656 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008657 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008658 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008659 }
Victor Stinner984890f2011-11-24 13:53:38 +01008660#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008661
Victor Stinner8c62be82010-05-06 00:08:46 +00008662 /* Remove the key from posix_putenv_garbage;
8663 * this will cause it to be collected. This has to
8664 * happen after the real unsetenv() call because the
8665 * old value was still accessible until then.
8666 */
Victor Stinner65170952011-11-22 22:16:17 +01008667 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008668 /* really not much we can do; just leak */
8669 PyErr_Clear();
8670 }
Victor Stinner65170952011-11-22 22:16:17 +01008671 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008672 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008673}
8674#endif /* unsetenv */
8675
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008676PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008677"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008678Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008679
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008681posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008682{
Victor Stinner8c62be82010-05-06 00:08:46 +00008683 int code;
8684 char *message;
8685 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8686 return NULL;
8687 message = strerror(code);
8688 if (message == NULL) {
8689 PyErr_SetString(PyExc_ValueError,
8690 "strerror() argument out of range");
8691 return NULL;
8692 }
Victor Stinner1b579672011-12-17 05:47:23 +01008693 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008694}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008695
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008696
Guido van Rossumc9641791998-08-04 15:26:23 +00008697#ifdef HAVE_SYS_WAIT_H
8698
Fred Drake106c1a02002-04-23 15:58:02 +00008699#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008700PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008701"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008702Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008703
8704static PyObject *
8705posix_WCOREDUMP(PyObject *self, PyObject *args)
8706{
Victor Stinner8c62be82010-05-06 00:08:46 +00008707 WAIT_TYPE status;
8708 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008709
Victor Stinner8c62be82010-05-06 00:08:46 +00008710 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8711 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008712
Victor Stinner8c62be82010-05-06 00:08:46 +00008713 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008714}
8715#endif /* WCOREDUMP */
8716
8717#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008718PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008719"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008720Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008721job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008722
8723static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008724posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008725{
Victor Stinner8c62be82010-05-06 00:08:46 +00008726 WAIT_TYPE status;
8727 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008728
Victor Stinner8c62be82010-05-06 00:08:46 +00008729 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8730 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008731
Victor Stinner8c62be82010-05-06 00:08:46 +00008732 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008733}
8734#endif /* WIFCONTINUED */
8735
Guido van Rossumc9641791998-08-04 15:26:23 +00008736#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008737PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008738"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008739Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008740
8741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008742posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008743{
Victor Stinner8c62be82010-05-06 00:08:46 +00008744 WAIT_TYPE status;
8745 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008746
Victor Stinner8c62be82010-05-06 00:08:46 +00008747 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8748 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008749
Victor Stinner8c62be82010-05-06 00:08:46 +00008750 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008751}
8752#endif /* WIFSTOPPED */
8753
8754#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008755PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008756"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008757Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008758
8759static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008760posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008761{
Victor Stinner8c62be82010-05-06 00:08:46 +00008762 WAIT_TYPE status;
8763 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008764
Victor Stinner8c62be82010-05-06 00:08:46 +00008765 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8766 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008767
Victor Stinner8c62be82010-05-06 00:08:46 +00008768 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008769}
8770#endif /* WIFSIGNALED */
8771
8772#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008773PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008774"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008775Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008776system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008777
8778static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008779posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008780{
Victor Stinner8c62be82010-05-06 00:08:46 +00008781 WAIT_TYPE status;
8782 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008783
Victor Stinner8c62be82010-05-06 00:08:46 +00008784 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8785 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008786
Victor Stinner8c62be82010-05-06 00:08:46 +00008787 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008788}
8789#endif /* WIFEXITED */
8790
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008791#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008792PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008793"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008794Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008795
8796static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008797posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008798{
Victor Stinner8c62be82010-05-06 00:08:46 +00008799 WAIT_TYPE status;
8800 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008801
Victor Stinner8c62be82010-05-06 00:08:46 +00008802 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8803 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008804
Victor Stinner8c62be82010-05-06 00:08:46 +00008805 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008806}
8807#endif /* WEXITSTATUS */
8808
8809#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008810PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008811"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008812Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008813value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008814
8815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008816posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008817{
Victor Stinner8c62be82010-05-06 00:08:46 +00008818 WAIT_TYPE status;
8819 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008820
Victor Stinner8c62be82010-05-06 00:08:46 +00008821 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8822 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008823
Victor Stinner8c62be82010-05-06 00:08:46 +00008824 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008825}
8826#endif /* WTERMSIG */
8827
8828#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008829PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008830"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008831Return the signal that stopped the process that provided\n\
8832the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008833
8834static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008835posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008836{
Victor Stinner8c62be82010-05-06 00:08:46 +00008837 WAIT_TYPE status;
8838 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008839
Victor Stinner8c62be82010-05-06 00:08:46 +00008840 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8841 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008842
Victor Stinner8c62be82010-05-06 00:08:46 +00008843 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008844}
8845#endif /* WSTOPSIG */
8846
8847#endif /* HAVE_SYS_WAIT_H */
8848
8849
Thomas Wouters477c8d52006-05-27 19:21:47 +00008850#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008851#ifdef _SCO_DS
8852/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8853 needed definitions in sys/statvfs.h */
8854#define _SVID3
8855#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008856#include <sys/statvfs.h>
8857
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008858static PyObject*
8859_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008860 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8861 if (v == NULL)
8862 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008863
8864#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008865 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8866 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8867 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8868 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8869 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8870 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8871 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8872 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8873 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8874 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008875#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008876 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8877 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8878 PyStructSequence_SET_ITEM(v, 2,
8879 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8880 PyStructSequence_SET_ITEM(v, 3,
8881 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8882 PyStructSequence_SET_ITEM(v, 4,
8883 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8884 PyStructSequence_SET_ITEM(v, 5,
8885 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8886 PyStructSequence_SET_ITEM(v, 6,
8887 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8888 PyStructSequence_SET_ITEM(v, 7,
8889 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8890 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8891 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008892#endif
8893
Victor Stinner8c62be82010-05-06 00:08:46 +00008894 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008895}
8896
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008897PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008898"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008899Perform an fstatvfs system call on the given fd.\n\
8900Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008901
8902static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008903posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008904{
Victor Stinner8c62be82010-05-06 00:08:46 +00008905 int fd, res;
8906 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008907
Victor Stinner8c62be82010-05-06 00:08:46 +00008908 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8909 return NULL;
8910 Py_BEGIN_ALLOW_THREADS
8911 res = fstatvfs(fd, &st);
8912 Py_END_ALLOW_THREADS
8913 if (res != 0)
8914 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008915
Victor Stinner8c62be82010-05-06 00:08:46 +00008916 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008917}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008918#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008919
8920
Thomas Wouters477c8d52006-05-27 19:21:47 +00008921#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008922#include <sys/statvfs.h>
8923
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008924PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008925"statvfs(path)\n\n\
8926Perform a statvfs system call on the given path.\n\
8927\n\
8928path may always be specified as a string.\n\
8929On some platforms, path may also be specified as an open file descriptor.\n\
8930 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008931
8932static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008933posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008934{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008935 static char *keywords[] = {"path", NULL};
8936 path_t path;
8937 int result;
8938 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008939 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008940
Larry Hastings9cf065c2012-06-22 16:30:09 -07008941 memset(&path, 0, sizeof(path));
8942#ifdef HAVE_FSTATVFS
8943 path.allow_fd = 1;
8944#endif
8945 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8946 path_converter, &path
8947 ))
8948 return NULL;
8949
8950 Py_BEGIN_ALLOW_THREADS
8951#ifdef HAVE_FSTATVFS
8952 if (path.fd != -1) {
8953#ifdef __APPLE__
8954 /* handle weak-linking on Mac OS X 10.3 */
8955 if (fstatvfs == NULL) {
8956 fd_specified("statvfs", path.fd);
8957 goto exit;
8958 }
8959#endif
8960 result = fstatvfs(path.fd, &st);
8961 }
8962 else
8963#endif
8964 result = statvfs(path.narrow, &st);
8965 Py_END_ALLOW_THREADS
8966
8967 if (result) {
8968 return_value = path_posix_error("statvfs", &path);
8969 goto exit;
8970 }
8971
8972 return_value = _pystatvfs_fromstructstatvfs(st);
8973
8974exit:
8975 path_cleanup(&path);
8976 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008977}
8978#endif /* HAVE_STATVFS */
8979
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008980#ifdef MS_WINDOWS
8981PyDoc_STRVAR(win32__getdiskusage__doc__,
8982"_getdiskusage(path) -> (total, free)\n\n\
8983Return disk usage statistics about the given path as (total, free) tuple.");
8984
8985static PyObject *
8986win32__getdiskusage(PyObject *self, PyObject *args)
8987{
8988 BOOL retval;
8989 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008990 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008991
Victor Stinner6139c1b2011-11-09 22:14:14 +01008992 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008993 return NULL;
8994
8995 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008996 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008997 Py_END_ALLOW_THREADS
8998 if (retval == 0)
8999 return PyErr_SetFromWindowsErr(0);
9000
9001 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9002}
9003#endif
9004
9005
Fred Drakec9680921999-12-13 16:37:25 +00009006/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9007 * It maps strings representing configuration variable names to
9008 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009009 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009010 * rarely-used constants. There are three separate tables that use
9011 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009012 *
9013 * This code is always included, even if none of the interfaces that
9014 * need it are included. The #if hackery needed to avoid it would be
9015 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009016 */
9017struct constdef {
9018 char *name;
9019 long value;
9020};
9021
Fred Drake12c6e2d1999-12-14 21:25:03 +00009022static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009023conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009024 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009025{
Christian Heimes217cfd12007-12-02 14:31:20 +00009026 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009027 *valuep = PyLong_AS_LONG(arg);
9028 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009029 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009030 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009031 /* look up the value in the table using a binary search */
9032 size_t lo = 0;
9033 size_t mid;
9034 size_t hi = tablesize;
9035 int cmp;
9036 const char *confname;
9037 if (!PyUnicode_Check(arg)) {
9038 PyErr_SetString(PyExc_TypeError,
9039 "configuration names must be strings or integers");
9040 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009041 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009042 confname = _PyUnicode_AsString(arg);
9043 if (confname == NULL)
9044 return 0;
9045 while (lo < hi) {
9046 mid = (lo + hi) / 2;
9047 cmp = strcmp(confname, table[mid].name);
9048 if (cmp < 0)
9049 hi = mid;
9050 else if (cmp > 0)
9051 lo = mid + 1;
9052 else {
9053 *valuep = table[mid].value;
9054 return 1;
9055 }
9056 }
9057 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9058 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009059 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009060}
9061
9062
9063#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9064static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009065#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009067#endif
9068#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009070#endif
Fred Drakec9680921999-12-13 16:37:25 +00009071#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009072 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009073#endif
9074#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009075 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009076#endif
9077#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009078 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009079#endif
9080#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009082#endif
9083#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009084 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009085#endif
9086#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009088#endif
9089#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009090 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009091#endif
9092#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009093 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009094#endif
9095#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009096 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009097#endif
9098#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009099 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009100#endif
9101#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009102 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009103#endif
9104#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009105 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009106#endif
9107#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009108 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009109#endif
9110#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009111 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009112#endif
9113#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009114 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009115#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009116#ifdef _PC_ACL_ENABLED
9117 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9118#endif
9119#ifdef _PC_MIN_HOLE_SIZE
9120 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9121#endif
9122#ifdef _PC_ALLOC_SIZE_MIN
9123 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9124#endif
9125#ifdef _PC_REC_INCR_XFER_SIZE
9126 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9127#endif
9128#ifdef _PC_REC_MAX_XFER_SIZE
9129 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9130#endif
9131#ifdef _PC_REC_MIN_XFER_SIZE
9132 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9133#endif
9134#ifdef _PC_REC_XFER_ALIGN
9135 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9136#endif
9137#ifdef _PC_SYMLINK_MAX
9138 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9139#endif
9140#ifdef _PC_XATTR_ENABLED
9141 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9142#endif
9143#ifdef _PC_XATTR_EXISTS
9144 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9145#endif
9146#ifdef _PC_TIMESTAMP_RESOLUTION
9147 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9148#endif
Fred Drakec9680921999-12-13 16:37:25 +00009149};
9150
Fred Drakec9680921999-12-13 16:37:25 +00009151static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009152conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009153{
9154 return conv_confname(arg, valuep, posix_constants_pathconf,
9155 sizeof(posix_constants_pathconf)
9156 / sizeof(struct constdef));
9157}
9158#endif
9159
9160#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009161PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009162"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009163Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009164If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009165
9166static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009167posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009168{
9169 PyObject *result = NULL;
9170 int name, fd;
9171
Fred Drake12c6e2d1999-12-14 21:25:03 +00009172 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9173 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009174 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009175
Stefan Krah0e803b32010-11-26 16:16:47 +00009176 errno = 0;
9177 limit = fpathconf(fd, name);
9178 if (limit == -1 && errno != 0)
9179 posix_error();
9180 else
9181 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009182 }
9183 return result;
9184}
9185#endif
9186
9187
9188#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009189PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009190"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009191Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009192If there is no limit, return -1.\n\
9193On some platforms, path may also be specified as an open file descriptor.\n\
9194 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009195
9196static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009197posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009198{
Georg Brandl306336b2012-06-24 12:55:33 +02009199 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009200 PyObject *result = NULL;
9201 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009202 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009203
Georg Brandl306336b2012-06-24 12:55:33 +02009204 memset(&path, 0, sizeof(path));
9205#ifdef HAVE_FPATHCONF
9206 path.allow_fd = 1;
9207#endif
9208 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9209 path_converter, &path,
9210 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009211 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009212
Victor Stinner8c62be82010-05-06 00:08:46 +00009213 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009214#ifdef HAVE_FPATHCONF
9215 if (path.fd != -1)
9216 limit = fpathconf(path.fd, name);
9217 else
9218#endif
9219 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009220 if (limit == -1 && errno != 0) {
9221 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009222 /* could be a path or name problem */
9223 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009224 else
Georg Brandl306336b2012-06-24 12:55:33 +02009225 result = path_posix_error("pathconf", &path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009226 }
9227 else
9228 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009229 }
Georg Brandl306336b2012-06-24 12:55:33 +02009230 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009231 return result;
9232}
9233#endif
9234
9235#ifdef HAVE_CONFSTR
9236static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009237#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009238 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009239#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009240#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009241 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009242#endif
9243#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009244 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009245#endif
Fred Draked86ed291999-12-15 15:34:33 +00009246#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009247 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009248#endif
9249#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009250 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009251#endif
9252#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009253 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009254#endif
9255#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009256 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009257#endif
Fred Drakec9680921999-12-13 16:37:25 +00009258#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009259 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009260#endif
9261#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009262 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009263#endif
9264#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009265 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009266#endif
9267#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009268 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009269#endif
9270#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009271 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009272#endif
9273#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009274 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009275#endif
9276#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009277 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009278#endif
9279#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009280 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009281#endif
Fred Draked86ed291999-12-15 15:34:33 +00009282#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009283 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009284#endif
Fred Drakec9680921999-12-13 16:37:25 +00009285#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009286 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009287#endif
Fred Draked86ed291999-12-15 15:34:33 +00009288#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009289 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009290#endif
9291#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009292 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009293#endif
9294#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009295 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009296#endif
9297#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009298 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009299#endif
Fred Drakec9680921999-12-13 16:37:25 +00009300#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009301 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009302#endif
9303#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009304 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009305#endif
9306#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009307 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009308#endif
9309#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009310 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009311#endif
9312#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009313 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009314#endif
9315#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009316 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009317#endif
9318#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009319 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009320#endif
9321#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009322 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009323#endif
9324#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009325 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009326#endif
9327#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009328 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009329#endif
9330#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009332#endif
9333#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009334 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009335#endif
9336#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009337 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009338#endif
9339#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009340 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009341#endif
9342#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009343 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009344#endif
9345#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009346 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009347#endif
Fred Draked86ed291999-12-15 15:34:33 +00009348#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009350#endif
9351#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009353#endif
9354#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009356#endif
9357#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009359#endif
9360#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009362#endif
9363#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009365#endif
9366#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009368#endif
9369#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009371#endif
9372#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009373 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009374#endif
9375#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009376 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009377#endif
9378#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009380#endif
9381#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009383#endif
9384#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009386#endif
Fred Drakec9680921999-12-13 16:37:25 +00009387};
9388
9389static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009390conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009391{
9392 return conv_confname(arg, valuep, posix_constants_confstr,
9393 sizeof(posix_constants_confstr)
9394 / sizeof(struct constdef));
9395}
9396
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009397PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009398"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009399Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009400
9401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009402posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009403{
9404 PyObject *result = NULL;
9405 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009406 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009407 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009408
Victor Stinnercb043522010-09-10 23:49:04 +00009409 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9410 return NULL;
9411
9412 errno = 0;
9413 len = confstr(name, buffer, sizeof(buffer));
9414 if (len == 0) {
9415 if (errno) {
9416 posix_error();
9417 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009418 }
9419 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009420 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009421 }
9422 }
Victor Stinnercb043522010-09-10 23:49:04 +00009423
9424 if ((unsigned int)len >= sizeof(buffer)) {
9425 char *buf = PyMem_Malloc(len);
9426 if (buf == NULL)
9427 return PyErr_NoMemory();
9428 confstr(name, buf, len);
9429 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9430 PyMem_Free(buf);
9431 }
9432 else
9433 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009434 return result;
9435}
9436#endif
9437
9438
9439#ifdef HAVE_SYSCONF
9440static struct constdef posix_constants_sysconf[] = {
9441#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009442 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009443#endif
9444#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009445 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009446#endif
9447#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009448 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009449#endif
9450#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009451 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009452#endif
9453#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009454 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009455#endif
9456#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009457 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009458#endif
9459#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009460 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009461#endif
9462#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009463 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009464#endif
9465#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009466 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009467#endif
9468#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009470#endif
Fred Draked86ed291999-12-15 15:34:33 +00009471#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009472 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009473#endif
9474#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009475 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009476#endif
Fred Drakec9680921999-12-13 16:37:25 +00009477#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009478 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009479#endif
Fred Drakec9680921999-12-13 16:37:25 +00009480#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009481 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009482#endif
9483#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009484 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009485#endif
9486#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009487 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009488#endif
9489#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009490 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009491#endif
9492#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009493 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009494#endif
Fred Draked86ed291999-12-15 15:34:33 +00009495#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009496 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009497#endif
Fred Drakec9680921999-12-13 16:37:25 +00009498#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009499 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009500#endif
9501#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009502 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009503#endif
9504#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009505 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009506#endif
9507#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009508 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009509#endif
9510#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009511 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009512#endif
Fred Draked86ed291999-12-15 15:34:33 +00009513#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009514 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009515#endif
Fred Drakec9680921999-12-13 16:37:25 +00009516#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009517 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009518#endif
9519#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009520 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009521#endif
9522#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009524#endif
9525#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009526 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009527#endif
9528#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009530#endif
9531#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009533#endif
9534#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009536#endif
9537#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009539#endif
9540#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009542#endif
9543#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009545#endif
9546#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
9567#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
9570#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
9573#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
9576#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
9579#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009581#endif
9582#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009584#endif
Fred Draked86ed291999-12-15 15:34:33 +00009585#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009587#endif
Fred Drakec9680921999-12-13 16:37:25 +00009588#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009590#endif
9591#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
9594#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
Fred Draked86ed291999-12-15 15:34:33 +00009597#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009599#endif
Fred Drakec9680921999-12-13 16:37:25 +00009600#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009602#endif
Fred Draked86ed291999-12-15 15:34:33 +00009603#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009605#endif
9606#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009608#endif
Fred Drakec9680921999-12-13 16:37:25 +00009609#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
Fred Draked86ed291999-12-15 15:34:33 +00009621#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009623#endif
Fred Drakec9680921999-12-13 16:37:25 +00009624#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
9627#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
9630#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009632#endif
9633#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009635#endif
9636#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009638#endif
9639#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009641#endif
9642#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009644#endif
Fred Draked86ed291999-12-15 15:34:33 +00009645#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009647#endif
Fred Drakec9680921999-12-13 16:37:25 +00009648#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009650#endif
9651#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009653#endif
Fred Draked86ed291999-12-15 15:34:33 +00009654#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009656#endif
Fred Drakec9680921999-12-13 16:37:25 +00009657#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009659#endif
9660#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009662#endif
9663#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009665#endif
9666#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009668#endif
9669#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009671#endif
9672#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009674#endif
9675#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009677#endif
9678#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009679 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009680#endif
9681#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009682 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009683#endif
Fred Draked86ed291999-12-15 15:34:33 +00009684#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009686#endif
9687#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009688 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009689#endif
Fred Drakec9680921999-12-13 16:37:25 +00009690#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009692#endif
9693#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009694 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009695#endif
9696#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009698#endif
9699#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009701#endif
9702#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009704#endif
9705#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009707#endif
9708#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009710#endif
9711#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009713#endif
9714#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009716#endif
9717#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009719#endif
9720#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009722#endif
9723#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009725#endif
9726#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009728#endif
9729#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
9732#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
9759#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
Fred Draked86ed291999-12-15 15:34:33 +00009795#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009797#endif
Fred Drakec9680921999-12-13 16:37:25 +00009798#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
9825#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
9828#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
9831#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009833#endif
9834#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
9837#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009839#endif
9840#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
9843#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009845#endif
9846#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
9849#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
9858#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009860#endif
9861#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009863#endif
9864#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009866#endif
9867#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
9873#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009875#endif
9876#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
9885#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
9888#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
9897#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
9900#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
9909#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
9912#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933};
9934
9935static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009936conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009937{
9938 return conv_confname(arg, valuep, posix_constants_sysconf,
9939 sizeof(posix_constants_sysconf)
9940 / sizeof(struct constdef));
9941}
9942
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009943PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009944"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009945Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009946
9947static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009948posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009949{
9950 PyObject *result = NULL;
9951 int name;
9952
9953 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9954 int value;
9955
9956 errno = 0;
9957 value = sysconf(name);
9958 if (value == -1 && errno != 0)
9959 posix_error();
9960 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009961 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009962 }
9963 return result;
9964}
9965#endif
9966
9967
Fred Drakebec628d1999-12-15 18:31:10 +00009968/* This code is used to ensure that the tables of configuration value names
9969 * are in sorted order as required by conv_confname(), and also to build the
9970 * the exported dictionaries that are used to publish information about the
9971 * names available on the host platform.
9972 *
9973 * Sorting the table at runtime ensures that the table is properly ordered
9974 * when used, even for platforms we're not able to test on. It also makes
9975 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009976 */
Fred Drakebec628d1999-12-15 18:31:10 +00009977
9978static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009979cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009980{
9981 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009983 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009985
9986 return strcmp(c1->name, c2->name);
9987}
9988
9989static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009990setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009992{
Fred Drakebec628d1999-12-15 18:31:10 +00009993 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009994 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009995
9996 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9997 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009998 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010000
Barry Warsaw3155db32000-04-13 15:20:40 +000010001 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 PyObject *o = PyLong_FromLong(table[i].value);
10003 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10004 Py_XDECREF(o);
10005 Py_DECREF(d);
10006 return -1;
10007 }
10008 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010009 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010010 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010011}
10012
Fred Drakebec628d1999-12-15 18:31:10 +000010013/* Return -1 on failure, 0 on success. */
10014static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010015setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010016{
10017#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010018 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010019 sizeof(posix_constants_pathconf)
10020 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010021 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010022 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010023#endif
10024#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010025 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010026 sizeof(posix_constants_confstr)
10027 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010028 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010029 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010030#endif
10031#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010032 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010033 sizeof(posix_constants_sysconf)
10034 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010035 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010036 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010037#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010038 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010039}
Fred Draked86ed291999-12-15 15:34:33 +000010040
10041
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010042PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010043"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010044Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010045in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010046
10047static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010048posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010049{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010050 abort();
10051 /*NOTREACHED*/
10052 Py_FatalError("abort() called from Python code didn't abort!");
10053 return NULL;
10054}
Fred Drakebec628d1999-12-15 18:31:10 +000010055
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010056#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010057PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010058"startfile(filepath [, operation]) - Start a file with its associated\n\
10059application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010060\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010061When \"operation\" is not specified or \"open\", this acts like\n\
10062double-clicking the file in Explorer, or giving the file name as an\n\
10063argument to the DOS \"start\" command: the file is opened with whatever\n\
10064application (if any) its extension is associated.\n\
10065When another \"operation\" is given, it specifies what should be done with\n\
10066the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010067\n\
10068startfile returns as soon as the associated application is launched.\n\
10069There is no option to wait for the application to close, and no way\n\
10070to retrieve the application's exit status.\n\
10071\n\
10072The filepath is relative to the current directory. If you want to use\n\
10073an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010074the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010075
10076static PyObject *
10077win32_startfile(PyObject *self, PyObject *args)
10078{
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 PyObject *ofilepath;
10080 char *filepath;
10081 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010082 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010084
Victor Stinnereb5657a2011-09-30 01:44:27 +020010085 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 if (!PyArg_ParseTuple(args, "U|s:startfile",
10087 &unipath, &operation)) {
10088 PyErr_Clear();
10089 goto normal;
10090 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010091
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010093 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010095 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 PyErr_Clear();
10097 operation = NULL;
10098 goto normal;
10099 }
10100 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010101
Victor Stinnereb5657a2011-09-30 01:44:27 +020010102 wpath = PyUnicode_AsUnicode(unipath);
10103 if (wpath == NULL)
10104 goto normal;
10105 if (uoperation) {
10106 woperation = PyUnicode_AsUnicode(uoperation);
10107 if (woperation == NULL)
10108 goto normal;
10109 }
10110 else
10111 woperation = NULL;
10112
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010114 rc = ShellExecuteW((HWND)0, woperation, wpath,
10115 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 Py_END_ALLOW_THREADS
10117
Victor Stinnereb5657a2011-09-30 01:44:27 +020010118 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010120 win32_error_object("startfile", unipath);
10121 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 }
10123 Py_INCREF(Py_None);
10124 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010125
10126normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10128 PyUnicode_FSConverter, &ofilepath,
10129 &operation))
10130 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010131 if (win32_warn_bytes_api()) {
10132 Py_DECREF(ofilepath);
10133 return NULL;
10134 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 filepath = PyBytes_AsString(ofilepath);
10136 Py_BEGIN_ALLOW_THREADS
10137 rc = ShellExecute((HWND)0, operation, filepath,
10138 NULL, NULL, SW_SHOWNORMAL);
10139 Py_END_ALLOW_THREADS
10140 if (rc <= (HINSTANCE)32) {
10141 PyObject *errval = win32_error("startfile", filepath);
10142 Py_DECREF(ofilepath);
10143 return errval;
10144 }
10145 Py_DECREF(ofilepath);
10146 Py_INCREF(Py_None);
10147 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010148}
10149#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010150
Martin v. Löwis438b5342002-12-27 10:16:42 +000010151#ifdef HAVE_GETLOADAVG
10152PyDoc_STRVAR(posix_getloadavg__doc__,
10153"getloadavg() -> (float, float, float)\n\n\
10154Return the number of processes in the system run queue averaged over\n\
10155the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10156was unobtainable");
10157
10158static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010159posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010160{
10161 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010162 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010163 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10164 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010165 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010166 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010167}
10168#endif
10169
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010170PyDoc_STRVAR(device_encoding__doc__,
10171"device_encoding(fd) -> str\n\n\
10172Return a string describing the encoding of the device\n\
10173if the output is a terminal; else return None.");
10174
10175static PyObject *
10176device_encoding(PyObject *self, PyObject *args)
10177{
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010179
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10181 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010182
10183 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010184}
10185
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010186#ifdef HAVE_SETRESUID
10187PyDoc_STRVAR(posix_setresuid__doc__,
10188"setresuid(ruid, euid, suid)\n\n\
10189Set the current process's real, effective, and saved user ids.");
10190
10191static PyObject*
10192posix_setresuid (PyObject *self, PyObject *args)
10193{
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 /* We assume uid_t is no larger than a long. */
10195 long ruid, euid, suid;
10196 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
10197 return NULL;
10198 if (setresuid(ruid, euid, suid) < 0)
10199 return posix_error();
10200 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010201}
10202#endif
10203
10204#ifdef HAVE_SETRESGID
10205PyDoc_STRVAR(posix_setresgid__doc__,
10206"setresgid(rgid, egid, sgid)\n\n\
10207Set the current process's real, effective, and saved group ids.");
10208
10209static PyObject*
10210posix_setresgid (PyObject *self, PyObject *args)
10211{
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 /* We assume uid_t is no larger than a long. */
10213 long rgid, egid, sgid;
10214 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
10215 return NULL;
10216 if (setresgid(rgid, egid, sgid) < 0)
10217 return posix_error();
10218 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010219}
10220#endif
10221
10222#ifdef HAVE_GETRESUID
10223PyDoc_STRVAR(posix_getresuid__doc__,
10224"getresuid() -> (ruid, euid, suid)\n\n\
10225Get tuple of the current process's real, effective, and saved user ids.");
10226
10227static PyObject*
10228posix_getresuid (PyObject *self, PyObject *noargs)
10229{
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 uid_t ruid, euid, suid;
10231 long l_ruid, l_euid, l_suid;
10232 if (getresuid(&ruid, &euid, &suid) < 0)
10233 return posix_error();
10234 /* Force the values into long's as we don't know the size of uid_t. */
10235 l_ruid = ruid;
10236 l_euid = euid;
10237 l_suid = suid;
10238 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010239}
10240#endif
10241
10242#ifdef HAVE_GETRESGID
10243PyDoc_STRVAR(posix_getresgid__doc__,
10244"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010245Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010246
10247static PyObject*
10248posix_getresgid (PyObject *self, PyObject *noargs)
10249{
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 uid_t rgid, egid, sgid;
10251 long l_rgid, l_egid, l_sgid;
10252 if (getresgid(&rgid, &egid, &sgid) < 0)
10253 return posix_error();
10254 /* Force the values into long's as we don't know the size of uid_t. */
10255 l_rgid = rgid;
10256 l_egid = egid;
10257 l_sgid = sgid;
10258 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010259}
10260#endif
10261
Benjamin Peterson9428d532011-09-14 11:45:52 -040010262#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010263
Benjamin Peterson799bd802011-08-31 22:15:17 -040010264PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010265"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10266Return the value of extended attribute attribute on path.\n\
10267\n\
10268path may be either a string or an open file descriptor.\n\
10269If follow_symlinks is False, and the last element of the path is a symbolic\n\
10270 link, getxattr will examine the symbolic link itself instead of the file\n\
10271 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010272
10273static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010274posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010275{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010276 path_t path;
10277 path_t attribute;
10278 int follow_symlinks = 1;
10279 PyObject *buffer = NULL;
10280 int i;
10281 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010282
Larry Hastings9cf065c2012-06-22 16:30:09 -070010283 memset(&path, 0, sizeof(path));
10284 memset(&attribute, 0, sizeof(attribute));
10285 path.allow_fd = 1;
10286 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10287 path_converter, &path,
10288 path_converter, &attribute,
10289 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010290 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010291
Larry Hastings9cf065c2012-06-22 16:30:09 -070010292 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10293 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010294
Larry Hastings9cf065c2012-06-22 16:30:09 -070010295 for (i = 0; ; i++) {
10296 void *ptr;
10297 ssize_t result;
10298 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10299 Py_ssize_t buffer_size = buffer_sizes[i];
10300 if (!buffer_size) {
10301 path_error("getxattr", &path);
10302 goto exit;
10303 }
10304 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10305 if (!buffer)
10306 goto exit;
10307 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010308
Larry Hastings9cf065c2012-06-22 16:30:09 -070010309 Py_BEGIN_ALLOW_THREADS;
10310 if (path.fd >= 0)
10311 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10312 else if (follow_symlinks)
10313 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10314 else
10315 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10316 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010317
Larry Hastings9cf065c2012-06-22 16:30:09 -070010318 if (result < 0) {
10319 Py_DECREF(buffer);
10320 buffer = NULL;
10321 if (errno == ERANGE)
10322 continue;
10323 path_error("getxattr", &path);
10324 goto exit;
10325 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010326
Larry Hastings9cf065c2012-06-22 16:30:09 -070010327 if (result != buffer_size) {
10328 /* Can only shrink. */
10329 _PyBytes_Resize(&buffer, result);
10330 }
10331 break;
10332 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010333
Larry Hastings9cf065c2012-06-22 16:30:09 -070010334exit:
10335 path_cleanup(&path);
10336 path_cleanup(&attribute);
10337 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010338}
10339
10340PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010341"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10342Set extended attribute attribute on path to value.\n\
10343path may be either a string or an open file descriptor.\n\
10344If follow_symlinks is False, and the last element of the path is a symbolic\n\
10345 link, setxattr will modify the symbolic link itself instead of the file\n\
10346 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010347
10348static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010349posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010350{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010351 path_t path;
10352 path_t attribute;
10353 Py_buffer value;
10354 int flags = 0;
10355 int follow_symlinks = 1;
10356 int result;
10357 PyObject *return_value = NULL;
10358 static char *keywords[] = {"path", "attribute", "value",
10359 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010360
Larry Hastings9cf065c2012-06-22 16:30:09 -070010361 memset(&path, 0, sizeof(path));
10362 path.allow_fd = 1;
10363 memset(&attribute, 0, sizeof(attribute));
10364 memset(&value, 0, sizeof(value));
10365 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10366 keywords,
10367 path_converter, &path,
10368 path_converter, &attribute,
10369 &value, &flags,
10370 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010371 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010372
10373 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10374 goto exit;
10375
Benjamin Peterson799bd802011-08-31 22:15:17 -040010376 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010377 if (path.fd > -1)
10378 result = fsetxattr(path.fd, attribute.narrow,
10379 value.buf, value.len, flags);
10380 else if (follow_symlinks)
10381 result = setxattr(path.narrow, attribute.narrow,
10382 value.buf, value.len, flags);
10383 else
10384 result = lsetxattr(path.narrow, attribute.narrow,
10385 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010386 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010387
Larry Hastings9cf065c2012-06-22 16:30:09 -070010388 if (result) {
10389 return_value = path_error("setxattr", &path);
10390 goto exit;
10391 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010392
Larry Hastings9cf065c2012-06-22 16:30:09 -070010393 return_value = Py_None;
10394 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010395
Larry Hastings9cf065c2012-06-22 16:30:09 -070010396exit:
10397 path_cleanup(&path);
10398 path_cleanup(&attribute);
10399 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010400
Larry Hastings9cf065c2012-06-22 16:30:09 -070010401 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010402}
10403
10404PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010405"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10406Remove extended attribute attribute on path.\n\
10407path may be either a string or an open file descriptor.\n\
10408If follow_symlinks is False, and the last element of the path is a symbolic\n\
10409 link, removexattr will modify the symbolic link itself instead of the file\n\
10410 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010411
10412static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010413posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010414{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010415 path_t path;
10416 path_t attribute;
10417 int follow_symlinks = 1;
10418 int result;
10419 PyObject *return_value = NULL;
10420 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010421
Larry Hastings9cf065c2012-06-22 16:30:09 -070010422 memset(&path, 0, sizeof(path));
10423 memset(&attribute, 0, sizeof(attribute));
10424 path.allow_fd = 1;
10425 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10426 keywords,
10427 path_converter, &path,
10428 path_converter, &attribute,
10429 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010430 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010431
10432 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10433 goto exit;
10434
Benjamin Peterson799bd802011-08-31 22:15:17 -040010435 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010436 if (path.fd > -1)
10437 result = fremovexattr(path.fd, attribute.narrow);
10438 else if (follow_symlinks)
10439 result = removexattr(path.narrow, attribute.narrow);
10440 else
10441 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010442 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010443
Larry Hastings9cf065c2012-06-22 16:30:09 -070010444 if (result) {
10445 return_value = path_error("removexattr", &path);
10446 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010447 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010448
Larry Hastings9cf065c2012-06-22 16:30:09 -070010449 return_value = Py_None;
10450 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010451
Larry Hastings9cf065c2012-06-22 16:30:09 -070010452exit:
10453 path_cleanup(&path);
10454 path_cleanup(&attribute);
10455
10456 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010457}
10458
10459PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010460"listxattr(path='.', *, follow_symlinks=True)\n\n\
10461Return a list of extended attributes on path.\n\
10462\n\
10463path may be either None, a string, or an open file descriptor.\n\
10464if path is None, listxattr will examine the current directory.\n\
10465If follow_symlinks is False, and the last element of the path is a symbolic\n\
10466 link, listxattr will examine the symbolic link itself instead of the file\n\
10467 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010468
10469static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010470posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010471{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010472 path_t path;
10473 int follow_symlinks = 1;
10474 Py_ssize_t i;
10475 PyObject *result = NULL;
10476 char *buffer = NULL;
10477 char *name;
10478 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010479
Larry Hastings9cf065c2012-06-22 16:30:09 -070010480 memset(&path, 0, sizeof(path));
10481 path.allow_fd = 1;
10482 path.fd = -1;
10483 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10484 path_converter, &path,
10485 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010486 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010487
Larry Hastings9cf065c2012-06-22 16:30:09 -070010488 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10489 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010490
Larry Hastings9cf065c2012-06-22 16:30:09 -070010491 name = path.narrow ? path.narrow : ".";
10492 for (i = 0; ; i++) {
10493 char *start, *trace, *end;
10494 ssize_t length;
10495 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10496 Py_ssize_t buffer_size = buffer_sizes[i];
10497 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010498 /* ERANGE */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010499 path_error("listxattr", &path);
10500 break;
10501 }
10502 buffer = PyMem_MALLOC(buffer_size);
10503 if (!buffer) {
10504 PyErr_NoMemory();
10505 break;
10506 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010507
Larry Hastings9cf065c2012-06-22 16:30:09 -070010508 Py_BEGIN_ALLOW_THREADS;
10509 if (path.fd > -1)
10510 length = flistxattr(path.fd, buffer, buffer_size);
10511 else if (follow_symlinks)
10512 length = listxattr(name, buffer, buffer_size);
10513 else
10514 length = llistxattr(name, buffer, buffer_size);
10515 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010516
Larry Hastings9cf065c2012-06-22 16:30:09 -070010517 if (length < 0) {
10518 if (errno == ERANGE)
10519 continue;
10520 path_error("listxattr", &path);
10521 break;
10522 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010523
Larry Hastings9cf065c2012-06-22 16:30:09 -070010524 result = PyList_New(0);
10525 if (!result) {
10526 goto exit;
10527 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010528
Larry Hastings9cf065c2012-06-22 16:30:09 -070010529 end = buffer + length;
10530 for (trace = start = buffer; trace != end; trace++) {
10531 if (!*trace) {
10532 int error;
10533 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10534 trace - start);
10535 if (!attribute) {
10536 Py_DECREF(result);
10537 result = NULL;
10538 goto exit;
10539 }
10540 error = PyList_Append(result, attribute);
10541 Py_DECREF(attribute);
10542 if (error) {
10543 Py_DECREF(result);
10544 result = NULL;
10545 goto exit;
10546 }
10547 start = trace + 1;
10548 }
10549 }
10550 break;
10551 }
10552exit:
10553 path_cleanup(&path);
10554 if (buffer)
10555 PyMem_FREE(buffer);
10556 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010557}
10558
Benjamin Peterson9428d532011-09-14 11:45:52 -040010559#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010560
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010561
Georg Brandl2fb477c2012-02-21 00:33:36 +010010562PyDoc_STRVAR(posix_urandom__doc__,
10563"urandom(n) -> str\n\n\
10564Return n random bytes suitable for cryptographic use.");
10565
10566static PyObject *
10567posix_urandom(PyObject *self, PyObject *args)
10568{
10569 Py_ssize_t size;
10570 PyObject *result;
10571 int ret;
10572
10573 /* Read arguments */
10574 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10575 return NULL;
10576 if (size < 0)
10577 return PyErr_Format(PyExc_ValueError,
10578 "negative argument not allowed");
10579 result = PyBytes_FromStringAndSize(NULL, size);
10580 if (result == NULL)
10581 return NULL;
10582
10583 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10584 PyBytes_GET_SIZE(result));
10585 if (ret == -1) {
10586 Py_DECREF(result);
10587 return NULL;
10588 }
10589 return result;
10590}
10591
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010592/* Terminal size querying */
10593
10594static PyTypeObject TerminalSizeType;
10595
10596PyDoc_STRVAR(TerminalSize_docstring,
10597 "A tuple of (columns, lines) for holding terminal window size");
10598
10599static PyStructSequence_Field TerminalSize_fields[] = {
10600 {"columns", "width of the terminal window in characters"},
10601 {"lines", "height of the terminal window in characters"},
10602 {NULL, NULL}
10603};
10604
10605static PyStructSequence_Desc TerminalSize_desc = {
10606 "os.terminal_size",
10607 TerminalSize_docstring,
10608 TerminalSize_fields,
10609 2,
10610};
10611
10612#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10613PyDoc_STRVAR(termsize__doc__,
10614 "Return the size of the terminal window as (columns, lines).\n" \
10615 "\n" \
10616 "The optional argument fd (default standard output) specifies\n" \
10617 "which file descriptor should be queried.\n" \
10618 "\n" \
10619 "If the file descriptor is not connected to a terminal, an OSError\n" \
10620 "is thrown.\n" \
10621 "\n" \
10622 "This function will only be defined if an implementation is\n" \
10623 "available for this system.\n" \
10624 "\n" \
10625 "shutil.get_terminal_size is the high-level function which should \n" \
10626 "normally be used, os.get_terminal_size is the low-level implementation.");
10627
10628static PyObject*
10629get_terminal_size(PyObject *self, PyObject *args)
10630{
10631 int columns, lines;
10632 PyObject *termsize;
10633
10634 int fd = fileno(stdout);
10635 /* Under some conditions stdout may not be connected and
10636 * fileno(stdout) may point to an invalid file descriptor. For example
10637 * GUI apps don't have valid standard streams by default.
10638 *
10639 * If this happens, and the optional fd argument is not present,
10640 * the ioctl below will fail returning EBADF. This is what we want.
10641 */
10642
10643 if (!PyArg_ParseTuple(args, "|i", &fd))
10644 return NULL;
10645
10646#ifdef TERMSIZE_USE_IOCTL
10647 {
10648 struct winsize w;
10649 if (ioctl(fd, TIOCGWINSZ, &w))
10650 return PyErr_SetFromErrno(PyExc_OSError);
10651 columns = w.ws_col;
10652 lines = w.ws_row;
10653 }
10654#endif /* TERMSIZE_USE_IOCTL */
10655
10656#ifdef TERMSIZE_USE_CONIO
10657 {
10658 DWORD nhandle;
10659 HANDLE handle;
10660 CONSOLE_SCREEN_BUFFER_INFO csbi;
10661 switch (fd) {
10662 case 0: nhandle = STD_INPUT_HANDLE;
10663 break;
10664 case 1: nhandle = STD_OUTPUT_HANDLE;
10665 break;
10666 case 2: nhandle = STD_ERROR_HANDLE;
10667 break;
10668 default:
10669 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10670 }
10671 handle = GetStdHandle(nhandle);
10672 if (handle == NULL)
10673 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10674 if (handle == INVALID_HANDLE_VALUE)
10675 return PyErr_SetFromWindowsErr(0);
10676
10677 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10678 return PyErr_SetFromWindowsErr(0);
10679
10680 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10681 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10682 }
10683#endif /* TERMSIZE_USE_CONIO */
10684
10685 termsize = PyStructSequence_New(&TerminalSizeType);
10686 if (termsize == NULL)
10687 return NULL;
10688 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10689 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10690 if (PyErr_Occurred()) {
10691 Py_DECREF(termsize);
10692 return NULL;
10693 }
10694 return termsize;
10695}
10696#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10697
10698
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010699static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010700 {"access", (PyCFunction)posix_access,
10701 METH_VARARGS | METH_KEYWORDS,
10702 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010703#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010704 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010705#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010706 {"chdir", (PyCFunction)posix_chdir,
10707 METH_VARARGS | METH_KEYWORDS,
10708 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010709#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010710 {"chflags", (PyCFunction)posix_chflags,
10711 METH_VARARGS | METH_KEYWORDS,
10712 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010713#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010714 {"chmod", (PyCFunction)posix_chmod,
10715 METH_VARARGS | METH_KEYWORDS,
10716 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010717#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010718 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010719#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010720#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010721 {"chown", (PyCFunction)posix_chown,
10722 METH_VARARGS | METH_KEYWORDS,
10723 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010724#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010725#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010726 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010727#endif /* HAVE_LCHMOD */
10728#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010730#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010731#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010732 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010733#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010734#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010736#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010737#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010739#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010740#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010741 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010742#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010743#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010744 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10745 METH_NOARGS, posix_getcwd__doc__},
10746 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10747 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010748#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010749#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10750 {"link", (PyCFunction)posix_link,
10751 METH_VARARGS | METH_KEYWORDS,
10752 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010753#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010754 {"listdir", (PyCFunction)posix_listdir,
10755 METH_VARARGS | METH_KEYWORDS,
10756 posix_listdir__doc__},
10757 {"lstat", (PyCFunction)posix_lstat,
10758 METH_VARARGS | METH_KEYWORDS,
10759 posix_lstat__doc__},
10760 {"mkdir", (PyCFunction)posix_mkdir,
10761 METH_VARARGS | METH_KEYWORDS,
10762 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010763#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010764 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010765#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010766#ifdef HAVE_GETPRIORITY
10767 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10768#endif /* HAVE_GETPRIORITY */
10769#ifdef HAVE_SETPRIORITY
10770 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10771#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010772#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010773 {"readlink", (PyCFunction)posix_readlink,
10774 METH_VARARGS | METH_KEYWORDS,
10775 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010776#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010777#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010778 {"readlink", (PyCFunction)win_readlink,
10779 METH_VARARGS | METH_KEYWORDS,
10780 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010781#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010782 {"rename", (PyCFunction)posix_rename,
10783 METH_VARARGS | METH_KEYWORDS,
10784 posix_rename__doc__},
10785 {"replace", (PyCFunction)posix_replace,
10786 METH_VARARGS | METH_KEYWORDS,
10787 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010788 {"rmdir", (PyCFunction)posix_rmdir,
10789 METH_VARARGS | METH_KEYWORDS,
10790 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010791 {"stat", (PyCFunction)posix_stat,
10792 METH_VARARGS | METH_KEYWORDS,
10793 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010794 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010795#if defined(HAVE_SYMLINK)
10796 {"symlink", (PyCFunction)posix_symlink,
10797 METH_VARARGS | METH_KEYWORDS,
10798 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010799#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010800#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010801 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010802#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010803 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010804#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010806#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010807 {"unlink", (PyCFunction)posix_unlink,
10808 METH_VARARGS | METH_KEYWORDS,
10809 posix_unlink__doc__},
10810 {"remove", (PyCFunction)posix_unlink,
10811 METH_VARARGS | METH_KEYWORDS,
10812 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010813 {"utime", (PyCFunction)posix_utime,
10814 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010815#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010817#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010818 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010819#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010821 {"execve", (PyCFunction)posix_execve,
10822 METH_VARARGS | METH_KEYWORDS,
10823 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010824#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010825#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010826 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10827 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010828#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010829 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10830 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010831#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010832#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010833#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010834 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010835#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010836#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010837 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010838#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010839#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010840#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010841 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10842 {"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 +020010843#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010844#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010845 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010846#endif
10847#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010848 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010849#endif
10850#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010851 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010852#endif
10853#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010854 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010855#endif
10856#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010857 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010858#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010859 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010860#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010861 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10862 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10863#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010864#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010865#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010866 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010867#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010868#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010869 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010870#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010871#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010872 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010873#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010874#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010875 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010876#endif /* HAVE_GETEUID */
10877#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010878 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010879#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010880#ifdef HAVE_GETGROUPLIST
10881 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10882#endif
Fred Drakec9680921999-12-13 16:37:25 +000010883#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010884 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010885#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010886 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010887#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010889#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010890#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010892#endif /* HAVE_GETPPID */
10893#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010895#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010896#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010898#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010899#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010901#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010902#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010904#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010905#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010907#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010908#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10910 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010911#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010912#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010914#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010915#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010917#endif /* HAVE_SETEUID */
10918#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010919 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010920#endif /* HAVE_SETEGID */
10921#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010923#endif /* HAVE_SETREUID */
10924#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010925 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010926#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010927#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010928 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010929#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010930#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010931 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010932#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010933#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010934 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010935#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010936#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010937 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010938#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010939#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010940 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010941#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010942#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010943 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010944#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010945#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010946 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010947#endif /* HAVE_WAIT3 */
10948#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010949 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010950#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010951#if defined(HAVE_WAITID) && !defined(__APPLE__)
10952 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10953#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010954#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010955 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010956#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010957#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010958 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010959#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010960#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010961 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010962#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010963#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010964 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010965#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010966#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010967 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010968#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010969#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010970 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010971#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010972 {"open", (PyCFunction)posix_open,\
10973 METH_VARARGS | METH_KEYWORDS,
10974 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010975 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10976 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10977 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10978 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10979 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010980#ifdef HAVE_LOCKF
10981 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10982#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010983 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10984 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010985#ifdef HAVE_READV
10986 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10987#endif
10988#ifdef HAVE_PREAD
10989 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10990#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010991 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010992#ifdef HAVE_WRITEV
10993 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10994#endif
10995#ifdef HAVE_PWRITE
10996 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10997#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010998#ifdef HAVE_SENDFILE
10999 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11000 posix_sendfile__doc__},
11001#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011002 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011003 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011004#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011005 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011006#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011007#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011008 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011009#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011010#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011011 {"mkfifo", (PyCFunction)posix_mkfifo,
11012 METH_VARARGS | METH_KEYWORDS,
11013 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011014#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011015#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011016 {"mknod", (PyCFunction)posix_mknod,
11017 METH_VARARGS | METH_KEYWORDS,
11018 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011019#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011020#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011021 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11022 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11023 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011024#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011025#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011027#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011028#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011029 {"truncate", (PyCFunction)posix_truncate,
11030 METH_VARARGS | METH_KEYWORDS,
11031 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011032#endif
11033#ifdef HAVE_POSIX_FALLOCATE
11034 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11035#endif
11036#ifdef HAVE_POSIX_FADVISE
11037 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11038#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011039#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011040 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011041#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011042#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011043 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011044#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011045 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011046#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011048#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011049#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011051#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011052#ifdef HAVE_SYNC
11053 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11054#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011055#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011057#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011058#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011059#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011060 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011061#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011062#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011063 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011064#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011065#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011066 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011067#endif /* WIFSTOPPED */
11068#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011069 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011070#endif /* WIFSIGNALED */
11071#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011072 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011073#endif /* WIFEXITED */
11074#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011075 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011076#endif /* WEXITSTATUS */
11077#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011078 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011079#endif /* WTERMSIG */
11080#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011081 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011082#endif /* WSTOPSIG */
11083#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011084#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011085 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011086#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011087#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011088 {"statvfs", (PyCFunction)posix_statvfs,
11089 METH_VARARGS | METH_KEYWORDS,
11090 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011091#endif
Fred Drakec9680921999-12-13 16:37:25 +000011092#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011093 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011094#endif
11095#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011096 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011097#endif
11098#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011099 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011100#endif
11101#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011102 {"pathconf", (PyCFunction)posix_pathconf,
11103 METH_VARARGS | METH_KEYWORDS,
11104 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011105#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011106 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011107#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011108 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011109 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011110 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011111 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011112 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011113#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011114#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011115 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011116#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011117 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011118#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011120#endif
11121#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011123#endif
11124#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011126#endif
11127#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011129#endif
11130
Benjamin Peterson9428d532011-09-14 11:45:52 -040011131#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011132 {"setxattr", (PyCFunction)posix_setxattr,
11133 METH_VARARGS | METH_KEYWORDS,
11134 posix_setxattr__doc__},
11135 {"getxattr", (PyCFunction)posix_getxattr,
11136 METH_VARARGS | METH_KEYWORDS,
11137 posix_getxattr__doc__},
11138 {"removexattr", (PyCFunction)posix_removexattr,
11139 METH_VARARGS | METH_KEYWORDS,
11140 posix_removexattr__doc__},
11141 {"listxattr", (PyCFunction)posix_listxattr,
11142 METH_VARARGS | METH_KEYWORDS,
11143 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011144#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011145#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11146 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11147#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011149};
11150
11151
Barry Warsaw4a342091996-12-19 23:50:02 +000011152static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011153ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011154{
Victor Stinner8c62be82010-05-06 00:08:46 +000011155 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011156}
11157
Guido van Rossumd48f2521997-12-05 22:19:34 +000011158#if defined(PYOS_OS2)
11159/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011160static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011161{
11162 APIRET rc;
11163 ULONG values[QSV_MAX+1];
11164 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011165 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011166
11167 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011168 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011169 Py_END_ALLOW_THREADS
11170
11171 if (rc != NO_ERROR) {
11172 os2_error(rc);
11173 return -1;
11174 }
11175
Fred Drake4d1e64b2002-04-15 19:40:07 +000011176 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11177 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11178 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11179 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11180 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11181 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11182 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011183
11184 switch (values[QSV_VERSION_MINOR]) {
11185 case 0: ver = "2.00"; break;
11186 case 10: ver = "2.10"; break;
11187 case 11: ver = "2.11"; break;
11188 case 30: ver = "3.00"; break;
11189 case 40: ver = "4.00"; break;
11190 case 50: ver = "5.00"; break;
11191 default:
Tim Peters885d4572001-11-28 20:27:42 +000011192 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011193 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011194 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011195 ver = &tmp[0];
11196 }
11197
11198 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011199 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011200 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011201
11202 /* Add Indicator of Which Drive was Used to Boot the System */
11203 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11204 tmp[1] = ':';
11205 tmp[2] = '\0';
11206
Fred Drake4d1e64b2002-04-15 19:40:07 +000011207 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011208}
11209#endif
11210
Brian Curtin52173d42010-12-02 18:29:18 +000011211#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011212static int
Brian Curtin52173d42010-12-02 18:29:18 +000011213enable_symlink()
11214{
11215 HANDLE tok;
11216 TOKEN_PRIVILEGES tok_priv;
11217 LUID luid;
11218 int meth_idx = 0;
11219
11220 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011221 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011222
11223 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011224 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011225
11226 tok_priv.PrivilegeCount = 1;
11227 tok_priv.Privileges[0].Luid = luid;
11228 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11229
11230 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11231 sizeof(TOKEN_PRIVILEGES),
11232 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011233 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011234
Brian Curtin3b4499c2010-12-28 14:31:47 +000011235 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11236 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011237}
11238#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11239
Barry Warsaw4a342091996-12-19 23:50:02 +000011240static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011241all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011242{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011243#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011245#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011246#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011248#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011249#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011250 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011251#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011252#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011254#endif
Fred Drakec9680921999-12-13 16:37:25 +000011255#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011257#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011258#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011260#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011261#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011263#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011264#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011266#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011267#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011268 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011269#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011270#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011271 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011272#endif
11273#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011274 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011275#endif
11276#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011277 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011278#endif
11279#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011281#endif
11282#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011284#endif
11285#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011287#endif
11288#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011290#endif
11291#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011293#endif
11294#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011295 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011296#endif
11297#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011298 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011299#endif
11300#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011302#endif
11303#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011305#endif
11306#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011308#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011309#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011311#endif
11312#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011314#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011315#ifdef O_XATTR
11316 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11317#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011318#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011320#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011321#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011323#endif
11324#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011326#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011327#ifdef O_EXEC
11328 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11329#endif
11330#ifdef O_SEARCH
11331 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11332#endif
11333#ifdef O_TTY_INIT
11334 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11335#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011336#ifdef PRIO_PROCESS
11337 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11338#endif
11339#ifdef PRIO_PGRP
11340 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11341#endif
11342#ifdef PRIO_USER
11343 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11344#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011345#ifdef O_CLOEXEC
11346 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11347#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011348#ifdef O_ACCMODE
11349 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11350#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011351
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011352
Jesus Cea94363612012-06-22 18:32:07 +020011353#ifdef SEEK_HOLE
11354 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11355#endif
11356#ifdef SEEK_DATA
11357 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11358#endif
11359
Tim Peters5aa91602002-01-30 05:46:57 +000011360/* MS Windows */
11361#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011362 /* Don't inherit in child processes. */
11363 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011364#endif
11365#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011366 /* Optimize for short life (keep in memory). */
11367 /* MS forgot to define this one with a non-underscore form too. */
11368 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011369#endif
11370#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011371 /* Automatically delete when last handle is closed. */
11372 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011373#endif
11374#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 /* Optimize for random access. */
11376 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011377#endif
11378#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011379 /* Optimize for sequential access. */
11380 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011381#endif
11382
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011383/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011384#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 /* Send a SIGIO signal whenever input or output
11386 becomes available on file descriptor */
11387 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011388#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011389#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 /* Direct disk access. */
11391 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011392#endif
11393#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011394 /* Must be a directory. */
11395 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011396#endif
11397#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011398 /* Do not follow links. */
11399 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011400#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011401#ifdef O_NOLINKS
11402 /* Fails if link count of the named file is greater than 1 */
11403 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11404#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011405#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011406 /* Do not update the access time. */
11407 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011408#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011409
Victor Stinner8c62be82010-05-06 00:08:46 +000011410 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011411#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011412 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011413#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011414#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011415 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011416#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011417#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011418 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011419#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011420#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011421 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011422#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011423#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011424 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011425#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011426#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011428#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011429#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011430 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011431#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011432#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011433 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011434#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011435#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011436 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011437#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011438#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011439 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011440#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011441#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011442 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011443#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011444#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011445 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011446#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011447#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011448 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011449#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011450#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011451 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011452#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011453#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011455#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011456#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011457 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011458#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011459#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011460 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011461#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011462
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011463 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011464#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011465 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011466#endif /* ST_RDONLY */
11467#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011468 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011469#endif /* ST_NOSUID */
11470
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011471 /* FreeBSD sendfile() constants */
11472#ifdef SF_NODISKIO
11473 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11474#endif
11475#ifdef SF_MNOWAIT
11476 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11477#endif
11478#ifdef SF_SYNC
11479 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11480#endif
11481
Ross Lagerwall7807c352011-03-17 20:20:30 +020011482 /* constants for posix_fadvise */
11483#ifdef POSIX_FADV_NORMAL
11484 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11485#endif
11486#ifdef POSIX_FADV_SEQUENTIAL
11487 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11488#endif
11489#ifdef POSIX_FADV_RANDOM
11490 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11491#endif
11492#ifdef POSIX_FADV_NOREUSE
11493 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11494#endif
11495#ifdef POSIX_FADV_WILLNEED
11496 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11497#endif
11498#ifdef POSIX_FADV_DONTNEED
11499 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11500#endif
11501
11502 /* constants for waitid */
11503#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11504 if (ins(d, "P_PID", (long)P_PID)) return -1;
11505 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11506 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11507#endif
11508#ifdef WEXITED
11509 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11510#endif
11511#ifdef WNOWAIT
11512 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11513#endif
11514#ifdef WSTOPPED
11515 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11516#endif
11517#ifdef CLD_EXITED
11518 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11519#endif
11520#ifdef CLD_DUMPED
11521 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11522#endif
11523#ifdef CLD_TRAPPED
11524 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11525#endif
11526#ifdef CLD_CONTINUED
11527 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11528#endif
11529
11530 /* constants for lockf */
11531#ifdef F_LOCK
11532 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11533#endif
11534#ifdef F_TLOCK
11535 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11536#endif
11537#ifdef F_ULOCK
11538 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11539#endif
11540#ifdef F_TEST
11541 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11542#endif
11543
Guido van Rossum246bc171999-02-01 23:54:31 +000011544#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011545#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11547 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11548 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11549 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11550 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11551 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11552 if (ins(d, "P_PM", (long)P_PM)) return -1;
11553 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11554 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11555 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11556 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11557 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11558 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11559 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11560 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11561 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11562 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11563 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11564 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11565 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011566#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011567 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11568 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11569 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11570 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11571 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011572#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011573#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011574
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011575#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011576 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011577 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11578 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11579#ifdef SCHED_SPORADIC
11580 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11581#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011582#ifdef SCHED_BATCH
11583 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11584#endif
11585#ifdef SCHED_IDLE
11586 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11587#endif
11588#ifdef SCHED_RESET_ON_FORK
11589 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11590#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011591#ifdef SCHED_SYS
11592 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11593#endif
11594#ifdef SCHED_IA
11595 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11596#endif
11597#ifdef SCHED_FSS
11598 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11599#endif
11600#ifdef SCHED_FX
11601 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11602#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011603#endif
11604
Benjamin Peterson9428d532011-09-14 11:45:52 -040011605#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011606 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11607 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11608 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11609#endif
11610
Victor Stinner8b905bd2011-10-25 13:34:04 +020011611#ifdef RTLD_LAZY
11612 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11613#endif
11614#ifdef RTLD_NOW
11615 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11616#endif
11617#ifdef RTLD_GLOBAL
11618 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11619#endif
11620#ifdef RTLD_LOCAL
11621 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11622#endif
11623#ifdef RTLD_NODELETE
11624 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11625#endif
11626#ifdef RTLD_NOLOAD
11627 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11628#endif
11629#ifdef RTLD_DEEPBIND
11630 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11631#endif
11632
Guido van Rossumd48f2521997-12-05 22:19:34 +000011633#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011634 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011635#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011636 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011637}
11638
11639
Tim Peters5aa91602002-01-30 05:46:57 +000011640#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011641#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011642#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011643
11644#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011645#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011646#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011647
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011648#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011649#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011650#define MODNAME "posix"
11651#endif
11652
Martin v. Löwis1a214512008-06-11 05:26:20 +000011653static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011654 PyModuleDef_HEAD_INIT,
11655 MODNAME,
11656 posix__doc__,
11657 -1,
11658 posix_methods,
11659 NULL,
11660 NULL,
11661 NULL,
11662 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011663};
11664
11665
Larry Hastings9cf065c2012-06-22 16:30:09 -070011666static char *have_functions[] = {
11667
11668#ifdef HAVE_FACCESSAT
11669 "HAVE_FACCESSAT",
11670#endif
11671
11672#ifdef HAVE_FCHDIR
11673 "HAVE_FCHDIR",
11674#endif
11675
11676#ifdef HAVE_FCHMOD
11677 "HAVE_FCHMOD",
11678#endif
11679
11680#ifdef HAVE_FCHMODAT
11681 "HAVE_FCHMODAT",
11682#endif
11683
11684#ifdef HAVE_FCHOWN
11685 "HAVE_FCHOWN",
11686#endif
11687
11688#ifdef HAVE_FEXECVE
11689 "HAVE_FEXECVE",
11690#endif
11691
11692#ifdef HAVE_FDOPENDIR
11693 "HAVE_FDOPENDIR",
11694#endif
11695
Georg Brandl306336b2012-06-24 12:55:33 +020011696#ifdef HAVE_FPATHCONF
11697 "HAVE_FPATHCONF",
11698#endif
11699
Larry Hastings9cf065c2012-06-22 16:30:09 -070011700#ifdef HAVE_FSTATAT
11701 "HAVE_FSTATAT",
11702#endif
11703
11704#ifdef HAVE_FSTATVFS
11705 "HAVE_FSTATVFS",
11706#endif
11707
Georg Brandl306336b2012-06-24 12:55:33 +020011708#ifdef HAVE_FTRUNCATE
11709 "HAVE_FTRUNCATE",
11710#endif
11711
Larry Hastings9cf065c2012-06-22 16:30:09 -070011712#ifdef HAVE_FUTIMENS
11713 "HAVE_FUTIMENS",
11714#endif
11715
11716#ifdef HAVE_FUTIMES
11717 "HAVE_FUTIMES",
11718#endif
11719
11720#ifdef HAVE_FUTIMESAT
11721 "HAVE_FUTIMESAT",
11722#endif
11723
11724#ifdef HAVE_LINKAT
11725 "HAVE_LINKAT",
11726#endif
11727
11728#ifdef HAVE_LCHFLAGS
11729 "HAVE_LCHFLAGS",
11730#endif
11731
11732#ifdef HAVE_LCHMOD
11733 "HAVE_LCHMOD",
11734#endif
11735
11736#ifdef HAVE_LCHOWN
11737 "HAVE_LCHOWN",
11738#endif
11739
11740#ifdef HAVE_LSTAT
11741 "HAVE_LSTAT",
11742#endif
11743
11744#ifdef HAVE_LUTIMES
11745 "HAVE_LUTIMES",
11746#endif
11747
11748#ifdef HAVE_MKDIRAT
11749 "HAVE_MKDIRAT",
11750#endif
11751
11752#ifdef HAVE_MKFIFOAT
11753 "HAVE_MKFIFOAT",
11754#endif
11755
11756#ifdef HAVE_MKNODAT
11757 "HAVE_MKNODAT",
11758#endif
11759
11760#ifdef HAVE_OPENAT
11761 "HAVE_OPENAT",
11762#endif
11763
11764#ifdef HAVE_READLINKAT
11765 "HAVE_READLINKAT",
11766#endif
11767
11768#ifdef HAVE_RENAMEAT
11769 "HAVE_RENAMEAT",
11770#endif
11771
11772#ifdef HAVE_SYMLINKAT
11773 "HAVE_SYMLINKAT",
11774#endif
11775
11776#ifdef HAVE_UNLINKAT
11777 "HAVE_UNLINKAT",
11778#endif
11779
11780#ifdef HAVE_UTIMENSAT
11781 "HAVE_UTIMENSAT",
11782#endif
11783
11784#ifdef MS_WINDOWS
11785 "MS_WINDOWS",
11786#endif
11787
11788 NULL
11789};
11790
11791
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011792PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011793INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011794{
Victor Stinner8c62be82010-05-06 00:08:46 +000011795 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011796 PyObject *list;
11797 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011798
Brian Curtin52173d42010-12-02 18:29:18 +000011799#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011800 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011801#endif
11802
Victor Stinner8c62be82010-05-06 00:08:46 +000011803 m = PyModule_Create(&posixmodule);
11804 if (m == NULL)
11805 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011806
Victor Stinner8c62be82010-05-06 00:08:46 +000011807 /* Initialize environ dictionary */
11808 v = convertenviron();
11809 Py_XINCREF(v);
11810 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11811 return NULL;
11812 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011813
Victor Stinner8c62be82010-05-06 00:08:46 +000011814 if (all_ins(m))
11815 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011816
Victor Stinner8c62be82010-05-06 00:08:46 +000011817 if (setup_confname_tables(m))
11818 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011819
Victor Stinner8c62be82010-05-06 00:08:46 +000011820 Py_INCREF(PyExc_OSError);
11821 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011822
Guido van Rossumb3d39562000-01-31 18:41:26 +000011823#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011824 if (posix_putenv_garbage == NULL)
11825 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011826#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011827
Victor Stinner8c62be82010-05-06 00:08:46 +000011828 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011829#if defined(HAVE_WAITID) && !defined(__APPLE__)
11830 waitid_result_desc.name = MODNAME ".waitid_result";
11831 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11832#endif
11833
Victor Stinner8c62be82010-05-06 00:08:46 +000011834 stat_result_desc.name = MODNAME ".stat_result";
11835 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11836 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11837 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11838 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11839 structseq_new = StatResultType.tp_new;
11840 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011841
Victor Stinner8c62be82010-05-06 00:08:46 +000011842 statvfs_result_desc.name = MODNAME ".statvfs_result";
11843 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011844#ifdef NEED_TICKS_PER_SECOND
11845# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011846 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011847# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011848 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011849# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011850 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011851# endif
11852#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011853
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011854#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011855 sched_param_desc.name = MODNAME ".sched_param";
11856 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11857 SchedParamType.tp_new = sched_param_new;
11858#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011859
11860 /* initialize TerminalSize_info */
11861 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011862 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011863#if defined(HAVE_WAITID) && !defined(__APPLE__)
11864 Py_INCREF((PyObject*) &WaitidResultType);
11865 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11866#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011867 Py_INCREF((PyObject*) &StatResultType);
11868 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11869 Py_INCREF((PyObject*) &StatVFSResultType);
11870 PyModule_AddObject(m, "statvfs_result",
11871 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011872
11873#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011874 Py_INCREF(&SchedParamType);
11875 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011876#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011877
Larry Hastings605a62d2012-06-24 04:33:36 -070011878 times_result_desc.name = MODNAME ".times_result";
11879 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11880 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11881
11882 uname_result_desc.name = MODNAME ".uname_result";
11883 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11884 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11885
Thomas Wouters477c8d52006-05-27 19:21:47 +000011886#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011887 /*
11888 * Step 2 of weak-linking support on Mac OS X.
11889 *
11890 * The code below removes functions that are not available on the
11891 * currently active platform.
11892 *
11893 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011894 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011895 * OSX 10.4.
11896 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011897#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011898 if (fstatvfs == NULL) {
11899 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11900 return NULL;
11901 }
11902 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011903#endif /* HAVE_FSTATVFS */
11904
11905#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011906 if (statvfs == NULL) {
11907 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11908 return NULL;
11909 }
11910 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011911#endif /* HAVE_STATVFS */
11912
11913# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011914 if (lchown == NULL) {
11915 if (PyObject_DelAttrString(m, "lchown") == -1) {
11916 return NULL;
11917 }
11918 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011919#endif /* HAVE_LCHOWN */
11920
11921
11922#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011923
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020011924 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011925 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11926
Larry Hastings6fe20b32012-04-19 15:07:49 -070011927 billion = PyLong_FromLong(1000000000);
11928 if (!billion)
11929 return NULL;
11930
Larry Hastings9cf065c2012-06-22 16:30:09 -070011931 /* suppress "function not used" warnings */
11932 {
11933 int ignored;
11934 fd_specified("", -1);
11935 follow_symlinks_specified("", 1);
11936 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11937 dir_fd_converter(Py_None, &ignored);
11938 dir_fd_unavailable(Py_None, &ignored);
11939 }
11940
11941 /*
11942 * provide list of locally available functions
11943 * so os.py can populate support_* lists
11944 */
11945 list = PyList_New(0);
11946 if (!list)
11947 return NULL;
11948 for (trace = have_functions; *trace; trace++) {
11949 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11950 if (!unicode)
11951 return NULL;
11952 if (PyList_Append(list, unicode))
11953 return NULL;
11954 Py_DECREF(unicode);
11955 }
11956 PyModule_AddObject(m, "_have_functions", list);
11957
11958 initialized = 1;
11959
Victor Stinner8c62be82010-05-06 00:08:46 +000011960 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011961
Guido van Rossumb6775db1994-08-01 11:34:53 +000011962}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011963
11964#ifdef __cplusplus
11965}
11966#endif