blob: df0d81b02ec1f7b02821cb09ec332c8c9fecd9d5 [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
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 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
Jesus Ceaab70e2a2012-10-05 01:48:08 +02009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Thomas Wouters477c8d52006-05-27 19:21:47 +000011#ifdef __APPLE__
12 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000013 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000014 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
15 * at the end of this file for more information.
16 */
17# pragma weak lchown
18# pragma weak statvfs
19# pragma weak fstatvfs
20
21#endif /* __APPLE__ */
22
Thomas Wouters68bc4f92006-03-01 01:05:10 +000023#define PY_SSIZE_T_CLEAN
24
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000025#include "Python.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020026#ifndef MS_WINDOWS
27#include "posixmodule.h"
28#endif
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
Ross Lagerwall4d076da2011-03-18 06:56:53 +020046#ifdef HAVE_SYS_UIO_H
47#include <sys/uio.h>
48#endif
49
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052#endif /* HAVE_SYS_TYPES_H */
53
54#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000055#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000057
Guido van Rossum36bc6801995-06-14 22:54:23 +000058#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000059#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000060#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000061
Thomas Wouters0e3f5912006-08-11 14:57:12 +000062#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000063#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000065
Guido van Rossumb6775db1994-08-01 11:34:53 +000066#ifdef HAVE_FCNTL_H
67#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000068#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000069
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070#ifdef HAVE_GRP_H
71#include <grp.h>
72#endif
73
Barry Warsaw5676bd12003-01-07 20:57:09 +000074#ifdef HAVE_SYSEXITS_H
75#include <sysexits.h>
76#endif /* HAVE_SYSEXITS_H */
77
Anthony Baxter8a560de2004-10-13 15:30:56 +000078#ifdef HAVE_SYS_LOADAVG_H
79#include <sys/loadavg.h>
80#endif
81
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000082#ifdef HAVE_LANGINFO_H
83#include <langinfo.h>
84#endif
85
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000086#ifdef HAVE_SYS_SENDFILE_H
87#include <sys/sendfile.h>
88#endif
89
Benjamin Peterson94b580d2011-08-02 17:30:04 -050090#ifdef HAVE_SCHED_H
91#include <sched.h>
92#endif
93
Benjamin Peterson2dbda072012-03-16 10:12:55 -050094#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050095#undef HAVE_SCHED_SETAFFINITY
96#endif
97
Benjamin Peterson9428d532011-09-14 11:45:52 -040098#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
99#define USE_XATTRS
100#endif
101
102#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400103#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400104#endif
105
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000106#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
107#ifdef HAVE_SYS_SOCKET_H
108#include <sys/socket.h>
109#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000110#endif
111
Victor Stinner8b905bd2011-10-25 13:34:04 +0200112#ifdef HAVE_DLFCN_H
113#include <dlfcn.h>
114#endif
115
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200116#ifdef __hpux
117#include <sys/mpctl.h>
118#endif
119
120#if defined(__DragonFly__) || \
121 defined(__OpenBSD__) || \
122 defined(__FreeBSD__) || \
123 defined(__NetBSD__) || \
124 defined(__APPLE__)
125#include <sys/sysctl.h>
126#endif
127
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100128#if defined(MS_WINDOWS)
129# define TERMSIZE_USE_CONIO
130#elif defined(HAVE_SYS_IOCTL_H)
131# include <sys/ioctl.h>
132# if defined(HAVE_TERMIOS_H)
133# include <termios.h>
134# endif
135# if defined(TIOCGWINSZ)
136# define TERMSIZE_USE_IOCTL
137# endif
138#endif /* MS_WINDOWS */
139
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000141/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000142#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#include <process.h>
146#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000147#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000148#define HAVE_EXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_OPENDIR 1
150#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000152#define HAVE_WAIT 1
153#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000154#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000155#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000156#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000157#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000158#define HAVE_EXECV 1
159#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000160#define HAVE_SYSTEM 1
161#define HAVE_CWAIT 1
162#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000163#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000164#else
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200165#if defined(__VMS)
166/* Everything needed is defined in vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168/* Unix functions that the configure script doesn't check for */
169#define HAVE_EXECV 1
170#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000171#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000172#define HAVE_FORK1 1
173#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000174#define HAVE_GETEGID 1
175#define HAVE_GETEUID 1
176#define HAVE_GETGID 1
177#define HAVE_GETPPID 1
178#define HAVE_GETUID 1
179#define HAVE_KILL 1
180#define HAVE_OPENDIR 1
181#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000182#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000183#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000184#define HAVE_TTYNAME 1
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200185#endif /* __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000186#endif /* _MSC_VER */
187#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000188#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000189
Victor Stinnera2f7c002012-02-08 03:36:25 +0100190
191
192
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000193#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000194
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000195#if defined(__sgi)&&_COMPILER_VERSION>=700
196/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
197 (default) */
198extern char *ctermid_r(char *);
199#endif
200
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000201#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000202#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000205#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000207#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000210#endif
211#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int chdir(char *);
213extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000214#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000215extern int chdir(const char *);
216extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000217#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000218#ifdef __BORLANDC__
219extern int chmod(const char *, int);
220#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000221extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000222#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000223/*#ifdef HAVE_FCHMOD
224extern int fchmod(int, mode_t);
225#endif*/
226/*#ifdef HAVE_LCHMOD
227extern int lchmod(const char *, mode_t);
228#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000229extern int chown(const char *, uid_t, gid_t);
230extern char *getcwd(char *, int);
231extern char *strerror(int);
232extern int link(const char *, const char *);
233extern int rename(const char *, const char *);
234extern int stat(const char *, struct stat *);
235extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000237extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000238#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000240extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000241#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000243
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000244#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#ifdef HAVE_UTIME_H
247#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000248#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000250#ifdef HAVE_SYS_UTIME_H
251#include <sys/utime.h>
252#define HAVE_UTIME_H /* pretend we do for the rest of this file */
253#endif /* HAVE_SYS_UTIME_H */
254
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#ifdef HAVE_SYS_TIMES_H
256#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258
259#ifdef HAVE_SYS_PARAM_H
260#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000261#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262
263#ifdef HAVE_SYS_UTSNAME_H
264#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000265#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000267#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000269#define NAMLEN(dirent) strlen((dirent)->d_name)
270#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000271#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000272#include <direct.h>
273#define NAMLEN(dirent) strlen((dirent)->d_name)
274#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#endif
281#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#endif
284#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000286#endif
287#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000288
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000289#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000290#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000292#endif
293#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000294#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#endif
296#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000297#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000298#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000299#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000300#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000301#endif
302#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000303#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#endif
305#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000306#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000307#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000308#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000309#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000311#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000312#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000313#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
314#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000315static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000316#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000317#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318
Tim Petersbc2e10e2002-03-03 23:17:02 +0000319#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320#if defined(PATH_MAX) && PATH_MAX > 1024
321#define MAXPATHLEN PATH_MAX
322#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000323#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000325#endif /* MAXPATHLEN */
326
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000327#ifdef UNION_WAIT
328/* Emulate some macros on systems that have a union instead of macros */
329
330#ifndef WIFEXITED
331#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
332#endif
333
334#ifndef WEXITSTATUS
335#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
336#endif
337
338#ifndef WTERMSIG
339#define WTERMSIG(u_wait) ((u_wait).w_termsig)
340#endif
341
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000342#define WAIT_TYPE union wait
343#define WAIT_STATUS_INT(s) (s.w_status)
344
345#else /* !UNION_WAIT */
346#define WAIT_TYPE int
347#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000348#endif /* UNION_WAIT */
349
Greg Wardb48bc172000-03-01 21:51:56 +0000350/* Don't use the "_r" form if we don't need it (also, won't have a
351 prototype for it, at least on Solaris -- maybe others as well?). */
352#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
353#define USE_CTERMID_R
354#endif
355
Fred Drake699f3522000-06-29 21:12:41 +0000356/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000357#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000358#undef FSTAT
359#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200360#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000361# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700362# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000363# define FSTAT win32_fstat
364# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000365#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000366# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700367# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000368# define FSTAT fstat
369# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000370#endif
371
Tim Peters11b23062003-04-23 02:39:17 +0000372#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000373#include <sys/mkdev.h>
374#else
375#if defined(MAJOR_IN_SYSMACROS)
376#include <sys/sysmacros.h>
377#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000378#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
379#include <sys/mkdev.h>
380#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000381#endif
Fred Drake699f3522000-06-29 21:12:41 +0000382
Larry Hastings9cf065c2012-06-22 16:30:09 -0700383
384#ifdef MS_WINDOWS
385static int
386win32_warn_bytes_api()
387{
388 return PyErr_WarnEx(PyExc_DeprecationWarning,
389 "The Windows bytes API has been deprecated, "
390 "use Unicode filenames instead",
391 1);
392}
393#endif
394
395
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200396#ifndef MS_WINDOWS
397PyObject *
398_PyLong_FromUid(uid_t uid)
399{
400 if (uid == (uid_t)-1)
401 return PyLong_FromLong(-1);
402 return PyLong_FromUnsignedLong(uid);
403}
404
405PyObject *
406_PyLong_FromGid(gid_t gid)
407{
408 if (gid == (gid_t)-1)
409 return PyLong_FromLong(-1);
410 return PyLong_FromUnsignedLong(gid);
411}
412
413int
414_Py_Uid_Converter(PyObject *obj, void *p)
415{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700416 uid_t uid;
417 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200418 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200419 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700420 unsigned long uresult;
421
422 index = PyNumber_Index(obj);
423 if (index == NULL) {
424 PyErr_Format(PyExc_TypeError,
425 "uid should be integer, not %.200s",
426 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200427 return 0;
428 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700429
430 /*
431 * Handling uid_t is complicated for two reasons:
432 * * Although uid_t is (always?) unsigned, it still
433 * accepts -1.
434 * * We don't know its size in advance--it may be
435 * bigger than an int, or it may be smaller than
436 * a long.
437 *
438 * So a bit of defensive programming is in order.
439 * Start with interpreting the value passed
440 * in as a signed long and see if it works.
441 */
442
443 result = PyLong_AsLongAndOverflow(index, &overflow);
444
445 if (!overflow) {
446 uid = (uid_t)result;
447
448 if (result == -1) {
449 if (PyErr_Occurred())
450 goto fail;
451 /* It's a legitimate -1, we're done. */
452 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200453 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700454
455 /* Any other negative number is disallowed. */
456 if (result < 0)
457 goto underflow;
458
459 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200460 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700461 (long)uid != result)
462 goto underflow;
463 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200464 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700465
466 if (overflow < 0)
467 goto underflow;
468
469 /*
470 * Okay, the value overflowed a signed long. If it
471 * fits in an *unsigned* long, it may still be okay,
472 * as uid_t may be unsigned long on this platform.
473 */
474 uresult = PyLong_AsUnsignedLong(index);
475 if (PyErr_Occurred()) {
476 if (PyErr_ExceptionMatches(PyExc_OverflowError))
477 goto overflow;
478 goto fail;
479 }
480
481 uid = (uid_t)uresult;
482
483 /*
484 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
485 * but this value would get interpreted as (uid_t)-1 by chown
486 * and its siblings. That's not what the user meant! So we
487 * throw an overflow exception instead. (We already
488 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
489 */
490 if (uid == (uid_t)-1)
491 goto overflow;
492
493 /* Ensure the value wasn't truncated. */
494 if (sizeof(uid_t) < sizeof(long) &&
495 (unsigned long)uid != uresult)
496 goto overflow;
497 /* fallthrough */
498
499success:
500 Py_DECREF(index);
501 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200502 return 1;
503
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700504underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200505 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700506 "uid is less than minimum");
507 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200508
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700509overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200510 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700511 "uid is greater than maximum");
512 /* fallthrough */
513
514fail:
515 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200516 return 0;
517}
518
519int
520_Py_Gid_Converter(PyObject *obj, void *p)
521{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700522 gid_t gid;
523 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200524 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200525 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700526 unsigned long uresult;
527
528 index = PyNumber_Index(obj);
529 if (index == NULL) {
530 PyErr_Format(PyExc_TypeError,
531 "gid should be integer, not %.200s",
532 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200533 return 0;
534 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700535
536 /*
537 * Handling gid_t is complicated for two reasons:
538 * * Although gid_t is (always?) unsigned, it still
539 * accepts -1.
540 * * We don't know its size in advance--it may be
541 * bigger than an int, or it may be smaller than
542 * a long.
543 *
544 * So a bit of defensive programming is in order.
545 * Start with interpreting the value passed
546 * in as a signed long and see if it works.
547 */
548
549 result = PyLong_AsLongAndOverflow(index, &overflow);
550
551 if (!overflow) {
552 gid = (gid_t)result;
553
554 if (result == -1) {
555 if (PyErr_Occurred())
556 goto fail;
557 /* It's a legitimate -1, we're done. */
558 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200559 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700560
561 /* Any other negative number is disallowed. */
562 if (result < 0) {
563 goto underflow;
564 }
565
566 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200567 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700568 (long)gid != result)
569 goto underflow;
570 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200571 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700572
573 if (overflow < 0)
574 goto underflow;
575
576 /*
577 * Okay, the value overflowed a signed long. If it
578 * fits in an *unsigned* long, it may still be okay,
579 * as gid_t may be unsigned long on this platform.
580 */
581 uresult = PyLong_AsUnsignedLong(index);
582 if (PyErr_Occurred()) {
583 if (PyErr_ExceptionMatches(PyExc_OverflowError))
584 goto overflow;
585 goto fail;
586 }
587
588 gid = (gid_t)uresult;
589
590 /*
591 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
592 * but this value would get interpreted as (gid_t)-1 by chown
593 * and its siblings. That's not what the user meant! So we
594 * throw an overflow exception instead. (We already
595 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
596 */
597 if (gid == (gid_t)-1)
598 goto overflow;
599
600 /* Ensure the value wasn't truncated. */
601 if (sizeof(gid_t) < sizeof(long) &&
602 (unsigned long)gid != uresult)
603 goto overflow;
604 /* fallthrough */
605
606success:
607 Py_DECREF(index);
608 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200609 return 1;
610
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700611underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200612 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700613 "gid is less than minimum");
614 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200615
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200617 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618 "gid is greater than maximum");
619 /* fallthrough */
620
621fail:
622 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200623 return 0;
624}
625#endif /* MS_WINDOWS */
626
627
Larry Hastings9cf065c2012-06-22 16:30:09 -0700628#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400629/*
630 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
631 * without the int cast, the value gets interpreted as uint (4291925331),
632 * which doesn't play nicely with all the initializer lines in this file that
633 * look like this:
634 * int dir_fd = DEFAULT_DIR_FD;
635 */
636#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700637#else
638#define DEFAULT_DIR_FD (-100)
639#endif
640
641static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200642_fd_converter(PyObject *o, int *p, const char *allowed)
643{
644 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700645 long long_value;
646
647 PyObject *index = PyNumber_Index(o);
648 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200649 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700650 "argument should be %s, not %.200s",
651 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700652 return 0;
653 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700654
655 long_value = PyLong_AsLongAndOverflow(index, &overflow);
656 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200657 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700658 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700659 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700660 return 0;
661 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200662 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700663 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700664 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700665 return 0;
666 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700667
Larry Hastings9cf065c2012-06-22 16:30:09 -0700668 *p = (int)long_value;
669 return 1;
670}
671
672static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200673dir_fd_converter(PyObject *o, void *p)
674{
675 if (o == Py_None) {
676 *(int *)p = DEFAULT_DIR_FD;
677 return 1;
678 }
679 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700680}
681
682
683
684/*
685 * A PyArg_ParseTuple "converter" function
686 * that handles filesystem paths in the manner
687 * preferred by the os module.
688 *
689 * path_converter accepts (Unicode) strings and their
690 * subclasses, and bytes and their subclasses. What
691 * it does with the argument depends on the platform:
692 *
693 * * On Windows, if we get a (Unicode) string we
694 * extract the wchar_t * and return it; if we get
695 * bytes we extract the char * and return that.
696 *
697 * * On all other platforms, strings are encoded
698 * to bytes using PyUnicode_FSConverter, then we
699 * extract the char * from the bytes object and
700 * return that.
701 *
702 * path_converter also optionally accepts signed
703 * integers (representing open file descriptors) instead
704 * of path strings.
705 *
706 * Input fields:
707 * path.nullable
708 * If nonzero, the path is permitted to be None.
709 * path.allow_fd
710 * If nonzero, the path is permitted to be a file handle
711 * (a signed int) instead of a string.
712 * path.function_name
713 * If non-NULL, path_converter will use that as the name
714 * of the function in error messages.
715 * (If path.argument_name is NULL it omits the function name.)
716 * path.argument_name
717 * If non-NULL, path_converter will use that as the name
718 * of the parameter in error messages.
719 * (If path.argument_name is NULL it uses "path".)
720 *
721 * Output fields:
722 * path.wide
723 * Points to the path if it was expressed as Unicode
724 * and was not encoded. (Only used on Windows.)
725 * path.narrow
726 * Points to the path if it was expressed as bytes,
727 * or it was Unicode and was encoded to bytes.
728 * path.fd
729 * Contains a file descriptor if path.accept_fd was true
730 * and the caller provided a signed integer instead of any
731 * sort of string.
732 *
733 * WARNING: if your "path" parameter is optional, and is
734 * unspecified, path_converter will never get called.
735 * So if you set allow_fd, you *MUST* initialize path.fd = -1
736 * yourself!
737 * path.length
738 * The length of the path in characters, if specified as
739 * a string.
740 * path.object
741 * The original object passed in.
742 * path.cleanup
743 * For internal use only. May point to a temporary object.
744 * (Pay no attention to the man behind the curtain.)
745 *
746 * At most one of path.wide or path.narrow will be non-NULL.
747 * If path was None and path.nullable was set,
748 * or if path was an integer and path.allow_fd was set,
749 * both path.wide and path.narrow will be NULL
750 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200751 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700752 * path_converter takes care to not write to the path_t
753 * unless it's successful. However it must reset the
754 * "cleanup" field each time it's called.
755 *
756 * Use as follows:
757 * path_t path;
758 * memset(&path, 0, sizeof(path));
759 * PyArg_ParseTuple(args, "O&", path_converter, &path);
760 * // ... use values from path ...
761 * path_cleanup(&path);
762 *
763 * (Note that if PyArg_Parse fails you don't need to call
764 * path_cleanup(). However it is safe to do so.)
765 */
766typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100767 const char *function_name;
768 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700769 int nullable;
770 int allow_fd;
771 wchar_t *wide;
772 char *narrow;
773 int fd;
774 Py_ssize_t length;
775 PyObject *object;
776 PyObject *cleanup;
777} path_t;
778
779static void
780path_cleanup(path_t *path) {
781 if (path->cleanup) {
782 Py_DECREF(path->cleanup);
783 path->cleanup = NULL;
784 }
785}
786
787static int
788path_converter(PyObject *o, void *p) {
789 path_t *path = (path_t *)p;
790 PyObject *unicode, *bytes;
791 Py_ssize_t length;
792 char *narrow;
793
794#define FORMAT_EXCEPTION(exc, fmt) \
795 PyErr_Format(exc, "%s%s" fmt, \
796 path->function_name ? path->function_name : "", \
797 path->function_name ? ": " : "", \
798 path->argument_name ? path->argument_name : "path")
799
800 /* Py_CLEANUP_SUPPORTED support */
801 if (o == NULL) {
802 path_cleanup(path);
803 return 1;
804 }
805
806 /* ensure it's always safe to call path_cleanup() */
807 path->cleanup = NULL;
808
809 if (o == Py_None) {
810 if (!path->nullable) {
811 FORMAT_EXCEPTION(PyExc_TypeError,
812 "can't specify None for %s argument");
813 return 0;
814 }
815 path->wide = NULL;
816 path->narrow = NULL;
817 path->length = 0;
818 path->object = o;
819 path->fd = -1;
820 return 1;
821 }
822
823 unicode = PyUnicode_FromObject(o);
824 if (unicode) {
825#ifdef MS_WINDOWS
826 wchar_t *wide;
827 length = PyUnicode_GET_SIZE(unicode);
828 if (length > 32767) {
829 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
830 Py_DECREF(unicode);
831 return 0;
832 }
833
834 wide = PyUnicode_AsUnicode(unicode);
835 if (!wide) {
836 Py_DECREF(unicode);
837 return 0;
838 }
839
840 path->wide = wide;
841 path->narrow = NULL;
842 path->length = length;
843 path->object = o;
844 path->fd = -1;
845 path->cleanup = unicode;
846 return Py_CLEANUP_SUPPORTED;
847#else
848 int converted = PyUnicode_FSConverter(unicode, &bytes);
849 Py_DECREF(unicode);
850 if (!converted)
851 bytes = NULL;
852#endif
853 }
854 else {
855 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200856 if (PyObject_CheckBuffer(o))
857 bytes = PyBytes_FromObject(o);
858 else
859 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700860 if (!bytes) {
861 PyErr_Clear();
862 if (path->allow_fd) {
863 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200864 int result = _fd_converter(o, &fd,
865 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700866 if (result) {
867 path->wide = NULL;
868 path->narrow = NULL;
869 path->length = 0;
870 path->object = o;
871 path->fd = fd;
872 return result;
873 }
874 }
875 }
876 }
877
878 if (!bytes) {
879 if (!PyErr_Occurred())
880 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
881 return 0;
882 }
883
884#ifdef MS_WINDOWS
885 if (win32_warn_bytes_api()) {
886 Py_DECREF(bytes);
887 return 0;
888 }
889#endif
890
891 length = PyBytes_GET_SIZE(bytes);
892#ifdef MS_WINDOWS
893 if (length > MAX_PATH) {
894 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
895 Py_DECREF(bytes);
896 return 0;
897 }
898#endif
899
900 narrow = PyBytes_AS_STRING(bytes);
901 if (length != strlen(narrow)) {
902 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
903 Py_DECREF(bytes);
904 return 0;
905 }
906
907 path->wide = NULL;
908 path->narrow = narrow;
909 path->length = length;
910 path->object = o;
911 path->fd = -1;
912 path->cleanup = bytes;
913 return Py_CLEANUP_SUPPORTED;
914}
915
916static void
917argument_unavailable_error(char *function_name, char *argument_name) {
918 PyErr_Format(PyExc_NotImplementedError,
919 "%s%s%s unavailable on this platform",
920 (function_name != NULL) ? function_name : "",
921 (function_name != NULL) ? ": ": "",
922 argument_name);
923}
924
925static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200926dir_fd_unavailable(PyObject *o, void *p)
927{
928 int dir_fd;
929 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700930 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200931 if (dir_fd != DEFAULT_DIR_FD) {
932 argument_unavailable_error(NULL, "dir_fd");
933 return 0;
934 }
935 *(int *)p = dir_fd;
936 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700937}
938
939static int
940fd_specified(char *function_name, int fd) {
941 if (fd == -1)
942 return 0;
943
944 argument_unavailable_error(function_name, "fd");
945 return 1;
946}
947
948static int
949follow_symlinks_specified(char *function_name, int follow_symlinks) {
950 if (follow_symlinks)
951 return 0;
952
953 argument_unavailable_error(function_name, "follow_symlinks");
954 return 1;
955}
956
957static int
958path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
959 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
960 PyErr_Format(PyExc_ValueError,
961 "%s: can't specify dir_fd without matching path",
962 function_name);
963 return 1;
964 }
965 return 0;
966}
967
968static int
969dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
970 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
971 PyErr_Format(PyExc_ValueError,
972 "%s: can't specify both dir_fd and fd",
973 function_name);
974 return 1;
975 }
976 return 0;
977}
978
979static int
980fd_and_follow_symlinks_invalid(char *function_name, int fd,
981 int follow_symlinks) {
982 if ((fd > 0) && (!follow_symlinks)) {
983 PyErr_Format(PyExc_ValueError,
984 "%s: cannot use fd and follow_symlinks together",
985 function_name);
986 return 1;
987 }
988 return 0;
989}
990
991static int
992dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
993 int follow_symlinks) {
994 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
995 PyErr_Format(PyExc_ValueError,
996 "%s: cannot use dir_fd and follow_symlinks together",
997 function_name);
998 return 1;
999 }
1000 return 0;
1001}
1002
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001003/* A helper used by a number of POSIX-only functions */
1004#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +00001005static int
1006_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001007{
1008#if !defined(HAVE_LARGEFILE_SUPPORT)
1009 *((off_t*)addr) = PyLong_AsLong(arg);
1010#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +00001011 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001012#endif
1013 if (PyErr_Occurred())
1014 return 0;
1015 return 1;
1016}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001017#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001018
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001019#if defined _MSC_VER && _MSC_VER >= 1400
1020/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +02001021 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001022 * Normally, an invalid fd is likely to be a C program error and therefore
1023 * an assertion can be useful, but it does contradict the POSIX standard
1024 * which for write(2) states:
1025 * "Otherwise, -1 shall be returned and errno set to indicate the error."
1026 * "[EBADF] The fildes argument is not a valid file descriptor open for
1027 * writing."
1028 * Furthermore, python allows the user to enter any old integer
1029 * as a fd and should merely raise a python exception on error.
1030 * The Microsoft CRT doesn't provide an official way to check for the
1031 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +00001032 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001033 * internal structures involved.
1034 * The structures below must be updated for each version of visual studio
1035 * according to the file internal.h in the CRT source, until MS comes
1036 * up with a less hacky way to do this.
1037 * (all of this is to avoid globally modifying the CRT behaviour using
1038 * _set_invalid_parameter_handler() and _CrtSetReportMode())
1039 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001040/* The actual size of the structure is determined at runtime.
1041 * Only the first items must be present.
1042 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001043typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +00001044 intptr_t osfhnd;
1045 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001046} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001047
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001048extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001049#define IOINFO_L2E 5
1050#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
1051#define IOINFO_ARRAYS 64
1052#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
1053#define FOPEN 0x01
1054#define _NO_CONSOLE_FILENO (intptr_t)-2
1055
1056/* This function emulates what the windows CRT does to validate file handles */
1057int
1058_PyVerify_fd(int fd)
1059{
Victor Stinner8c62be82010-05-06 00:08:46 +00001060 const int i1 = fd >> IOINFO_L2E;
1061 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001062
Antoine Pitrou22e41552010-08-15 18:07:50 +00001063 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001064
Victor Stinner8c62be82010-05-06 00:08:46 +00001065 /* Determine the actual size of the ioinfo structure,
1066 * as used by the CRT loaded in memory
1067 */
1068 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
1069 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
1070 }
1071 if (sizeof_ioinfo == 0) {
1072 /* This should not happen... */
1073 goto fail;
1074 }
1075
1076 /* See that it isn't a special CLEAR fileno */
1077 if (fd != _NO_CONSOLE_FILENO) {
1078 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
1079 * we check pointer validity and other info
1080 */
1081 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
1082 /* finally, check that the file is open */
1083 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
1084 if (info->osfile & FOPEN) {
1085 return 1;
1086 }
1087 }
1088 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001089 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001090 errno = EBADF;
1091 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001092}
1093
1094/* the special case of checking dup2. The target fd must be in a sensible range */
1095static int
1096_PyVerify_fd_dup2(int fd1, int fd2)
1097{
Victor Stinner8c62be82010-05-06 00:08:46 +00001098 if (!_PyVerify_fd(fd1))
1099 return 0;
1100 if (fd2 == _NO_CONSOLE_FILENO)
1101 return 0;
1102 if ((unsigned)fd2 < _NHANDLE_)
1103 return 1;
1104 else
1105 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001106}
1107#else
1108/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1109#define _PyVerify_fd_dup2(A, B) (1)
1110#endif
1111
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001112#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001113/* The following structure was copied from
1114 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1115 include doesn't seem to be present in the Windows SDK (at least as included
1116 with Visual Studio Express). */
1117typedef struct _REPARSE_DATA_BUFFER {
1118 ULONG ReparseTag;
1119 USHORT ReparseDataLength;
1120 USHORT Reserved;
1121 union {
1122 struct {
1123 USHORT SubstituteNameOffset;
1124 USHORT SubstituteNameLength;
1125 USHORT PrintNameOffset;
1126 USHORT PrintNameLength;
1127 ULONG Flags;
1128 WCHAR PathBuffer[1];
1129 } SymbolicLinkReparseBuffer;
1130
1131 struct {
1132 USHORT SubstituteNameOffset;
1133 USHORT SubstituteNameLength;
1134 USHORT PrintNameOffset;
1135 USHORT PrintNameLength;
1136 WCHAR PathBuffer[1];
1137 } MountPointReparseBuffer;
1138
1139 struct {
1140 UCHAR DataBuffer[1];
1141 } GenericReparseBuffer;
1142 };
1143} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1144
1145#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1146 GenericReparseBuffer)
1147#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1148
1149static int
Brian Curtind25aef52011-06-13 15:16:04 -05001150win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001151{
1152 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1153 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1154 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001155
1156 if (0 == DeviceIoControl(
1157 reparse_point_handle,
1158 FSCTL_GET_REPARSE_POINT,
1159 NULL, 0, /* in buffer */
1160 target_buffer, sizeof(target_buffer),
1161 &n_bytes_returned,
1162 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001163 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001164
1165 if (reparse_tag)
1166 *reparse_tag = rdb->ReparseTag;
1167
Brian Curtind25aef52011-06-13 15:16:04 -05001168 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001169}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001170
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001171#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001172
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001173/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001174#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001175/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001176** environ directly, we must obtain it with _NSGetEnviron(). See also
1177** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001178*/
1179#include <crt_externs.h>
1180static char **environ;
1181#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001182extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001183#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001184
Barry Warsaw53699e91996-12-10 23:23:01 +00001185static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001186convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001187{
Victor Stinner8c62be82010-05-06 00:08:46 +00001188 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001189#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001190 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001191#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001192 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001193#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001194
Victor Stinner8c62be82010-05-06 00:08:46 +00001195 d = PyDict_New();
1196 if (d == NULL)
1197 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001198#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001199 if (environ == NULL)
1200 environ = *_NSGetEnviron();
1201#endif
1202#ifdef MS_WINDOWS
1203 /* _wenviron must be initialized in this way if the program is started
1204 through main() instead of wmain(). */
1205 _wgetenv(L"");
1206 if (_wenviron == NULL)
1207 return d;
1208 /* This part ignores errors */
1209 for (e = _wenviron; *e != NULL; e++) {
1210 PyObject *k;
1211 PyObject *v;
1212 wchar_t *p = wcschr(*e, L'=');
1213 if (p == NULL)
1214 continue;
1215 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1216 if (k == NULL) {
1217 PyErr_Clear();
1218 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001219 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001220 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1221 if (v == NULL) {
1222 PyErr_Clear();
1223 Py_DECREF(k);
1224 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001225 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001226 if (PyDict_GetItem(d, k) == NULL) {
1227 if (PyDict_SetItem(d, k, v) != 0)
1228 PyErr_Clear();
1229 }
1230 Py_DECREF(k);
1231 Py_DECREF(v);
1232 }
1233#else
1234 if (environ == NULL)
1235 return d;
1236 /* This part ignores errors */
1237 for (e = environ; *e != NULL; e++) {
1238 PyObject *k;
1239 PyObject *v;
1240 char *p = strchr(*e, '=');
1241 if (p == NULL)
1242 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001243 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001244 if (k == NULL) {
1245 PyErr_Clear();
1246 continue;
1247 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001248 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001249 if (v == NULL) {
1250 PyErr_Clear();
1251 Py_DECREF(k);
1252 continue;
1253 }
1254 if (PyDict_GetItem(d, k) == NULL) {
1255 if (PyDict_SetItem(d, k, v) != 0)
1256 PyErr_Clear();
1257 }
1258 Py_DECREF(k);
1259 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001260 }
1261#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001262 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001263}
1264
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001265/* Set a POSIX-specific error from errno, and return NULL */
1266
Barry Warsawd58d7641998-07-23 16:14:40 +00001267static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001268posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001269{
Victor Stinner8c62be82010-05-06 00:08:46 +00001270 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001271}
Mark Hammondef8b6542001-05-13 08:04:26 +00001272
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001273#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001274static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001275win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001276{
Victor Stinner8c62be82010-05-06 00:08:46 +00001277 /* XXX We should pass the function name along in the future.
1278 (winreg.c also wants to pass the function name.)
1279 This would however require an additional param to the
1280 Windows error object, which is non-trivial.
1281 */
1282 errno = GetLastError();
1283 if (filename)
1284 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1285 else
1286 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001287}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001288
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001289static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001290win32_error_object(char* function, PyObject* filename)
1291{
1292 /* XXX - see win32_error for comments on 'function' */
1293 errno = GetLastError();
1294 if (filename)
1295 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001296 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001297 errno,
1298 filename);
1299 else
1300 return PyErr_SetFromWindowsErr(errno);
1301}
1302
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001303#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001304
Larry Hastings9cf065c2012-06-22 16:30:09 -07001305static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001306path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001307{
1308#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001309 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1310 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001311#else
Victor Stinner292c8352012-10-30 02:17:38 +01001312 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001313#endif
1314}
1315
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001316/* POSIX generic methods */
1317
Barry Warsaw53699e91996-12-10 23:23:01 +00001318static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001319posix_fildes(PyObject *fdobj, int (*func)(int))
1320{
Victor Stinner8c62be82010-05-06 00:08:46 +00001321 int fd;
1322 int res;
1323 fd = PyObject_AsFileDescriptor(fdobj);
1324 if (fd < 0)
1325 return NULL;
1326 if (!_PyVerify_fd(fd))
1327 return posix_error();
1328 Py_BEGIN_ALLOW_THREADS
1329 res = (*func)(fd);
1330 Py_END_ALLOW_THREADS
1331 if (res < 0)
1332 return posix_error();
1333 Py_INCREF(Py_None);
1334 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001335}
Guido van Rossum21142a01999-01-08 21:05:37 +00001336
1337static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001338posix_1str(const char *func_name, PyObject *args, char *format,
1339 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001340{
Victor Stinner292c8352012-10-30 02:17:38 +01001341 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001342 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001343 memset(&path, 0, sizeof(path));
1344 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001345 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001346 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001347 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001348 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001349 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001350 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001351 if (res < 0) {
1352 path_error(&path);
1353 path_cleanup(&path);
1354 return NULL;
1355 }
1356 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001357 Py_INCREF(Py_None);
1358 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001359}
1360
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001361
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001362#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001363/* This is a reimplementation of the C library's chdir function,
1364 but one that produces Win32 errors instead of DOS error codes.
1365 chdir is essentially a wrapper around SetCurrentDirectory; however,
1366 it also needs to set "magic" environment variables indicating
1367 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001368static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001369win32_chdir(LPCSTR path)
1370{
Victor Stinner8c62be82010-05-06 00:08:46 +00001371 char new_path[MAX_PATH+1];
1372 int result;
1373 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001374
Victor Stinner8c62be82010-05-06 00:08:46 +00001375 if(!SetCurrentDirectoryA(path))
1376 return FALSE;
1377 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1378 if (!result)
1379 return FALSE;
1380 /* In the ANSI API, there should not be any paths longer
1381 than MAX_PATH. */
1382 assert(result <= MAX_PATH+1);
1383 if (strncmp(new_path, "\\\\", 2) == 0 ||
1384 strncmp(new_path, "//", 2) == 0)
1385 /* UNC path, nothing to do. */
1386 return TRUE;
1387 env[1] = new_path[0];
1388 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001389}
1390
1391/* The Unicode version differs from the ANSI version
1392 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001393static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001394win32_wchdir(LPCWSTR path)
1395{
Victor Stinner8c62be82010-05-06 00:08:46 +00001396 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1397 int result;
1398 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001399
Victor Stinner8c62be82010-05-06 00:08:46 +00001400 if(!SetCurrentDirectoryW(path))
1401 return FALSE;
1402 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1403 if (!result)
1404 return FALSE;
1405 if (result > MAX_PATH+1) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001406 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001407 if (!new_path) {
1408 SetLastError(ERROR_OUTOFMEMORY);
1409 return FALSE;
1410 }
1411 result = GetCurrentDirectoryW(result, new_path);
1412 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001413 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001414 return FALSE;
1415 }
1416 }
1417 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1418 wcsncmp(new_path, L"//", 2) == 0)
1419 /* UNC path, nothing to do. */
1420 return TRUE;
1421 env[1] = new_path[0];
1422 result = SetEnvironmentVariableW(env, new_path);
1423 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001424 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001425 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001426}
1427#endif
1428
Martin v. Löwis14694662006-02-03 12:54:16 +00001429#ifdef MS_WINDOWS
1430/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1431 - time stamps are restricted to second resolution
1432 - file modification times suffer from forth-and-back conversions between
1433 UTC and local time
1434 Therefore, we implement our own stat, based on the Win32 API directly.
1435*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001436#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001437
1438struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001439 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001440 __int64 st_ino;
1441 unsigned short st_mode;
1442 int st_nlink;
1443 int st_uid;
1444 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001445 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001446 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001447 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001448 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001449 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001450 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001451 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001452 int st_ctime_nsec;
1453};
1454
1455static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1456
1457static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001458FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001459{
Victor Stinner8c62be82010-05-06 00:08:46 +00001460 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1461 /* Cannot simply cast and dereference in_ptr,
1462 since it might not be aligned properly */
1463 __int64 in;
1464 memcpy(&in, in_ptr, sizeof(in));
1465 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001466 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001467}
1468
Thomas Wouters477c8d52006-05-27 19:21:47 +00001469static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001470time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001471{
Victor Stinner8c62be82010-05-06 00:08:46 +00001472 /* XXX endianness */
1473 __int64 out;
1474 out = time_in + secs_between_epochs;
1475 out = out * 10000000 + nsec_in / 100;
1476 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001477}
1478
Martin v. Löwis14694662006-02-03 12:54:16 +00001479/* Below, we *know* that ugo+r is 0444 */
1480#if _S_IREAD != 0400
1481#error Unsupported C library
1482#endif
1483static int
1484attributes_to_mode(DWORD attr)
1485{
Victor Stinner8c62be82010-05-06 00:08:46 +00001486 int m = 0;
1487 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1488 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1489 else
1490 m |= _S_IFREG;
1491 if (attr & FILE_ATTRIBUTE_READONLY)
1492 m |= 0444;
1493 else
1494 m |= 0666;
1495 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001496}
1497
1498static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001499attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001500{
Victor Stinner8c62be82010-05-06 00:08:46 +00001501 memset(result, 0, sizeof(*result));
1502 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1503 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001504 result->st_dev = info->dwVolumeSerialNumber;
1505 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001506 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1507 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1508 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001509 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001510 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001511 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1512 /* first clear the S_IFMT bits */
Christian Heimes99d61352013-06-23 23:56:05 +02001513 result->st_mode ^= (result->st_mode & S_IFMT);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001514 /* now set the bits that make this a symlink */
Christian Heimes99d61352013-06-23 23:56:05 +02001515 result->st_mode |= S_IFLNK;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001516 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001517
Victor Stinner8c62be82010-05-06 00:08:46 +00001518 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001519}
1520
Guido van Rossumd8faa362007-04-27 19:54:29 +00001521static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001522attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001523{
Victor Stinner8c62be82010-05-06 00:08:46 +00001524 HANDLE hFindFile;
1525 WIN32_FIND_DATAA FileData;
1526 hFindFile = FindFirstFileA(pszFile, &FileData);
1527 if (hFindFile == INVALID_HANDLE_VALUE)
1528 return FALSE;
1529 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001530 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001531 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001532 info->dwFileAttributes = FileData.dwFileAttributes;
1533 info->ftCreationTime = FileData.ftCreationTime;
1534 info->ftLastAccessTime = FileData.ftLastAccessTime;
1535 info->ftLastWriteTime = FileData.ftLastWriteTime;
1536 info->nFileSizeHigh = FileData.nFileSizeHigh;
1537 info->nFileSizeLow = FileData.nFileSizeLow;
1538/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001539 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1540 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001541 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001542}
1543
1544static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001545attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001546{
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 HANDLE hFindFile;
1548 WIN32_FIND_DATAW FileData;
1549 hFindFile = FindFirstFileW(pszFile, &FileData);
1550 if (hFindFile == INVALID_HANDLE_VALUE)
1551 return FALSE;
1552 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001553 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001554 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001555 info->dwFileAttributes = FileData.dwFileAttributes;
1556 info->ftCreationTime = FileData.ftCreationTime;
1557 info->ftLastAccessTime = FileData.ftLastAccessTime;
1558 info->ftLastWriteTime = FileData.ftLastWriteTime;
1559 info->nFileSizeHigh = FileData.nFileSizeHigh;
1560 info->nFileSizeLow = FileData.nFileSizeLow;
1561/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001562 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1563 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001564 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001565}
1566
Brian Curtind25aef52011-06-13 15:16:04 -05001567/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001568static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001569static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1570 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001571static int
Brian Curtind25aef52011-06-13 15:16:04 -05001572check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001573{
Brian Curtind25aef52011-06-13 15:16:04 -05001574 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001575 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1576 DWORD);
1577
Brian Curtind25aef52011-06-13 15:16:04 -05001578 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001579 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001580 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001581 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001582 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1583 "GetFinalPathNameByHandleA");
1584 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1585 "GetFinalPathNameByHandleW");
1586 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1587 Py_GetFinalPathNameByHandleW;
1588 }
1589 return has_GetFinalPathNameByHandle;
1590}
1591
1592static BOOL
1593get_target_path(HANDLE hdl, wchar_t **target_path)
1594{
1595 int buf_size, result_length;
1596 wchar_t *buf;
1597
1598 /* We have a good handle to the target, use it to determine
1599 the target path name (then we'll call lstat on it). */
1600 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1601 VOLUME_NAME_DOS);
1602 if(!buf_size)
1603 return FALSE;
1604
Victor Stinnerb6404912013-07-07 16:21:41 +02001605 buf = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001606 if (!buf) {
1607 SetLastError(ERROR_OUTOFMEMORY);
1608 return FALSE;
1609 }
1610
Brian Curtind25aef52011-06-13 15:16:04 -05001611 result_length = Py_GetFinalPathNameByHandleW(hdl,
1612 buf, buf_size, VOLUME_NAME_DOS);
1613
1614 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001615 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001616 return FALSE;
1617 }
1618
1619 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001620 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001621 return FALSE;
1622 }
1623
1624 buf[result_length] = 0;
1625
1626 *target_path = buf;
1627 return TRUE;
1628}
1629
1630static int
1631win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1632 BOOL traverse);
1633static int
1634win32_xstat_impl(const char *path, struct win32_stat *result,
1635 BOOL traverse)
1636{
Victor Stinner26de69d2011-06-17 15:15:38 +02001637 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001638 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001639 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001640 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001641 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001642 const char *dot;
1643
Brian Curtind25aef52011-06-13 15:16:04 -05001644 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001645 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1646 traverse reparse point. */
1647 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001648 }
1649
Brian Curtinf5e76d02010-11-24 13:14:05 +00001650 hFile = CreateFileA(
1651 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001652 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001653 0, /* share mode */
1654 NULL, /* security attributes */
1655 OPEN_EXISTING,
1656 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001657 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1658 Because of this, calls like GetFinalPathNameByHandle will return
1659 the symlink path agin and not the actual final path. */
1660 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1661 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001662 NULL);
1663
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001664 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001665 /* Either the target doesn't exist, or we don't have access to
1666 get a handle to it. If the former, we need to return an error.
1667 If the latter, we can use attributes_from_dir. */
1668 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001669 return -1;
1670 /* Could not get attributes on open file. Fall back to
1671 reading the directory. */
1672 if (!attributes_from_dir(path, &info, &reparse_tag))
1673 /* Very strange. This should not fail now */
1674 return -1;
1675 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1676 if (traverse) {
1677 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001678 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001679 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001680 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001681 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001682 } else {
1683 if (!GetFileInformationByHandle(hFile, &info)) {
1684 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001685 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001686 }
1687 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001688 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1689 return -1;
1690
1691 /* Close the outer open file handle now that we're about to
1692 reopen it with different flags. */
1693 if (!CloseHandle(hFile))
1694 return -1;
1695
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001696 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001697 /* In order to call GetFinalPathNameByHandle we need to open
1698 the file without the reparse handling flag set. */
1699 hFile2 = CreateFileA(
1700 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1701 NULL, OPEN_EXISTING,
1702 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1703 NULL);
1704 if (hFile2 == INVALID_HANDLE_VALUE)
1705 return -1;
1706
1707 if (!get_target_path(hFile2, &target_path))
1708 return -1;
1709
1710 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001711 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001712 return code;
1713 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001714 } else
1715 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001716 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001717 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001718
1719 /* Set S_IEXEC if it is an .exe, .bat, ... */
1720 dot = strrchr(path, '.');
1721 if (dot) {
1722 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1723 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1724 result->st_mode |= 0111;
1725 }
1726 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001727}
1728
1729static int
Brian Curtind25aef52011-06-13 15:16:04 -05001730win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1731 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001732{
1733 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001734 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001735 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001736 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001737 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001738 const wchar_t *dot;
1739
Brian Curtind25aef52011-06-13 15:16:04 -05001740 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001741 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1742 traverse reparse point. */
1743 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001744 }
1745
Brian Curtinf5e76d02010-11-24 13:14:05 +00001746 hFile = CreateFileW(
1747 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001748 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001749 0, /* share mode */
1750 NULL, /* security attributes */
1751 OPEN_EXISTING,
1752 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001753 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1754 Because of this, calls like GetFinalPathNameByHandle will return
1755 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001756 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001757 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001758 NULL);
1759
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001760 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001761 /* Either the target doesn't exist, or we don't have access to
1762 get a handle to it. If the former, we need to return an error.
1763 If the latter, we can use attributes_from_dir. */
1764 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001765 return -1;
1766 /* Could not get attributes on open file. Fall back to
1767 reading the directory. */
1768 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1769 /* Very strange. This should not fail now */
1770 return -1;
1771 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1772 if (traverse) {
1773 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001774 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001775 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001776 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001777 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001778 } else {
1779 if (!GetFileInformationByHandle(hFile, &info)) {
1780 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001781 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001782 }
1783 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001784 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1785 return -1;
1786
1787 /* Close the outer open file handle now that we're about to
1788 reopen it with different flags. */
1789 if (!CloseHandle(hFile))
1790 return -1;
1791
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001792 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001793 /* In order to call GetFinalPathNameByHandle we need to open
1794 the file without the reparse handling flag set. */
1795 hFile2 = CreateFileW(
1796 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1797 NULL, OPEN_EXISTING,
1798 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1799 NULL);
1800 if (hFile2 == INVALID_HANDLE_VALUE)
1801 return -1;
1802
1803 if (!get_target_path(hFile2, &target_path))
1804 return -1;
1805
1806 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001807 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001808 return code;
1809 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001810 } else
1811 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001812 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001813 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001814
1815 /* Set S_IEXEC if it is an .exe, .bat, ... */
1816 dot = wcsrchr(path, '.');
1817 if (dot) {
1818 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1819 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1820 result->st_mode |= 0111;
1821 }
1822 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001823}
1824
1825static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001826win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001827{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001828 /* Protocol violation: we explicitly clear errno, instead of
1829 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001830 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001831 errno = 0;
1832 return code;
1833}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001834
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001835static int
1836win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1837{
1838 /* Protocol violation: we explicitly clear errno, instead of
1839 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001840 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001841 errno = 0;
1842 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001843}
Brian Curtind25aef52011-06-13 15:16:04 -05001844/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001845
1846 In Posix, stat automatically traverses symlinks and returns the stat
1847 structure for the target. In Windows, the equivalent GetFileAttributes by
1848 default does not traverse symlinks and instead returns attributes for
1849 the symlink.
1850
1851 Therefore, win32_lstat will get the attributes traditionally, and
1852 win32_stat will first explicitly resolve the symlink target and then will
1853 call win32_lstat on that result.
1854
Ezio Melotti4969f702011-03-15 05:59:46 +02001855 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001856
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001857static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001858win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001859{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001860 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001861}
1862
Victor Stinner8c62be82010-05-06 00:08:46 +00001863static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001864win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001865{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001866 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001867}
1868
1869static int
1870win32_stat(const char* path, struct win32_stat *result)
1871{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001872 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001873}
1874
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001875static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001876win32_stat_w(const wchar_t* path, struct win32_stat *result)
1877{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001878 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001879}
1880
1881static int
1882win32_fstat(int file_number, struct win32_stat *result)
1883{
Victor Stinner8c62be82010-05-06 00:08:46 +00001884 BY_HANDLE_FILE_INFORMATION info;
1885 HANDLE h;
1886 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001887
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001888 if (!_PyVerify_fd(file_number))
1889 h = INVALID_HANDLE_VALUE;
1890 else
1891 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001892
Victor Stinner8c62be82010-05-06 00:08:46 +00001893 /* Protocol violation: we explicitly clear errno, instead of
1894 setting it to a POSIX error. Callers should use GetLastError. */
1895 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001896
Victor Stinner8c62be82010-05-06 00:08:46 +00001897 if (h == INVALID_HANDLE_VALUE) {
1898 /* This is really a C library error (invalid file handle).
1899 We set the Win32 error to the closes one matching. */
1900 SetLastError(ERROR_INVALID_HANDLE);
1901 return -1;
1902 }
1903 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001904
Victor Stinner8c62be82010-05-06 00:08:46 +00001905 type = GetFileType(h);
1906 if (type == FILE_TYPE_UNKNOWN) {
1907 DWORD error = GetLastError();
1908 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001909 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001910 }
1911 /* else: valid but unknown file */
1912 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001913
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 if (type != FILE_TYPE_DISK) {
1915 if (type == FILE_TYPE_CHAR)
1916 result->st_mode = _S_IFCHR;
1917 else if (type == FILE_TYPE_PIPE)
1918 result->st_mode = _S_IFIFO;
1919 return 0;
1920 }
1921
1922 if (!GetFileInformationByHandle(h, &info)) {
1923 return -1;
1924 }
1925
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001926 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001927 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001928 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1929 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001930}
1931
1932#endif /* MS_WINDOWS */
1933
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001934PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001935"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001936This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001937 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001938or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1939\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001940Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1941or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001942\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001943See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001944
1945static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001946 {"st_mode", "protection bits"},
1947 {"st_ino", "inode"},
1948 {"st_dev", "device"},
1949 {"st_nlink", "number of hard links"},
1950 {"st_uid", "user ID of owner"},
1951 {"st_gid", "group ID of owner"},
1952 {"st_size", "total size, in bytes"},
1953 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1954 {NULL, "integer time of last access"},
1955 {NULL, "integer time of last modification"},
1956 {NULL, "integer time of last change"},
1957 {"st_atime", "time of last access"},
1958 {"st_mtime", "time of last modification"},
1959 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001960 {"st_atime_ns", "time of last access in nanoseconds"},
1961 {"st_mtime_ns", "time of last modification in nanoseconds"},
1962 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001963#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001964 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001965#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001966#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001967 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001968#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001969#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001970 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001971#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001972#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001973 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001974#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001975#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001976 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001977#endif
1978#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001979 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001980#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001981 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001982};
1983
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001984#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001985#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001986#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001987#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001988#endif
1989
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001990#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001991#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1992#else
1993#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1994#endif
1995
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001996#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001997#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1998#else
1999#define ST_RDEV_IDX ST_BLOCKS_IDX
2000#endif
2001
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002002#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2003#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2004#else
2005#define ST_FLAGS_IDX ST_RDEV_IDX
2006#endif
2007
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002008#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002009#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002010#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002011#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002012#endif
2013
2014#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2015#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2016#else
2017#define ST_BIRTHTIME_IDX ST_GEN_IDX
2018#endif
2019
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002020static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002021 "stat_result", /* name */
2022 stat_result__doc__, /* doc */
2023 stat_result_fields,
2024 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002025};
2026
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002027PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002028"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2029This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002030 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002031or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002032\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002033See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002034
2035static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002036 {"f_bsize", },
2037 {"f_frsize", },
2038 {"f_blocks", },
2039 {"f_bfree", },
2040 {"f_bavail", },
2041 {"f_files", },
2042 {"f_ffree", },
2043 {"f_favail", },
2044 {"f_flag", },
2045 {"f_namemax",},
2046 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002047};
2048
2049static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 "statvfs_result", /* name */
2051 statvfs_result__doc__, /* doc */
2052 statvfs_result_fields,
2053 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002054};
2055
Ross Lagerwall7807c352011-03-17 20:20:30 +02002056#if defined(HAVE_WAITID) && !defined(__APPLE__)
2057PyDoc_STRVAR(waitid_result__doc__,
2058"waitid_result: Result from waitid.\n\n\
2059This object may be accessed either as a tuple of\n\
2060 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2061or via the attributes si_pid, si_uid, and so on.\n\
2062\n\
2063See os.waitid for more information.");
2064
2065static PyStructSequence_Field waitid_result_fields[] = {
2066 {"si_pid", },
2067 {"si_uid", },
2068 {"si_signo", },
2069 {"si_status", },
2070 {"si_code", },
2071 {0}
2072};
2073
2074static PyStructSequence_Desc waitid_result_desc = {
2075 "waitid_result", /* name */
2076 waitid_result__doc__, /* doc */
2077 waitid_result_fields,
2078 5
2079};
2080static PyTypeObject WaitidResultType;
2081#endif
2082
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002083static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002084static PyTypeObject StatResultType;
2085static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002086#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002087static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002088#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002089static newfunc structseq_new;
2090
2091static PyObject *
2092statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2093{
Victor Stinner8c62be82010-05-06 00:08:46 +00002094 PyStructSequence *result;
2095 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002096
Victor Stinner8c62be82010-05-06 00:08:46 +00002097 result = (PyStructSequence*)structseq_new(type, args, kwds);
2098 if (!result)
2099 return NULL;
2100 /* If we have been initialized from a tuple,
2101 st_?time might be set to None. Initialize it
2102 from the int slots. */
2103 for (i = 7; i <= 9; i++) {
2104 if (result->ob_item[i+3] == Py_None) {
2105 Py_DECREF(Py_None);
2106 Py_INCREF(result->ob_item[i]);
2107 result->ob_item[i+3] = result->ob_item[i];
2108 }
2109 }
2110 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002111}
2112
2113
2114
2115/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002116static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002117
2118PyDoc_STRVAR(stat_float_times__doc__,
2119"stat_float_times([newval]) -> oldval\n\n\
2120Determine whether os.[lf]stat represents time stamps as float objects.\n\
2121If newval is True, future calls to stat() return floats, if it is False,\n\
2122future calls return ints. \n\
2123If newval is omitted, return the current setting.\n");
2124
2125static PyObject*
2126stat_float_times(PyObject* self, PyObject *args)
2127{
Victor Stinner8c62be82010-05-06 00:08:46 +00002128 int newval = -1;
2129 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2130 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002131 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2132 "stat_float_times() is deprecated",
2133 1))
2134 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 if (newval == -1)
2136 /* Return old value */
2137 return PyBool_FromLong(_stat_float_times);
2138 _stat_float_times = newval;
2139 Py_INCREF(Py_None);
2140 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002141}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002142
Larry Hastings6fe20b32012-04-19 15:07:49 -07002143static PyObject *billion = NULL;
2144
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002145static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002146fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002147{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002148 PyObject *s = _PyLong_FromTime_t(sec);
2149 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2150 PyObject *s_in_ns = NULL;
2151 PyObject *ns_total = NULL;
2152 PyObject *float_s = NULL;
2153
2154 if (!(s && ns_fractional))
2155 goto exit;
2156
2157 s_in_ns = PyNumber_Multiply(s, billion);
2158 if (!s_in_ns)
2159 goto exit;
2160
2161 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2162 if (!ns_total)
2163 goto exit;
2164
Victor Stinner4195b5c2012-02-08 23:03:19 +01002165 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002166 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2167 if (!float_s)
2168 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002169 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002170 else {
2171 float_s = s;
2172 Py_INCREF(float_s);
2173 }
2174
2175 PyStructSequence_SET_ITEM(v, index, s);
2176 PyStructSequence_SET_ITEM(v, index+3, float_s);
2177 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2178 s = NULL;
2179 float_s = NULL;
2180 ns_total = NULL;
2181exit:
2182 Py_XDECREF(s);
2183 Py_XDECREF(ns_fractional);
2184 Py_XDECREF(s_in_ns);
2185 Py_XDECREF(ns_total);
2186 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002187}
2188
Tim Peters5aa91602002-01-30 05:46:57 +00002189/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002190 (used by posix_stat() and posix_fstat()) */
2191static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002192_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002193{
Victor Stinner8c62be82010-05-06 00:08:46 +00002194 unsigned long ansec, mnsec, cnsec;
2195 PyObject *v = PyStructSequence_New(&StatResultType);
2196 if (v == NULL)
2197 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002198
Victor Stinner8c62be82010-05-06 00:08:46 +00002199 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002200#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002201 PyStructSequence_SET_ITEM(v, 1,
2202 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002203#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002204 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002205#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002206#ifdef MS_WINDOWS
2207 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
2208#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00002209 PyStructSequence_SET_ITEM(v, 2,
2210 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002211#else
Brian Curtin9cc43212013-01-01 12:31:06 -06002212 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002213#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002214 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002215#if defined(MS_WINDOWS)
2216 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2217 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2218#else
2219 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2220 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2221#endif
Fred Drake699f3522000-06-29 21:12:41 +00002222#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002223 PyStructSequence_SET_ITEM(v, 6,
2224 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002225#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002226 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002227#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002228
Martin v. Löwis14694662006-02-03 12:54:16 +00002229#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002230 ansec = st->st_atim.tv_nsec;
2231 mnsec = st->st_mtim.tv_nsec;
2232 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002233#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002234 ansec = st->st_atimespec.tv_nsec;
2235 mnsec = st->st_mtimespec.tv_nsec;
2236 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002237#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002238 ansec = st->st_atime_nsec;
2239 mnsec = st->st_mtime_nsec;
2240 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002241#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002242 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002243#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002244 fill_time(v, 7, st->st_atime, ansec);
2245 fill_time(v, 8, st->st_mtime, mnsec);
2246 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002247
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002248#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002249 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2250 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002251#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002252#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002253 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2254 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002255#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002256#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002257 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2258 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002259#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002260#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002261 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2262 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002263#endif
2264#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002265 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002266 PyObject *val;
2267 unsigned long bsec,bnsec;
2268 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002269#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002270 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002271#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002272 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002273#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002274 if (_stat_float_times) {
2275 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2276 } else {
2277 val = PyLong_FromLong((long)bsec);
2278 }
2279 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2280 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002281 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002282#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002283#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002284 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2285 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002286#endif
Fred Drake699f3522000-06-29 21:12:41 +00002287
Victor Stinner8c62be82010-05-06 00:08:46 +00002288 if (PyErr_Occurred()) {
2289 Py_DECREF(v);
2290 return NULL;
2291 }
Fred Drake699f3522000-06-29 21:12:41 +00002292
Victor Stinner8c62be82010-05-06 00:08:46 +00002293 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002294}
2295
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002296/* POSIX methods */
2297
Guido van Rossum94f6f721999-01-06 18:42:14 +00002298
2299static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002300posix_do_stat(char *function_name, path_t *path,
2301 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002302{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002303 STRUCT_STAT st;
2304 int result;
2305
2306#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2307 if (follow_symlinks_specified(function_name, follow_symlinks))
2308 return NULL;
2309#endif
2310
2311 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2312 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2313 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2314 return NULL;
2315
2316 Py_BEGIN_ALLOW_THREADS
2317 if (path->fd != -1)
2318 result = FSTAT(path->fd, &st);
2319 else
2320#ifdef MS_WINDOWS
2321 if (path->wide) {
2322 if (follow_symlinks)
2323 result = win32_stat_w(path->wide, &st);
2324 else
2325 result = win32_lstat_w(path->wide, &st);
2326 }
2327 else
2328#endif
2329#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2330 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2331 result = LSTAT(path->narrow, &st);
2332 else
2333#endif
2334#ifdef HAVE_FSTATAT
2335 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2336 result = fstatat(dir_fd, path->narrow, &st,
2337 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2338 else
2339#endif
2340 result = STAT(path->narrow, &st);
2341 Py_END_ALLOW_THREADS
2342
Victor Stinner292c8352012-10-30 02:17:38 +01002343 if (result != 0) {
2344 return path_error(path);
2345 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002346
2347 return _pystat_fromstructstat(&st);
2348}
2349
2350PyDoc_STRVAR(posix_stat__doc__,
2351"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2352Perform a stat system call on the given path.\n\
2353\n\
2354path may be specified as either a string or as an open file descriptor.\n\
2355\n\
2356If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2357 and path should be relative; path will then be relative to that directory.\n\
2358 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2359 it will raise a NotImplementedError.\n\
2360If follow_symlinks is False, and the last element of the path is a symbolic\n\
2361 link, stat will examine the symbolic link itself instead of the file the\n\
2362 link points to.\n\
2363It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2364 an open file descriptor.");
2365
2366static PyObject *
2367posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2368{
2369 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2370 path_t path;
2371 int dir_fd = DEFAULT_DIR_FD;
2372 int follow_symlinks = 1;
2373 PyObject *return_value;
2374
2375 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002376 path.function_name = "stat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002377 path.allow_fd = 1;
2378 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2379 path_converter, &path,
2380#ifdef HAVE_FSTATAT
2381 dir_fd_converter, &dir_fd,
2382#else
2383 dir_fd_unavailable, &dir_fd,
2384#endif
2385 &follow_symlinks))
2386 return NULL;
2387 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2388 path_cleanup(&path);
2389 return return_value;
2390}
2391
2392PyDoc_STRVAR(posix_lstat__doc__,
2393"lstat(path, *, dir_fd=None) -> stat result\n\n\
2394Like stat(), but do not follow symbolic links.\n\
2395Equivalent to stat(path, follow_symlinks=False).");
2396
2397static PyObject *
2398posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2399{
2400 static char *keywords[] = {"path", "dir_fd", NULL};
2401 path_t path;
2402 int dir_fd = DEFAULT_DIR_FD;
2403 int follow_symlinks = 0;
2404 PyObject *return_value;
2405
2406 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002407 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002408 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2409 path_converter, &path,
2410#ifdef HAVE_FSTATAT
2411 dir_fd_converter, &dir_fd
2412#else
2413 dir_fd_unavailable, &dir_fd
2414#endif
2415 ))
2416 return NULL;
2417 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2418 path_cleanup(&path);
2419 return return_value;
2420}
2421
2422PyDoc_STRVAR(posix_access__doc__,
2423"access(path, mode, *, dir_fd=None, effective_ids=False,\
2424 follow_symlinks=True)\n\n\
2425Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2426False otherwise.\n\
2427\n\
2428If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2429 and path should be relative; path will then be relative to that directory.\n\
2430If effective_ids is True, access will use the effective uid/gid instead of\n\
2431 the real uid/gid.\n\
2432If follow_symlinks is False, and the last element of the path is a symbolic\n\
2433 link, access will examine the symbolic link itself instead of the file the\n\
2434 link points to.\n\
2435dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2436 on your platform. If they are unavailable, using them will raise a\n\
2437 NotImplementedError.\n\
2438\n\
2439Note that most operations will use the effective uid/gid, therefore this\n\
2440 routine can be used in a suid/sgid environment to test if the invoking user\n\
2441 has the specified access to the path.\n\
2442The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2443 of R_OK, W_OK, and X_OK.");
2444
2445static PyObject *
2446posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2447{
2448 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2449 "follow_symlinks", NULL};
2450 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002451 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002452 int dir_fd = DEFAULT_DIR_FD;
2453 int effective_ids = 0;
2454 int follow_symlinks = 1;
2455 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002456
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002457#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002458 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002459#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002460 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002461#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002462
2463 memset(&path, 0, sizeof(path));
2464 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2465 path_converter, &path, &mode,
2466#ifdef HAVE_FACCESSAT
2467 dir_fd_converter, &dir_fd,
2468#else
2469 dir_fd_unavailable, &dir_fd,
2470#endif
2471 &effective_ids, &follow_symlinks))
2472 return NULL;
2473
2474#ifndef HAVE_FACCESSAT
2475 if (follow_symlinks_specified("access", follow_symlinks))
2476 goto exit;
2477
2478 if (effective_ids) {
2479 argument_unavailable_error("access", "effective_ids");
2480 goto exit;
2481 }
2482#endif
2483
2484#ifdef MS_WINDOWS
2485 Py_BEGIN_ALLOW_THREADS
2486 if (path.wide != NULL)
2487 attr = GetFileAttributesW(path.wide);
2488 else
2489 attr = GetFileAttributesA(path.narrow);
2490 Py_END_ALLOW_THREADS
2491
2492 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002493 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002494 * * we didn't get a -1, and
2495 * * write access wasn't requested,
2496 * * or the file isn't read-only,
2497 * * or it's a directory.
2498 * (Directories cannot be read-only on Windows.)
2499 */
2500 return_value = PyBool_FromLong(
2501 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002502 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002503 !(attr & FILE_ATTRIBUTE_READONLY) ||
2504 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2505#else
2506
2507 Py_BEGIN_ALLOW_THREADS
2508#ifdef HAVE_FACCESSAT
2509 if ((dir_fd != DEFAULT_DIR_FD) ||
2510 effective_ids ||
2511 !follow_symlinks) {
2512 int flags = 0;
2513 if (!follow_symlinks)
2514 flags |= AT_SYMLINK_NOFOLLOW;
2515 if (effective_ids)
2516 flags |= AT_EACCESS;
2517 result = faccessat(dir_fd, path.narrow, mode, flags);
2518 }
2519 else
2520#endif
2521 result = access(path.narrow, mode);
2522 Py_END_ALLOW_THREADS
2523 return_value = PyBool_FromLong(!result);
2524#endif
2525
2526#ifndef HAVE_FACCESSAT
2527exit:
2528#endif
2529 path_cleanup(&path);
2530 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002531}
2532
Guido van Rossumd371ff11999-01-25 16:12:23 +00002533#ifndef F_OK
2534#define F_OK 0
2535#endif
2536#ifndef R_OK
2537#define R_OK 4
2538#endif
2539#ifndef W_OK
2540#define W_OK 2
2541#endif
2542#ifndef X_OK
2543#define X_OK 1
2544#endif
2545
2546#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002547PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002548"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002549Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002550
2551static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002552posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002553{
Victor Stinner8c62be82010-05-06 00:08:46 +00002554 int id;
2555 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002556
Victor Stinner8c62be82010-05-06 00:08:46 +00002557 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2558 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002559
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002560#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002561 /* file descriptor 0 only, the default input device (stdin) */
2562 if (id == 0) {
2563 ret = ttyname();
2564 }
2565 else {
2566 ret = NULL;
2567 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002568#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002569 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002570#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002571 if (ret == NULL)
2572 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002573 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002574}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002575#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002576
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002577#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002578PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002579"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002580Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002581
2582static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002583posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002584{
Victor Stinner8c62be82010-05-06 00:08:46 +00002585 char *ret;
2586 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002587
Greg Wardb48bc172000-03-01 21:51:56 +00002588#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002589 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002590#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002591 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002592#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002593 if (ret == NULL)
2594 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002595 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002596}
2597#endif
2598
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002599PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002600"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002601Change the current working directory to the specified path.\n\
2602\n\
2603path may always be specified as a string.\n\
2604On some platforms, path may also be specified as an open file descriptor.\n\
2605 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002606
Barry Warsaw53699e91996-12-10 23:23:01 +00002607static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002608posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002609{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002610 path_t path;
2611 int result;
2612 PyObject *return_value = NULL;
2613 static char *keywords[] = {"path", NULL};
2614
2615 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002616 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002617#ifdef HAVE_FCHDIR
2618 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002619#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002620 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2621 path_converter, &path
2622 ))
2623 return NULL;
2624
2625 Py_BEGIN_ALLOW_THREADS
2626#ifdef MS_WINDOWS
2627 if (path.wide)
2628 result = win32_wchdir(path.wide);
2629 else
2630 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002631 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002632#else
2633#ifdef HAVE_FCHDIR
2634 if (path.fd != -1)
2635 result = fchdir(path.fd);
2636 else
2637#endif
2638 result = chdir(path.narrow);
2639#endif
2640 Py_END_ALLOW_THREADS
2641
2642 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002643 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002644 goto exit;
2645 }
2646
2647 return_value = Py_None;
2648 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002649
Larry Hastings9cf065c2012-06-22 16:30:09 -07002650exit:
2651 path_cleanup(&path);
2652 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002653}
2654
Fred Drake4d1e64b2002-04-15 19:40:07 +00002655#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002656PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002657"fchdir(fd)\n\n\
2658Change to the directory of the given file descriptor. fd must be\n\
2659opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002660
2661static PyObject *
2662posix_fchdir(PyObject *self, PyObject *fdobj)
2663{
Victor Stinner8c62be82010-05-06 00:08:46 +00002664 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002665}
2666#endif /* HAVE_FCHDIR */
2667
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002668
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002669PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002670"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2671Change the access permissions of a file.\n\
2672\n\
2673path may always be specified as a string.\n\
2674On some platforms, path may also be specified as an open file descriptor.\n\
2675 If this functionality is unavailable, using it raises an exception.\n\
2676If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2677 and path should be relative; path will then be relative to that directory.\n\
2678If follow_symlinks is False, and the last element of the path is a symbolic\n\
2679 link, chmod will modify the symbolic link itself instead of the file the\n\
2680 link points to.\n\
2681It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2682 an open file descriptor.\n\
2683dir_fd and follow_symlinks may not be implemented on your platform.\n\
2684 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002685
Barry Warsaw53699e91996-12-10 23:23:01 +00002686static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002687posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002688{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002689 path_t path;
2690 int mode;
2691 int dir_fd = DEFAULT_DIR_FD;
2692 int follow_symlinks = 1;
2693 int result;
2694 PyObject *return_value = NULL;
2695 static char *keywords[] = {"path", "mode", "dir_fd",
2696 "follow_symlinks", NULL};
2697
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002698#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002699 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002700#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002701
Larry Hastings9cf065c2012-06-22 16:30:09 -07002702#ifdef HAVE_FCHMODAT
2703 int fchmodat_nofollow_unsupported = 0;
2704#endif
2705
2706 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002707 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002708#ifdef HAVE_FCHMOD
2709 path.allow_fd = 1;
2710#endif
2711 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2712 path_converter, &path,
2713 &mode,
2714#ifdef HAVE_FCHMODAT
2715 dir_fd_converter, &dir_fd,
2716#else
2717 dir_fd_unavailable, &dir_fd,
2718#endif
2719 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002720 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002721
2722#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2723 if (follow_symlinks_specified("chmod", follow_symlinks))
2724 goto exit;
2725#endif
2726
2727#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002728 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002729 if (path.wide)
2730 attr = GetFileAttributesW(path.wide);
2731 else
2732 attr = GetFileAttributesA(path.narrow);
2733 if (attr == 0xFFFFFFFF)
2734 result = 0;
2735 else {
2736 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002737 attr &= ~FILE_ATTRIBUTE_READONLY;
2738 else
2739 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002740 if (path.wide)
2741 result = SetFileAttributesW(path.wide, attr);
2742 else
2743 result = SetFileAttributesA(path.narrow, attr);
2744 }
2745 Py_END_ALLOW_THREADS
2746
2747 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002748 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002749 goto exit;
2750 }
2751#else /* MS_WINDOWS */
2752 Py_BEGIN_ALLOW_THREADS
2753#ifdef HAVE_FCHMOD
2754 if (path.fd != -1)
2755 result = fchmod(path.fd, mode);
2756 else
2757#endif
2758#ifdef HAVE_LCHMOD
2759 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2760 result = lchmod(path.narrow, mode);
2761 else
2762#endif
2763#ifdef HAVE_FCHMODAT
2764 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2765 /*
2766 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2767 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002768 * and then says it isn't implemented yet.
2769 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002770 *
2771 * Once it is supported, os.chmod will automatically
2772 * support dir_fd and follow_symlinks=False. (Hopefully.)
2773 * Until then, we need to be careful what exception we raise.
2774 */
2775 result = fchmodat(dir_fd, path.narrow, mode,
2776 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2777 /*
2778 * But wait! We can't throw the exception without allowing threads,
2779 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2780 */
2781 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002782 result &&
2783 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2784 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002785 }
2786 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002787#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002788 result = chmod(path.narrow, mode);
2789 Py_END_ALLOW_THREADS
2790
2791 if (result) {
2792#ifdef HAVE_FCHMODAT
2793 if (fchmodat_nofollow_unsupported) {
2794 if (dir_fd != DEFAULT_DIR_FD)
2795 dir_fd_and_follow_symlinks_invalid("chmod",
2796 dir_fd, follow_symlinks);
2797 else
2798 follow_symlinks_specified("chmod", follow_symlinks);
2799 }
2800 else
2801#endif
Victor Stinner292c8352012-10-30 02:17:38 +01002802 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002803 goto exit;
2804 }
2805#endif
2806
2807 Py_INCREF(Py_None);
2808 return_value = Py_None;
2809exit:
2810 path_cleanup(&path);
2811 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002812}
2813
Larry Hastings9cf065c2012-06-22 16:30:09 -07002814
Christian Heimes4e30a842007-11-30 22:12:06 +00002815#ifdef HAVE_FCHMOD
2816PyDoc_STRVAR(posix_fchmod__doc__,
2817"fchmod(fd, mode)\n\n\
2818Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002819descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002820
2821static PyObject *
2822posix_fchmod(PyObject *self, PyObject *args)
2823{
Victor Stinner8c62be82010-05-06 00:08:46 +00002824 int fd, mode, res;
2825 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2826 return NULL;
2827 Py_BEGIN_ALLOW_THREADS
2828 res = fchmod(fd, mode);
2829 Py_END_ALLOW_THREADS
2830 if (res < 0)
2831 return posix_error();
2832 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002833}
2834#endif /* HAVE_FCHMOD */
2835
2836#ifdef HAVE_LCHMOD
2837PyDoc_STRVAR(posix_lchmod__doc__,
2838"lchmod(path, mode)\n\n\
2839Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002840affects the link itself rather than the target.\n\
2841Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002842
2843static PyObject *
2844posix_lchmod(PyObject *self, PyObject *args)
2845{
Victor Stinner292c8352012-10-30 02:17:38 +01002846 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002847 int i;
2848 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002849 memset(&path, 0, sizeof(path));
2850 path.function_name = "lchmod";
2851 if (!PyArg_ParseTuple(args, "O&i:lchmod",
2852 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002853 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002854 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002855 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00002856 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002857 if (res < 0) {
2858 path_error(&path);
2859 path_cleanup(&path);
2860 return NULL;
2861 }
2862 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002863 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002864}
2865#endif /* HAVE_LCHMOD */
2866
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002867
Thomas Wouterscf297e42007-02-23 15:07:44 +00002868#ifdef HAVE_CHFLAGS
2869PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002870"chflags(path, flags, *, follow_symlinks=True)\n\n\
2871Set file flags.\n\
2872\n\
2873If follow_symlinks is False, and the last element of the path is a symbolic\n\
2874 link, chflags will change flags on the symbolic link itself instead of the\n\
2875 file the link points to.\n\
2876follow_symlinks may not be implemented on your platform. If it is\n\
2877unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002878
2879static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002880posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002881{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002882 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002883 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002884 int follow_symlinks = 1;
2885 int result;
Victor Stinner45e90392013-07-18 23:57:35 +02002886 PyObject *return_value = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002887 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2888
2889 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002890 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002891 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2892 path_converter, &path,
2893 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002894 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002895
2896#ifndef HAVE_LCHFLAGS
2897 if (follow_symlinks_specified("chflags", follow_symlinks))
2898 goto exit;
2899#endif
2900
Victor Stinner8c62be82010-05-06 00:08:46 +00002901 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002902#ifdef HAVE_LCHFLAGS
2903 if (!follow_symlinks)
2904 result = lchflags(path.narrow, flags);
2905 else
2906#endif
2907 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002908 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002909
2910 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002911 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002912 goto exit;
2913 }
2914
2915 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002917
2918exit:
2919 path_cleanup(&path);
2920 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002921}
2922#endif /* HAVE_CHFLAGS */
2923
2924#ifdef HAVE_LCHFLAGS
2925PyDoc_STRVAR(posix_lchflags__doc__,
2926"lchflags(path, flags)\n\n\
2927Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002928This function will not follow symbolic links.\n\
2929Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002930
2931static PyObject *
2932posix_lchflags(PyObject *self, PyObject *args)
2933{
Victor Stinner292c8352012-10-30 02:17:38 +01002934 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002935 unsigned long flags;
2936 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002937 memset(&path, 0, sizeof(path));
2938 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00002939 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01002940 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00002941 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002942 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002943 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002944 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002945 if (res < 0) {
2946 path_error(&path);
2947 path_cleanup(&path);
2948 return NULL;
2949 }
2950 path_cleanup(&path);
2951 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002952}
2953#endif /* HAVE_LCHFLAGS */
2954
Martin v. Löwis244edc82001-10-04 22:44:26 +00002955#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002956PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002957"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002958Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002959
2960static PyObject *
2961posix_chroot(PyObject *self, PyObject *args)
2962{
Victor Stinner292c8352012-10-30 02:17:38 +01002963 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002964}
2965#endif
2966
Guido van Rossum21142a01999-01-08 21:05:37 +00002967#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002968PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002969"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002970force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002971
2972static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002973posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002974{
Stefan Krah0e803b32010-11-26 16:16:47 +00002975 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002976}
2977#endif /* HAVE_FSYNC */
2978
Ross Lagerwall7807c352011-03-17 20:20:30 +02002979#ifdef HAVE_SYNC
2980PyDoc_STRVAR(posix_sync__doc__,
2981"sync()\n\n\
2982Force write of everything to disk.");
2983
2984static PyObject *
2985posix_sync(PyObject *self, PyObject *noargs)
2986{
2987 Py_BEGIN_ALLOW_THREADS
2988 sync();
2989 Py_END_ALLOW_THREADS
2990 Py_RETURN_NONE;
2991}
2992#endif
2993
Guido van Rossum21142a01999-01-08 21:05:37 +00002994#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002995
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002996#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002997extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2998#endif
2999
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003000PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003001"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003002force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003003 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003004
3005static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003006posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003007{
Stefan Krah0e803b32010-11-26 16:16:47 +00003008 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003009}
3010#endif /* HAVE_FDATASYNC */
3011
3012
Fredrik Lundh10723342000-07-10 16:38:09 +00003013#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003014PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003015"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3016Change the owner and group id of path to the numeric uid and gid.\n\
3017\n\
3018path may always be specified as a string.\n\
3019On some platforms, path may also be specified as an open file descriptor.\n\
3020 If this functionality is unavailable, using it raises an exception.\n\
3021If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3022 and path should be relative; path will then be relative to that directory.\n\
3023If follow_symlinks is False, and the last element of the path is a symbolic\n\
3024 link, chown will modify the symbolic link itself instead of the file the\n\
3025 link points to.\n\
3026It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3027 an open file descriptor.\n\
3028dir_fd and follow_symlinks may not be implemented on your platform.\n\
3029 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003030
Barry Warsaw53699e91996-12-10 23:23:01 +00003031static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003032posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003033{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003034 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003035 uid_t uid;
3036 gid_t gid;
3037 int dir_fd = DEFAULT_DIR_FD;
3038 int follow_symlinks = 1;
3039 int result;
3040 PyObject *return_value = NULL;
3041 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3042 "follow_symlinks", NULL};
3043
3044 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003045 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003046#ifdef HAVE_FCHOWN
3047 path.allow_fd = 1;
3048#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003049 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003050 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003051 _Py_Uid_Converter, &uid,
3052 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003053#ifdef HAVE_FCHOWNAT
3054 dir_fd_converter, &dir_fd,
3055#else
3056 dir_fd_unavailable, &dir_fd,
3057#endif
3058 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003059 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003060
3061#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3062 if (follow_symlinks_specified("chown", follow_symlinks))
3063 goto exit;
3064#endif
3065 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3066 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3067 goto exit;
3068
3069#ifdef __APPLE__
3070 /*
3071 * This is for Mac OS X 10.3, which doesn't have lchown.
3072 * (But we still have an lchown symbol because of weak-linking.)
3073 * It doesn't have fchownat either. So there's no possibility
3074 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003075 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003076 if ((!follow_symlinks) && (lchown == NULL)) {
3077 follow_symlinks_specified("chown", follow_symlinks);
3078 goto exit;
3079 }
3080#endif
3081
Victor Stinner8c62be82010-05-06 00:08:46 +00003082 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003083#ifdef HAVE_FCHOWN
3084 if (path.fd != -1)
3085 result = fchown(path.fd, uid, gid);
3086 else
3087#endif
3088#ifdef HAVE_LCHOWN
3089 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3090 result = lchown(path.narrow, uid, gid);
3091 else
3092#endif
3093#ifdef HAVE_FCHOWNAT
3094 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3095 result = fchownat(dir_fd, path.narrow, uid, gid,
3096 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3097 else
3098#endif
3099 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003100 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003101
3102 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003103 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003104 goto exit;
3105 }
3106
3107 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003108 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003109
3110exit:
3111 path_cleanup(&path);
3112 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003113}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003114#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003115
Christian Heimes4e30a842007-11-30 22:12:06 +00003116#ifdef HAVE_FCHOWN
3117PyDoc_STRVAR(posix_fchown__doc__,
3118"fchown(fd, uid, gid)\n\n\
3119Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003120fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003121
3122static PyObject *
3123posix_fchown(PyObject *self, PyObject *args)
3124{
Victor Stinner8c62be82010-05-06 00:08:46 +00003125 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003126 uid_t uid;
3127 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003128 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003129 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3130 _Py_Uid_Converter, &uid,
3131 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003132 return NULL;
3133 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003134 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003135 Py_END_ALLOW_THREADS
3136 if (res < 0)
3137 return posix_error();
3138 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003139}
3140#endif /* HAVE_FCHOWN */
3141
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003142#ifdef HAVE_LCHOWN
3143PyDoc_STRVAR(posix_lchown__doc__,
3144"lchown(path, uid, gid)\n\n\
3145Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003146This function will not follow symbolic links.\n\
3147Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003148
3149static PyObject *
3150posix_lchown(PyObject *self, PyObject *args)
3151{
Victor Stinner292c8352012-10-30 02:17:38 +01003152 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003153 uid_t uid;
3154 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003155 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003156 memset(&path, 0, sizeof(path));
3157 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003158 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003159 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003160 _Py_Uid_Converter, &uid,
3161 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003162 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003163 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003164 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003165 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003166 if (res < 0) {
3167 path_error(&path);
3168 path_cleanup(&path);
3169 return NULL;
3170 }
3171 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003172 Py_INCREF(Py_None);
3173 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003174}
3175#endif /* HAVE_LCHOWN */
3176
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003177
Barry Warsaw53699e91996-12-10 23:23:01 +00003178static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003179posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003180{
Victor Stinner8c62be82010-05-06 00:08:46 +00003181 char buf[1026];
3182 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003183
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003184#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003185 if (!use_bytes) {
3186 wchar_t wbuf[1026];
3187 wchar_t *wbuf2 = wbuf;
3188 PyObject *resobj;
3189 DWORD len;
3190 Py_BEGIN_ALLOW_THREADS
3191 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3192 /* If the buffer is large enough, len does not include the
3193 terminating \0. If the buffer is too small, len includes
3194 the space needed for the terminator. */
3195 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003196 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003197 if (wbuf2)
3198 len = GetCurrentDirectoryW(len, wbuf2);
3199 }
3200 Py_END_ALLOW_THREADS
3201 if (!wbuf2) {
3202 PyErr_NoMemory();
3203 return NULL;
3204 }
3205 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003206 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003207 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003208 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003209 }
3210 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003211 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003212 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003213 return resobj;
3214 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003215
3216 if (win32_warn_bytes_api())
3217 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003218#endif
3219
Victor Stinner8c62be82010-05-06 00:08:46 +00003220 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003221 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003222 Py_END_ALLOW_THREADS
3223 if (res == NULL)
3224 return posix_error();
3225 if (use_bytes)
3226 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003227 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003228}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003229
3230PyDoc_STRVAR(posix_getcwd__doc__,
3231"getcwd() -> path\n\n\
3232Return a unicode string representing the current working directory.");
3233
3234static PyObject *
3235posix_getcwd_unicode(PyObject *self)
3236{
3237 return posix_getcwd(0);
3238}
3239
3240PyDoc_STRVAR(posix_getcwdb__doc__,
3241"getcwdb() -> path\n\n\
3242Return a bytes string representing the current working directory.");
3243
3244static PyObject *
3245posix_getcwd_bytes(PyObject *self)
3246{
3247 return posix_getcwd(1);
3248}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003249
Larry Hastings9cf065c2012-06-22 16:30:09 -07003250#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3251#define HAVE_LINK 1
3252#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003253
Guido van Rossumb6775db1994-08-01 11:34:53 +00003254#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003255PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003256"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3257Create a hard link to a file.\n\
3258\n\
3259If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3260 descriptor open to a directory, and the respective path string (src or dst)\n\
3261 should be relative; the path will then be relative to that directory.\n\
3262If follow_symlinks is False, and the last element of src is a symbolic\n\
3263 link, link will create a link to the symbolic link itself instead of the\n\
3264 file the link points to.\n\
3265src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3266 platform. If they are unavailable, using them will raise a\n\
3267 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003268
Barry Warsaw53699e91996-12-10 23:23:01 +00003269static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003270posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003271{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003272 path_t src, dst;
3273 int src_dir_fd = DEFAULT_DIR_FD;
3274 int dst_dir_fd = DEFAULT_DIR_FD;
3275 int follow_symlinks = 1;
3276 PyObject *return_value = NULL;
3277 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3278 "follow_symlinks", NULL};
3279#ifdef MS_WINDOWS
3280 BOOL result;
3281#else
3282 int result;
3283#endif
3284
3285 memset(&src, 0, sizeof(src));
3286 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003287 src.function_name = "link";
3288 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003289 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3290 path_converter, &src,
3291 path_converter, &dst,
3292 dir_fd_converter, &src_dir_fd,
3293 dir_fd_converter, &dst_dir_fd,
3294 &follow_symlinks))
3295 return NULL;
3296
3297#ifndef HAVE_LINKAT
3298 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3299 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3300 goto exit;
3301 }
3302#endif
3303
3304 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3305 PyErr_SetString(PyExc_NotImplementedError,
3306 "link: src and dst must be the same type");
3307 goto exit;
3308 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003309
Brian Curtin1b9df392010-11-24 20:24:31 +00003310#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003311 Py_BEGIN_ALLOW_THREADS
3312 if (src.wide)
3313 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3314 else
3315 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3316 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003317
Larry Hastings9cf065c2012-06-22 16:30:09 -07003318 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003319 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003320 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003321 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003322#else
3323 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003324#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003325 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3326 (dst_dir_fd != DEFAULT_DIR_FD) ||
3327 (!follow_symlinks))
3328 result = linkat(src_dir_fd, src.narrow,
3329 dst_dir_fd, dst.narrow,
3330 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3331 else
3332#endif
3333 result = link(src.narrow, dst.narrow);
3334 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003335
Larry Hastings9cf065c2012-06-22 16:30:09 -07003336 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003337 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003338 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003339 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003340#endif
3341
3342 return_value = Py_None;
3343 Py_INCREF(Py_None);
3344
3345exit:
3346 path_cleanup(&src);
3347 path_cleanup(&dst);
3348 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003349}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003350#endif
3351
Brian Curtin1b9df392010-11-24 20:24:31 +00003352
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003353
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003354PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003355"listdir(path='.') -> list_of_filenames\n\n\
3356Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003357The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003358entries '.' and '..' even if they are present in the directory.\n\
3359\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003360path can be specified as either str or bytes. If path is bytes,\n\
3361 the filenames returned will also be bytes; in all other circumstances\n\
3362 the filenames returned will be str.\n\
3363On some platforms, path may also be specified as an open file descriptor;\n\
3364 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003365 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003366
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003367#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003368static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003369_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003370{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003371 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003372 PyObject *v;
3373 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3374 BOOL result;
3375 WIN32_FIND_DATA FileData;
3376 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3377 char *bufptr = namebuf;
3378 /* only claim to have space for MAX_PATH */
3379 Py_ssize_t len = sizeof(namebuf)-5;
3380 PyObject *po = NULL;
3381 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003382
Gregory P. Smith40a21602013-03-20 20:52:50 -07003383 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003384 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003385 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003386
Gregory P. Smith40a21602013-03-20 20:52:50 -07003387 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003388 po_wchars = L".";
3389 len = 1;
3390 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003391 po_wchars = path->wide;
3392 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003393 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003394 /* The +5 is so we can append "\\*.*\0" */
Victor Stinnerb6404912013-07-07 16:21:41 +02003395 wnamebuf = PyMem_Malloc((len + 5) * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003396 if (!wnamebuf) {
3397 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003399 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003400 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003401 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003402 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003403 if (wch != L'/' && wch != L'\\' && wch != L':')
3404 wnamebuf[len++] = L'\\';
3405 wcscpy(wnamebuf + len, L"*.*");
3406 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003407 if ((list = PyList_New(0)) == NULL) {
3408 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003409 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003410 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003411 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003412 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003413 if (hFindFile == INVALID_HANDLE_VALUE) {
3414 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003415 if (error == ERROR_FILE_NOT_FOUND)
3416 goto exit;
3417 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003418 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003419 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003420 }
3421 do {
3422 /* Skip over . and .. */
3423 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3424 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425 v = PyUnicode_FromWideChar(wFileData.cFileName,
3426 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003427 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428 Py_DECREF(list);
3429 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 break;
3431 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003433 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 Py_DECREF(list);
3435 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003436 break;
3437 }
3438 Py_DECREF(v);
3439 }
3440 Py_BEGIN_ALLOW_THREADS
3441 result = FindNextFileW(hFindFile, &wFileData);
3442 Py_END_ALLOW_THREADS
3443 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3444 it got to the end of the directory. */
3445 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003447 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003448 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003449 }
3450 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003451
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003453 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003454 strcpy(namebuf, path->narrow);
3455 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 if (len > 0) {
3457 char ch = namebuf[len-1];
3458 if (ch != SEP && ch != ALTSEP && ch != ':')
3459 namebuf[len++] = '/';
3460 strcpy(namebuf + len, "*.*");
3461 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003462
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003464 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003465
Antoine Pitroub73caab2010-08-09 23:39:31 +00003466 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003467 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003468 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003469 if (hFindFile == INVALID_HANDLE_VALUE) {
3470 int error = GetLastError();
3471 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003472 goto exit;
3473 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003474 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003476 }
3477 do {
3478 /* Skip over . and .. */
3479 if (strcmp(FileData.cFileName, ".") != 0 &&
3480 strcmp(FileData.cFileName, "..") != 0) {
3481 v = PyBytes_FromString(FileData.cFileName);
3482 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003483 Py_DECREF(list);
3484 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003485 break;
3486 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489 Py_DECREF(list);
3490 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 break;
3492 }
3493 Py_DECREF(v);
3494 }
3495 Py_BEGIN_ALLOW_THREADS
3496 result = FindNextFile(hFindFile, &FileData);
3497 Py_END_ALLOW_THREADS
3498 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3499 it got to the end of the directory. */
3500 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003501 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003502 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003503 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 }
3505 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003506
Larry Hastings9cf065c2012-06-22 16:30:09 -07003507exit:
3508 if (hFindFile != INVALID_HANDLE_VALUE) {
3509 if (FindClose(hFindFile) == FALSE) {
3510 if (list != NULL) {
3511 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003512 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003513 }
3514 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003515 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003516 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003517
Larry Hastings9cf065c2012-06-22 16:30:09 -07003518 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003519} /* end of _listdir_windows_no_opendir */
3520
3521#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3522
3523static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003524_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003525{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003526 PyObject *v;
3527 DIR *dirp = NULL;
3528 struct dirent *ep;
3529 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003530#ifdef HAVE_FDOPENDIR
3531 int fd = -1;
3532#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003533
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003535#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003536 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003538 fd = _Py_dup(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003539 if (fd == -1) {
3540 list = posix_error();
3541 goto exit;
3542 }
3543
Larry Hastingsfdaea062012-06-25 04:42:23 -07003544 return_str = 1;
3545
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546 Py_BEGIN_ALLOW_THREADS
3547 dirp = fdopendir(fd);
3548 Py_END_ALLOW_THREADS
3549 }
3550 else
3551#endif
3552 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003553 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003554 if (path->narrow) {
3555 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003556 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003557 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003558 }
3559 else {
3560 name = ".";
3561 return_str = 1;
3562 }
3563
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564 Py_BEGIN_ALLOW_THREADS
3565 dirp = opendir(name);
3566 Py_END_ALLOW_THREADS
3567 }
3568
3569 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003570 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003571#ifdef HAVE_FDOPENDIR
3572 if (fd != -1) {
3573 Py_BEGIN_ALLOW_THREADS
3574 close(fd);
3575 Py_END_ALLOW_THREADS
3576 }
3577#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578 goto exit;
3579 }
3580 if ((list = PyList_New(0)) == NULL) {
3581 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003582 }
3583 for (;;) {
3584 errno = 0;
3585 Py_BEGIN_ALLOW_THREADS
3586 ep = readdir(dirp);
3587 Py_END_ALLOW_THREADS
3588 if (ep == NULL) {
3589 if (errno == 0) {
3590 break;
3591 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003593 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003594 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003595 }
3596 }
3597 if (ep->d_name[0] == '.' &&
3598 (NAMLEN(ep) == 1 ||
3599 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3600 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003601 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003602 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3603 else
3604 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003607 break;
3608 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003610 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003611 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 break;
3613 }
3614 Py_DECREF(v);
3615 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003616
Larry Hastings9cf065c2012-06-22 16:30:09 -07003617exit:
3618 if (dirp != NULL) {
3619 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003620#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003621 if (fd > -1)
3622 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003623#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003624 closedir(dirp);
3625 Py_END_ALLOW_THREADS
3626 }
3627
Larry Hastings9cf065c2012-06-22 16:30:09 -07003628 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003629} /* end of _posix_listdir */
3630#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003631
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003632static PyObject *
3633posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3634{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003635 path_t path;
3636 PyObject *list = NULL;
3637 static char *keywords[] = {"path", NULL};
3638 PyObject *return_value;
3639
3640 memset(&path, 0, sizeof(path));
3641 path.function_name = "listdir";
3642 path.nullable = 1;
3643#ifdef HAVE_FDOPENDIR
3644 path.allow_fd = 1;
3645 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003646#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003647
3648 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3649 path_converter, &path)) {
3650 return NULL;
3651 }
3652
3653#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3654 return_value = _listdir_windows_no_opendir(&path, list);
3655#else
3656 return_value = _posix_listdir(&path, list);
3657#endif
3658 path_cleanup(&path);
3659 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003660}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003661
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003662#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003663/* A helper function for abspath on win32 */
3664static PyObject *
3665posix__getfullpathname(PyObject *self, PyObject *args)
3666{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003667 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003668 char outbuf[MAX_PATH*2];
3669 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003670 PyObject *po;
3671
3672 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3673 {
3674 wchar_t *wpath;
3675 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3676 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 DWORD result;
3678 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003679
3680 wpath = PyUnicode_AsUnicode(po);
3681 if (wpath == NULL)
3682 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003683 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003684 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003685 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003686 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003687 woutbufp = PyMem_Malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003688 if (!woutbufp)
3689 return PyErr_NoMemory();
3690 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3691 }
3692 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003693 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003695 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003697 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003698 return v;
3699 }
3700 /* Drop the argument parsing error as narrow strings
3701 are also valid. */
3702 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003703
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003704 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3705 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003706 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003707 if (win32_warn_bytes_api())
3708 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003709 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003710 outbuf, &temp)) {
3711 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003712 return NULL;
3713 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003714 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3715 return PyUnicode_Decode(outbuf, strlen(outbuf),
3716 Py_FileSystemDefaultEncoding, NULL);
3717 }
3718 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003719} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003720
Brian Curtind25aef52011-06-13 15:16:04 -05003721
Brian Curtinf5e76d02010-11-24 13:14:05 +00003722
Brian Curtind40e6f72010-07-08 21:39:08 +00003723/* A helper function for samepath on windows */
3724static PyObject *
3725posix__getfinalpathname(PyObject *self, PyObject *args)
3726{
3727 HANDLE hFile;
3728 int buf_size;
3729 wchar_t *target_path;
3730 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003731 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003732 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003733
Victor Stinnereb5657a2011-09-30 01:44:27 +02003734 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003735 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003736 path = PyUnicode_AsUnicode(po);
3737 if (path == NULL)
3738 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003739
3740 if(!check_GetFinalPathNameByHandle()) {
3741 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3742 NotImplementedError. */
3743 return PyErr_Format(PyExc_NotImplementedError,
3744 "GetFinalPathNameByHandle not available on this platform");
3745 }
3746
3747 hFile = CreateFileW(
3748 path,
3749 0, /* desired access */
3750 0, /* share mode */
3751 NULL, /* security attributes */
3752 OPEN_EXISTING,
3753 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3754 FILE_FLAG_BACKUP_SEMANTICS,
3755 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003756
Victor Stinnereb5657a2011-09-30 01:44:27 +02003757 if(hFile == INVALID_HANDLE_VALUE)
3758 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003759
3760 /* We have a good handle to the target, use it to determine the
3761 target path name. */
3762 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3763
3764 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003765 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003766
Victor Stinnerb6404912013-07-07 16:21:41 +02003767 target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtind40e6f72010-07-08 21:39:08 +00003768 if(!target_path)
3769 return PyErr_NoMemory();
3770
3771 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3772 buf_size, VOLUME_NAME_DOS);
3773 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003774 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003775
3776 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003777 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003778
3779 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003780 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003781 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003782 return result;
3783
3784} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003785
Brian Curtin95d028f2011-06-09 09:10:38 -05003786PyDoc_STRVAR(posix__isdir__doc__,
3787"Return true if the pathname refers to an existing directory.");
3788
Brian Curtin9c669cc2011-06-08 18:17:18 -05003789static PyObject *
3790posix__isdir(PyObject *self, PyObject *args)
3791{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003792 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003793 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003794 DWORD attributes;
3795
3796 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003797 wchar_t *wpath = PyUnicode_AsUnicode(po);
3798 if (wpath == NULL)
3799 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003800
3801 attributes = GetFileAttributesW(wpath);
3802 if (attributes == INVALID_FILE_ATTRIBUTES)
3803 Py_RETURN_FALSE;
3804 goto check;
3805 }
3806 /* Drop the argument parsing error as narrow strings
3807 are also valid. */
3808 PyErr_Clear();
3809
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003810 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003811 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003812 if (win32_warn_bytes_api())
3813 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003814 attributes = GetFileAttributesA(path);
3815 if (attributes == INVALID_FILE_ATTRIBUTES)
3816 Py_RETURN_FALSE;
3817
3818check:
3819 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3820 Py_RETURN_TRUE;
3821 else
3822 Py_RETURN_FALSE;
3823}
Tim Golden6b528062013-08-01 12:44:00 +01003824
3825PyDoc_STRVAR(posix__getvolumepathname__doc__,
3826"Return volume mount point of the specified path.");
3827
3828/* A helper function for ismount on windows */
3829static PyObject *
3830posix__getvolumepathname(PyObject *self, PyObject *args)
3831{
3832 PyObject *po, *result;
3833 wchar_t *path, *mountpath=NULL;
3834 size_t bufsize;
3835 BOOL ret;
3836
3837 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
3838 return NULL;
3839 path = PyUnicode_AsUnicode(po);
3840 if (path == NULL)
3841 return NULL;
3842
3843 /* Volume path should be shorter than entire path */
3844 bufsize = max(MAX_PATH, wcslen(path) * 2 * sizeof(wchar_t)+1);
3845 mountpath = (wchar_t *)PyMem_Malloc(bufsize);
3846 if (mountpath == NULL)
3847 return PyErr_NoMemory();
3848
3849 Py_BEGIN_ALLOW_THREADS
3850 ret = GetVolumePathNameW(path, mountpath, bufsize);
3851 Py_END_ALLOW_THREADS
3852
3853 if (!ret) {
3854 result = win32_error_object("_getvolumepathname", po);
3855 goto exit;
3856 }
3857 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3858
3859exit:
3860 PyMem_Free(mountpath);
3861 return result;
3862}
3863/* end of posix__getvolumepathname */
3864
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003865#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003866
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003867PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003868"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3869Create a directory.\n\
3870\n\
3871If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3872 and path should be relative; path will then be relative to that directory.\n\
3873dir_fd may not be implemented on your platform.\n\
3874 If it is unavailable, using it will raise a NotImplementedError.\n\
3875\n\
3876The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003877
Barry Warsaw53699e91996-12-10 23:23:01 +00003878static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003879posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003880{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003881 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003882 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003883 int dir_fd = DEFAULT_DIR_FD;
3884 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3885 PyObject *return_value = NULL;
3886 int result;
3887
3888 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003889 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003890 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3891 path_converter, &path, &mode,
3892#ifdef HAVE_MKDIRAT
3893 dir_fd_converter, &dir_fd
3894#else
3895 dir_fd_unavailable, &dir_fd
3896#endif
3897 ))
3898 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003899
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003900#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003901 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003902 if (path.wide)
3903 result = CreateDirectoryW(path.wide, NULL);
3904 else
3905 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003906 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003907
Larry Hastings9cf065c2012-06-22 16:30:09 -07003908 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003909 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003910 goto exit;
3911 }
3912#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003913 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003914#if HAVE_MKDIRAT
3915 if (dir_fd != DEFAULT_DIR_FD)
3916 result = mkdirat(dir_fd, path.narrow, mode);
3917 else
3918#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003919#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003920 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003921#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003922 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003923#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003924 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003925 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01003926 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003927 goto exit;
3928 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003929#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003930 return_value = Py_None;
3931 Py_INCREF(Py_None);
3932exit:
3933 path_cleanup(&path);
3934 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003935}
3936
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003937
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003938/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3939#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003940#include <sys/resource.h>
3941#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003942
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003943
3944#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003945PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003946"nice(inc) -> new_priority\n\n\
3947Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003948
Barry Warsaw53699e91996-12-10 23:23:01 +00003949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003950posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003951{
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003953
Victor Stinner8c62be82010-05-06 00:08:46 +00003954 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3955 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003956
Victor Stinner8c62be82010-05-06 00:08:46 +00003957 /* There are two flavours of 'nice': one that returns the new
3958 priority (as required by almost all standards out there) and the
3959 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3960 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003961
Victor Stinner8c62be82010-05-06 00:08:46 +00003962 If we are of the nice family that returns the new priority, we
3963 need to clear errno before the call, and check if errno is filled
3964 before calling posix_error() on a returnvalue of -1, because the
3965 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003966
Victor Stinner8c62be82010-05-06 00:08:46 +00003967 errno = 0;
3968 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003969#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003970 if (value == 0)
3971 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003972#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003973 if (value == -1 && errno != 0)
3974 /* either nice() or getpriority() returned an error */
3975 return posix_error();
3976 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003977}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003978#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003979
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003980
3981#ifdef HAVE_GETPRIORITY
3982PyDoc_STRVAR(posix_getpriority__doc__,
3983"getpriority(which, who) -> current_priority\n\n\
3984Get program scheduling priority.");
3985
3986static PyObject *
3987posix_getpriority(PyObject *self, PyObject *args)
3988{
3989 int which, who, retval;
3990
3991 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3992 return NULL;
3993 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003994 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003995 if (errno != 0)
3996 return posix_error();
3997 return PyLong_FromLong((long)retval);
3998}
3999#endif /* HAVE_GETPRIORITY */
4000
4001
4002#ifdef HAVE_SETPRIORITY
4003PyDoc_STRVAR(posix_setpriority__doc__,
4004"setpriority(which, who, prio) -> None\n\n\
4005Set program scheduling priority.");
4006
4007static PyObject *
4008posix_setpriority(PyObject *self, PyObject *args)
4009{
4010 int which, who, prio, retval;
4011
4012 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4013 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004014 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004015 if (retval == -1)
4016 return posix_error();
4017 Py_RETURN_NONE;
4018}
4019#endif /* HAVE_SETPRIORITY */
4020
4021
Barry Warsaw53699e91996-12-10 23:23:01 +00004022static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004023internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004024{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004025 char *function_name = is_replace ? "replace" : "rename";
4026 path_t src;
4027 path_t dst;
4028 int src_dir_fd = DEFAULT_DIR_FD;
4029 int dst_dir_fd = DEFAULT_DIR_FD;
4030 int dir_fd_specified;
4031 PyObject *return_value = NULL;
4032 char format[24];
4033 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4034
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004035#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004036 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004037 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004038#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004039 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004040#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004041
4042 memset(&src, 0, sizeof(src));
4043 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01004044 src.function_name = function_name;
4045 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004046 strcpy(format, "O&O&|$O&O&:");
4047 strcat(format, function_name);
4048 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4049 path_converter, &src,
4050 path_converter, &dst,
4051 dir_fd_converter, &src_dir_fd,
4052 dir_fd_converter, &dst_dir_fd))
4053 return NULL;
4054
4055 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4056 (dst_dir_fd != DEFAULT_DIR_FD);
4057#ifndef HAVE_RENAMEAT
4058 if (dir_fd_specified) {
4059 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4060 goto exit;
4061 }
4062#endif
4063
4064 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4065 PyErr_Format(PyExc_ValueError,
4066 "%s: src and dst must be the same type", function_name);
4067 goto exit;
4068 }
4069
4070#ifdef MS_WINDOWS
4071 Py_BEGIN_ALLOW_THREADS
4072 if (src.wide)
4073 result = MoveFileExW(src.wide, dst.wide, flags);
4074 else
4075 result = MoveFileExA(src.narrow, dst.narrow, flags);
4076 Py_END_ALLOW_THREADS
4077
4078 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01004079 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004080 goto exit;
4081 }
4082
4083#else
4084 Py_BEGIN_ALLOW_THREADS
4085#ifdef HAVE_RENAMEAT
4086 if (dir_fd_specified)
4087 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4088 else
4089#endif
4090 result = rename(src.narrow, dst.narrow);
4091 Py_END_ALLOW_THREADS
4092
4093 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004094 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004095 goto exit;
4096 }
4097#endif
4098
4099 Py_INCREF(Py_None);
4100 return_value = Py_None;
4101exit:
4102 path_cleanup(&src);
4103 path_cleanup(&dst);
4104 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004105}
4106
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004107PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004108"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4109Rename a file or directory.\n\
4110\n\
4111If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4112 descriptor open to a directory, and the respective path string (src or dst)\n\
4113 should be relative; the path will then be relative to that directory.\n\
4114src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4115 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004116
4117static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004118posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004119{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004120 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004121}
4122
4123PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004124"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4125Rename a file or directory, overwriting the destination.\n\
4126\n\
4127If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4128 descriptor open to a directory, and the respective path string (src or dst)\n\
4129 should be relative; the path will then be relative to that directory.\n\
4130src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4131 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004132
4133static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004135{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004136 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004137}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004138
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004139PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004140"rmdir(path, *, dir_fd=None)\n\n\
4141Remove a directory.\n\
4142\n\
4143If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4144 and path should be relative; path will then be relative to that directory.\n\
4145dir_fd may not be implemented on your platform.\n\
4146 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004147
Barry Warsaw53699e91996-12-10 23:23:01 +00004148static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004149posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004150{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004151 path_t path;
4152 int dir_fd = DEFAULT_DIR_FD;
4153 static char *keywords[] = {"path", "dir_fd", NULL};
4154 int result;
4155 PyObject *return_value = NULL;
4156
4157 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004158 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004159 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4160 path_converter, &path,
4161#ifdef HAVE_UNLINKAT
4162 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004163#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004164 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004165#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004166 ))
4167 return NULL;
4168
4169 Py_BEGIN_ALLOW_THREADS
4170#ifdef MS_WINDOWS
4171 if (path.wide)
4172 result = RemoveDirectoryW(path.wide);
4173 else
4174 result = RemoveDirectoryA(path.narrow);
4175 result = !result; /* Windows, success=1, UNIX, success=0 */
4176#else
4177#ifdef HAVE_UNLINKAT
4178 if (dir_fd != DEFAULT_DIR_FD)
4179 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4180 else
4181#endif
4182 result = rmdir(path.narrow);
4183#endif
4184 Py_END_ALLOW_THREADS
4185
4186 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004187 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004188 goto exit;
4189 }
4190
4191 return_value = Py_None;
4192 Py_INCREF(Py_None);
4193
4194exit:
4195 path_cleanup(&path);
4196 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004197}
4198
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004199
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004200#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004201PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004202"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004203Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004204
Barry Warsaw53699e91996-12-10 23:23:01 +00004205static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004206posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004207{
Victor Stinner8c62be82010-05-06 00:08:46 +00004208 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004209#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004210 wchar_t *command;
4211 if (!PyArg_ParseTuple(args, "u:system", &command))
4212 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004213
Victor Stinner8c62be82010-05-06 00:08:46 +00004214 Py_BEGIN_ALLOW_THREADS
4215 sts = _wsystem(command);
4216 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004217#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004218 PyObject *command_obj;
4219 char *command;
4220 if (!PyArg_ParseTuple(args, "O&:system",
4221 PyUnicode_FSConverter, &command_obj))
4222 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004223
Victor Stinner8c62be82010-05-06 00:08:46 +00004224 command = PyBytes_AsString(command_obj);
4225 Py_BEGIN_ALLOW_THREADS
4226 sts = system(command);
4227 Py_END_ALLOW_THREADS
4228 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004229#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004230 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004231}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004232#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004233
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004234
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004235PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004236"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004237Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004238
Barry Warsaw53699e91996-12-10 23:23:01 +00004239static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004240posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004241{
Victor Stinner8c62be82010-05-06 00:08:46 +00004242 int i;
4243 if (!PyArg_ParseTuple(args, "i:umask", &i))
4244 return NULL;
4245 i = (int)umask(i);
4246 if (i < 0)
4247 return posix_error();
4248 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004249}
4250
Brian Curtind40e6f72010-07-08 21:39:08 +00004251#ifdef MS_WINDOWS
4252
4253/* override the default DeleteFileW behavior so that directory
4254symlinks can be removed with this function, the same as with
4255Unix symlinks */
4256BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4257{
4258 WIN32_FILE_ATTRIBUTE_DATA info;
4259 WIN32_FIND_DATAW find_data;
4260 HANDLE find_data_handle;
4261 int is_directory = 0;
4262 int is_link = 0;
4263
4264 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4265 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004266
Brian Curtind40e6f72010-07-08 21:39:08 +00004267 /* Get WIN32_FIND_DATA structure for the path to determine if
4268 it is a symlink */
4269 if(is_directory &&
4270 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4271 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4272
4273 if(find_data_handle != INVALID_HANDLE_VALUE) {
4274 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4275 FindClose(find_data_handle);
4276 }
4277 }
4278 }
4279
4280 if (is_directory && is_link)
4281 return RemoveDirectoryW(lpFileName);
4282
4283 return DeleteFileW(lpFileName);
4284}
4285#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004286
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004287PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004288"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004289Remove a file (same as remove()).\n\
4290\n\
4291If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4292 and path should be relative; path will then be relative to that directory.\n\
4293dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004294 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004295
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004296PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004297"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004298Remove a file (same as unlink()).\n\
4299\n\
4300If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4301 and path should be relative; path will then be relative to that directory.\n\
4302dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004303 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004304
Barry Warsaw53699e91996-12-10 23:23:01 +00004305static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004306posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004307{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004308 path_t path;
4309 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004310 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004311 int result;
4312 PyObject *return_value = NULL;
4313
4314 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004315 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004316 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004317 path_converter, &path,
4318#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004319 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004320#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004321 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004322#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004323 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004324 return NULL;
4325
4326 Py_BEGIN_ALLOW_THREADS
4327#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004328 if (path.wide)
4329 result = Py_DeleteFileW(path.wide);
4330 else
4331 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004332 result = !result; /* Windows, success=1, UNIX, success=0 */
4333#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004334#ifdef HAVE_UNLINKAT
4335 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004336 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004337 else
4338#endif /* HAVE_UNLINKAT */
4339 result = unlink(path.narrow);
4340#endif
4341 Py_END_ALLOW_THREADS
4342
4343 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004344 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004345 goto exit;
4346 }
4347
4348 return_value = Py_None;
4349 Py_INCREF(Py_None);
4350
4351exit:
4352 path_cleanup(&path);
4353 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004354}
4355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004356
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004357PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004358"uname() -> uname_result\n\n\
4359Return an object identifying the current operating system.\n\
4360The object behaves like a named tuple with the following fields:\n\
4361 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004362
Larry Hastings605a62d2012-06-24 04:33:36 -07004363static PyStructSequence_Field uname_result_fields[] = {
4364 {"sysname", "operating system name"},
4365 {"nodename", "name of machine on network (implementation-defined)"},
4366 {"release", "operating system release"},
4367 {"version", "operating system version"},
4368 {"machine", "hardware identifier"},
4369 {NULL}
4370};
4371
4372PyDoc_STRVAR(uname_result__doc__,
4373"uname_result: Result from os.uname().\n\n\
4374This object may be accessed either as a tuple of\n\
4375 (sysname, nodename, release, version, machine),\n\
4376or via the attributes sysname, nodename, release, version, and machine.\n\
4377\n\
4378See os.uname for more information.");
4379
4380static PyStructSequence_Desc uname_result_desc = {
4381 "uname_result", /* name */
4382 uname_result__doc__, /* doc */
4383 uname_result_fields,
4384 5
4385};
4386
4387static PyTypeObject UnameResultType;
4388
4389
4390#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004391static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004392posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004393{
Victor Stinner8c62be82010-05-06 00:08:46 +00004394 struct utsname u;
4395 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004396 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004397
Victor Stinner8c62be82010-05-06 00:08:46 +00004398 Py_BEGIN_ALLOW_THREADS
4399 res = uname(&u);
4400 Py_END_ALLOW_THREADS
4401 if (res < 0)
4402 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004403
4404 value = PyStructSequence_New(&UnameResultType);
4405 if (value == NULL)
4406 return NULL;
4407
4408#define SET(i, field) \
4409 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004410 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004411 if (!o) { \
4412 Py_DECREF(value); \
4413 return NULL; \
4414 } \
4415 PyStructSequence_SET_ITEM(value, i, o); \
4416 } \
4417
4418 SET(0, u.sysname);
4419 SET(1, u.nodename);
4420 SET(2, u.release);
4421 SET(3, u.version);
4422 SET(4, u.machine);
4423
4424#undef SET
4425
4426 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004427}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004428#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004429
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004430
Larry Hastings9cf065c2012-06-22 16:30:09 -07004431PyDoc_STRVAR(posix_utime__doc__,
4432"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4433Set the access and modified time of path.\n\
4434\n\
4435path may always be specified as a string.\n\
4436On some platforms, path may also be specified as an open file descriptor.\n\
4437 If this functionality is unavailable, using it raises an exception.\n\
4438\n\
4439If times is not None, it must be a tuple (atime, mtime);\n\
4440 atime and mtime should be expressed as float seconds since the epoch.\n\
4441If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4442 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4443 since the epoch.\n\
4444If both times and ns are None, utime uses the current time.\n\
4445Specifying tuples for both times and ns is an error.\n\
4446\n\
4447If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4448 and path should be relative; path will then be relative to that directory.\n\
4449If follow_symlinks is False, and the last element of the path is a symbolic\n\
4450 link, utime will modify the symbolic link itself instead of the file the\n\
4451 link points to.\n\
4452It is an error to use dir_fd or follow_symlinks when specifying path\n\
4453 as an open file descriptor.\n\
4454dir_fd and follow_symlinks may not be available on your platform.\n\
4455 If they are unavailable, using them will raise a NotImplementedError.");
4456
4457typedef struct {
4458 int now;
4459 time_t atime_s;
4460 long atime_ns;
4461 time_t mtime_s;
4462 long mtime_ns;
4463} utime_t;
4464
4465/*
4466 * these macros assume that "utime" is a pointer to a utime_t
4467 * they also intentionally leak the declaration of a pointer named "time"
4468 */
4469#define UTIME_TO_TIMESPEC \
4470 struct timespec ts[2]; \
4471 struct timespec *time; \
4472 if (utime->now) \
4473 time = NULL; \
4474 else { \
4475 ts[0].tv_sec = utime->atime_s; \
4476 ts[0].tv_nsec = utime->atime_ns; \
4477 ts[1].tv_sec = utime->mtime_s; \
4478 ts[1].tv_nsec = utime->mtime_ns; \
4479 time = ts; \
4480 } \
4481
4482#define UTIME_TO_TIMEVAL \
4483 struct timeval tv[2]; \
4484 struct timeval *time; \
4485 if (utime->now) \
4486 time = NULL; \
4487 else { \
4488 tv[0].tv_sec = utime->atime_s; \
4489 tv[0].tv_usec = utime->atime_ns / 1000; \
4490 tv[1].tv_sec = utime->mtime_s; \
4491 tv[1].tv_usec = utime->mtime_ns / 1000; \
4492 time = tv; \
4493 } \
4494
4495#define UTIME_TO_UTIMBUF \
4496 struct utimbuf u[2]; \
4497 struct utimbuf *time; \
4498 if (utime->now) \
4499 time = NULL; \
4500 else { \
4501 u.actime = utime->atime_s; \
4502 u.modtime = utime->mtime_s; \
4503 time = u; \
4504 }
4505
4506#define UTIME_TO_TIME_T \
4507 time_t timet[2]; \
4508 struct timet time; \
4509 if (utime->now) \
4510 time = NULL; \
4511 else { \
4512 timet[0] = utime->atime_s; \
4513 timet[1] = utime->mtime_s; \
4514 time = &timet; \
4515 } \
4516
4517
4518#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4519
4520#if UTIME_HAVE_DIR_FD
4521
4522static int
4523utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4524{
4525#ifdef HAVE_UTIMENSAT
4526 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4527 UTIME_TO_TIMESPEC;
4528 return utimensat(dir_fd, path, time, flags);
4529#elif defined(HAVE_FUTIMESAT)
4530 UTIME_TO_TIMEVAL;
4531 /*
4532 * follow_symlinks will never be false here;
4533 * we only allow !follow_symlinks and dir_fd together
4534 * if we have utimensat()
4535 */
4536 assert(follow_symlinks);
4537 return futimesat(dir_fd, path, time);
4538#endif
4539}
4540
4541#endif
4542
4543#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4544
4545#if UTIME_HAVE_FD
4546
4547static int
4548utime_fd(utime_t *utime, int fd)
4549{
4550#ifdef HAVE_FUTIMENS
4551 UTIME_TO_TIMESPEC;
4552 return futimens(fd, time);
4553#else
4554 UTIME_TO_TIMEVAL;
4555 return futimes(fd, time);
4556#endif
4557}
4558
4559#endif
4560
4561
4562#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4563 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4564
4565#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4566
4567static int
4568utime_nofollow_symlinks(utime_t *utime, char *path)
4569{
4570#ifdef HAVE_UTIMENSAT
4571 UTIME_TO_TIMESPEC;
4572 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4573#else
4574 UTIME_TO_TIMEVAL;
4575 return lutimes(path, time);
4576#endif
4577}
4578
4579#endif
4580
4581#ifndef MS_WINDOWS
4582
4583static int
4584utime_default(utime_t *utime, char *path)
4585{
4586#ifdef HAVE_UTIMENSAT
4587 UTIME_TO_TIMESPEC;
4588 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4589#elif defined(HAVE_UTIMES)
4590 UTIME_TO_TIMEVAL;
4591 return utimes(path, time);
4592#elif defined(HAVE_UTIME_H)
4593 UTIME_TO_UTIMBUF;
4594 return utime(path, time);
4595#else
4596 UTIME_TO_TIME_T;
4597 return utime(path, time);
4598#endif
4599}
4600
4601#endif
4602
Larry Hastings76ad59b2012-05-03 00:30:07 -07004603static int
4604split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4605{
4606 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004607 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004608 divmod = PyNumber_Divmod(py_long, billion);
4609 if (!divmod)
4610 goto exit;
4611 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4612 if ((*s == -1) && PyErr_Occurred())
4613 goto exit;
4614 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004615 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004616 goto exit;
4617
4618 result = 1;
4619exit:
4620 Py_XDECREF(divmod);
4621 return result;
4622}
4623
Larry Hastings9cf065c2012-06-22 16:30:09 -07004624static PyObject *
4625posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004626{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004627 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004628 PyObject *times = NULL;
4629 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004630 int dir_fd = DEFAULT_DIR_FD;
4631 int follow_symlinks = 1;
4632 char *keywords[] = {"path", "times", "ns", "dir_fd",
4633 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004634
Larry Hastings9cf065c2012-06-22 16:30:09 -07004635 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004636
Larry Hastings9cf065c2012-06-22 16:30:09 -07004637#ifdef MS_WINDOWS
4638 HANDLE hFile;
4639 FILETIME atime, mtime;
4640#else
4641 int result;
4642#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004643
Larry Hastings9cf065c2012-06-22 16:30:09 -07004644 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004645
Larry Hastings9cf065c2012-06-22 16:30:09 -07004646 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004647 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004648 memset(&utime, 0, sizeof(utime_t));
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649#if UTIME_HAVE_FD
4650 path.allow_fd = 1;
4651#endif
4652 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4653 "O&|O$OO&p:utime", keywords,
4654 path_converter, &path,
4655 &times, &ns,
4656#if UTIME_HAVE_DIR_FD
4657 dir_fd_converter, &dir_fd,
4658#else
4659 dir_fd_unavailable, &dir_fd,
4660#endif
4661 &follow_symlinks
4662 ))
4663 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004664
Larry Hastings9cf065c2012-06-22 16:30:09 -07004665 if (times && (times != Py_None) && ns) {
4666 PyErr_SetString(PyExc_ValueError,
4667 "utime: you may specify either 'times'"
4668 " or 'ns' but not both");
4669 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004670 }
4671
4672 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004673 time_t a_sec, m_sec;
4674 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004675 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004676 PyErr_SetString(PyExc_TypeError,
4677 "utime: 'times' must be either"
4678 " a tuple of two ints or None");
4679 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004680 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004681 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004682 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004683 &a_sec, &a_nsec) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004684 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004685 &m_sec, &m_nsec) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004687 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004688 utime.atime_s = a_sec;
4689 utime.atime_ns = a_nsec;
4690 utime.mtime_s = m_sec;
4691 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004692 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004693 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004694 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004695 PyErr_SetString(PyExc_TypeError,
4696 "utime: 'ns' must be a tuple of two ints");
4697 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004698 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004699 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004700 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004701 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004702 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004703 &utime.mtime_s, &utime.mtime_ns)) {
4704 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004705 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706 }
4707 else {
4708 /* times and ns are both None/unspecified. use "now". */
4709 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004710 }
4711
Larry Hastings9cf065c2012-06-22 16:30:09 -07004712#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4713 if (follow_symlinks_specified("utime", follow_symlinks))
4714 goto exit;
4715#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004716
Larry Hastings9cf065c2012-06-22 16:30:09 -07004717 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4718 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4719 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4720 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004721
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722#if !defined(HAVE_UTIMENSAT)
4723 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004724 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004725 "utime: cannot use dir_fd and follow_symlinks "
4726 "together on this platform");
4727 goto exit;
4728 }
4729#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004730
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004731#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732 Py_BEGIN_ALLOW_THREADS
4733 if (path.wide)
4734 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004735 NULL, OPEN_EXISTING,
4736 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004737 else
4738 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004739 NULL, OPEN_EXISTING,
4740 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004741 Py_END_ALLOW_THREADS
4742 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004743 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004744 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004745 }
4746
Larry Hastings9cf065c2012-06-22 16:30:09 -07004747 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004748 SYSTEMTIME now;
4749 GetSystemTime(&now);
4750 if (!SystemTimeToFileTime(&now, &mtime) ||
4751 !SystemTimeToFileTime(&now, &atime)) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004752 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004754 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004755 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004756 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4758 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004759 }
4760 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4761 /* Avoid putting the file name into the error here,
4762 as that may confuse the user into believing that
4763 something is wrong with the file, when it also
4764 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004765 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004766 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004767 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004768#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004769 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004770
Larry Hastings9cf065c2012-06-22 16:30:09 -07004771#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4772 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4773 result = utime_nofollow_symlinks(&utime, path.narrow);
4774 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004775#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004776
4777#if UTIME_HAVE_DIR_FD
4778 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4779 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4780 else
4781#endif
4782
4783#if UTIME_HAVE_FD
4784 if (path.fd != -1)
4785 result = utime_fd(&utime, path.fd);
4786 else
4787#endif
4788
4789 result = utime_default(&utime, path.narrow);
4790
4791 Py_END_ALLOW_THREADS
4792
4793 if (result < 0) {
4794 /* see previous comment about not putting filename in error here */
4795 return_value = posix_error();
4796 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004798
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004799#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004800
4801 Py_INCREF(Py_None);
4802 return_value = Py_None;
4803
4804exit:
4805 path_cleanup(&path);
4806#ifdef MS_WINDOWS
4807 if (hFile != INVALID_HANDLE_VALUE)
4808 CloseHandle(hFile);
4809#endif
4810 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004811}
4812
Guido van Rossum3b066191991-06-04 19:40:25 +00004813/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004814
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004815PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004816"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004817Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004818
Barry Warsaw53699e91996-12-10 23:23:01 +00004819static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004820posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004821{
Victor Stinner8c62be82010-05-06 00:08:46 +00004822 int sts;
4823 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4824 return NULL;
4825 _exit(sts);
4826 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004827}
4828
Martin v. Löwis114619e2002-10-07 06:44:21 +00004829#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4830static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004831free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004832{
Victor Stinner8c62be82010-05-06 00:08:46 +00004833 Py_ssize_t i;
4834 for (i = 0; i < count; i++)
4835 PyMem_Free(array[i]);
4836 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004837}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004838
Antoine Pitrou69f71142009-05-24 21:25:49 +00004839static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004840int fsconvert_strdup(PyObject *o, char**out)
4841{
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 PyObject *bytes;
4843 Py_ssize_t size;
4844 if (!PyUnicode_FSConverter(o, &bytes))
4845 return 0;
4846 size = PyBytes_GET_SIZE(bytes);
4847 *out = PyMem_Malloc(size+1);
4848 if (!*out)
4849 return 0;
4850 memcpy(*out, PyBytes_AsString(bytes), size+1);
4851 Py_DECREF(bytes);
4852 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004853}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004854#endif
4855
Ross Lagerwall7807c352011-03-17 20:20:30 +02004856#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004857static char**
4858parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4859{
Victor Stinner8c62be82010-05-06 00:08:46 +00004860 char **envlist;
4861 Py_ssize_t i, pos, envc;
4862 PyObject *keys=NULL, *vals=NULL;
4863 PyObject *key, *val, *key2, *val2;
4864 char *p, *k, *v;
4865 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004866
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 i = PyMapping_Size(env);
4868 if (i < 0)
4869 return NULL;
4870 envlist = PyMem_NEW(char *, i + 1);
4871 if (envlist == NULL) {
4872 PyErr_NoMemory();
4873 return NULL;
4874 }
4875 envc = 0;
4876 keys = PyMapping_Keys(env);
4877 vals = PyMapping_Values(env);
4878 if (!keys || !vals)
4879 goto error;
4880 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4881 PyErr_Format(PyExc_TypeError,
4882 "env.keys() or env.values() is not a list");
4883 goto error;
4884 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004885
Victor Stinner8c62be82010-05-06 00:08:46 +00004886 for (pos = 0; pos < i; pos++) {
4887 key = PyList_GetItem(keys, pos);
4888 val = PyList_GetItem(vals, pos);
4889 if (!key || !val)
4890 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004891
Victor Stinner8c62be82010-05-06 00:08:46 +00004892 if (PyUnicode_FSConverter(key, &key2) == 0)
4893 goto error;
4894 if (PyUnicode_FSConverter(val, &val2) == 0) {
4895 Py_DECREF(key2);
4896 goto error;
4897 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004898
Victor Stinner8c62be82010-05-06 00:08:46 +00004899 k = PyBytes_AsString(key2);
4900 v = PyBytes_AsString(val2);
4901 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004902
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 p = PyMem_NEW(char, len);
4904 if (p == NULL) {
4905 PyErr_NoMemory();
4906 Py_DECREF(key2);
4907 Py_DECREF(val2);
4908 goto error;
4909 }
4910 PyOS_snprintf(p, len, "%s=%s", k, v);
4911 envlist[envc++] = p;
4912 Py_DECREF(key2);
4913 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004914 }
4915 Py_DECREF(vals);
4916 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004917
Victor Stinner8c62be82010-05-06 00:08:46 +00004918 envlist[envc] = 0;
4919 *envc_ptr = envc;
4920 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004921
4922error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004923 Py_XDECREF(keys);
4924 Py_XDECREF(vals);
4925 while (--envc >= 0)
4926 PyMem_DEL(envlist[envc]);
4927 PyMem_DEL(envlist);
4928 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004929}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004930
Ross Lagerwall7807c352011-03-17 20:20:30 +02004931static char**
4932parse_arglist(PyObject* argv, Py_ssize_t *argc)
4933{
4934 int i;
4935 char **argvlist = PyMem_NEW(char *, *argc+1);
4936 if (argvlist == NULL) {
4937 PyErr_NoMemory();
4938 return NULL;
4939 }
4940 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004941 PyObject* item = PySequence_ITEM(argv, i);
4942 if (item == NULL)
4943 goto fail;
4944 if (!fsconvert_strdup(item, &argvlist[i])) {
4945 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004946 goto fail;
4947 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004948 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004949 }
4950 argvlist[*argc] = NULL;
4951 return argvlist;
4952fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004953 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004954 free_string_array(argvlist, *argc);
4955 return NULL;
4956}
4957#endif
4958
4959#ifdef HAVE_EXECV
4960PyDoc_STRVAR(posix_execv__doc__,
4961"execv(path, args)\n\n\
4962Execute an executable path with arguments, replacing current process.\n\
4963\n\
4964 path: path of executable file\n\
4965 args: tuple or list of strings");
4966
4967static PyObject *
4968posix_execv(PyObject *self, PyObject *args)
4969{
4970 PyObject *opath;
4971 char *path;
4972 PyObject *argv;
4973 char **argvlist;
4974 Py_ssize_t argc;
4975
4976 /* execv has two arguments: (path, argv), where
4977 argv is a list or tuple of strings. */
4978
4979 if (!PyArg_ParseTuple(args, "O&O:execv",
4980 PyUnicode_FSConverter,
4981 &opath, &argv))
4982 return NULL;
4983 path = PyBytes_AsString(opath);
4984 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4985 PyErr_SetString(PyExc_TypeError,
4986 "execv() arg 2 must be a tuple or list");
4987 Py_DECREF(opath);
4988 return NULL;
4989 }
4990 argc = PySequence_Size(argv);
4991 if (argc < 1) {
4992 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4993 Py_DECREF(opath);
4994 return NULL;
4995 }
4996
4997 argvlist = parse_arglist(argv, &argc);
4998 if (argvlist == NULL) {
4999 Py_DECREF(opath);
5000 return NULL;
5001 }
5002
5003 execv(path, argvlist);
5004
5005 /* If we get here it's definitely an error */
5006
5007 free_string_array(argvlist, argc);
5008 Py_DECREF(opath);
5009 return posix_error();
5010}
5011
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005012PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005013"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005014Execute a path with arguments and environment, replacing current process.\n\
5015\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005016 path: path of executable file\n\
5017 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005018 env: dictionary of strings mapping to strings\n\
5019\n\
5020On some platforms, you may specify an open file descriptor for path;\n\
5021 execve will execute the program the file descriptor is open to.\n\
5022 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005023
Barry Warsaw53699e91996-12-10 23:23:01 +00005024static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005025posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005026{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005027 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005028 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005029 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005030 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005031 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005032 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005033
Victor Stinner8c62be82010-05-06 00:08:46 +00005034 /* execve has three arguments: (path, argv, env), where
5035 argv is a list or tuple of strings and env is a dictionary
5036 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005037
Larry Hastings9cf065c2012-06-22 16:30:09 -07005038 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005039 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005040#ifdef HAVE_FEXECVE
5041 path.allow_fd = 1;
5042#endif
5043 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5044 path_converter, &path,
5045 &argv, &env
5046 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005047 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005048
Ross Lagerwall7807c352011-03-17 20:20:30 +02005049 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005050 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005051 "execve: argv must be a tuple or list");
5052 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005053 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005054 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 if (!PyMapping_Check(env)) {
5056 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005057 "execve: environment must be a mapping object");
5058 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005059 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005060
Ross Lagerwall7807c352011-03-17 20:20:30 +02005061 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005062 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005063 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005064 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005065
Victor Stinner8c62be82010-05-06 00:08:46 +00005066 envlist = parse_envlist(env, &envc);
5067 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005068 goto fail;
5069
Larry Hastings9cf065c2012-06-22 16:30:09 -07005070#ifdef HAVE_FEXECVE
5071 if (path.fd > -1)
5072 fexecve(path.fd, argvlist, envlist);
5073 else
5074#endif
5075 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005076
5077 /* If we get here it's definitely an error */
5078
Victor Stinner292c8352012-10-30 02:17:38 +01005079 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005080
5081 while (--envc >= 0)
5082 PyMem_DEL(envlist[envc]);
5083 PyMem_DEL(envlist);
5084 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005085 if (argvlist)
5086 free_string_array(argvlist, argc);
5087 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005088 return NULL;
5089}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005090#endif /* HAVE_EXECV */
5091
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005092
Guido van Rossuma1065681999-01-25 23:20:23 +00005093#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005094PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005095"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005096Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005097\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005098 mode: mode of process creation\n\
5099 path: path of executable file\n\
5100 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005101
5102static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005103posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005104{
Victor Stinner8c62be82010-05-06 00:08:46 +00005105 PyObject *opath;
5106 char *path;
5107 PyObject *argv;
5108 char **argvlist;
5109 int mode, i;
5110 Py_ssize_t argc;
5111 Py_intptr_t spawnval;
5112 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005113
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 /* spawnv has three arguments: (mode, path, argv), where
5115 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005116
Victor Stinner8c62be82010-05-06 00:08:46 +00005117 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5118 PyUnicode_FSConverter,
5119 &opath, &argv))
5120 return NULL;
5121 path = PyBytes_AsString(opath);
5122 if (PyList_Check(argv)) {
5123 argc = PyList_Size(argv);
5124 getitem = PyList_GetItem;
5125 }
5126 else if (PyTuple_Check(argv)) {
5127 argc = PyTuple_Size(argv);
5128 getitem = PyTuple_GetItem;
5129 }
5130 else {
5131 PyErr_SetString(PyExc_TypeError,
5132 "spawnv() arg 2 must be a tuple or list");
5133 Py_DECREF(opath);
5134 return NULL;
5135 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005136
Victor Stinner8c62be82010-05-06 00:08:46 +00005137 argvlist = PyMem_NEW(char *, argc+1);
5138 if (argvlist == NULL) {
5139 Py_DECREF(opath);
5140 return PyErr_NoMemory();
5141 }
5142 for (i = 0; i < argc; i++) {
5143 if (!fsconvert_strdup((*getitem)(argv, i),
5144 &argvlist[i])) {
5145 free_string_array(argvlist, i);
5146 PyErr_SetString(
5147 PyExc_TypeError,
5148 "spawnv() arg 2 must contain only strings");
5149 Py_DECREF(opath);
5150 return NULL;
5151 }
5152 }
5153 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005154
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 if (mode == _OLD_P_OVERLAY)
5156 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005157
Victor Stinner8c62be82010-05-06 00:08:46 +00005158 Py_BEGIN_ALLOW_THREADS
5159 spawnval = _spawnv(mode, path, argvlist);
5160 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005161
Victor Stinner8c62be82010-05-06 00:08:46 +00005162 free_string_array(argvlist, argc);
5163 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005164
Victor Stinner8c62be82010-05-06 00:08:46 +00005165 if (spawnval == -1)
5166 return posix_error();
5167 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005168 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005169}
5170
5171
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005172PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005173"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005174Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005175\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005176 mode: mode of process creation\n\
5177 path: path of executable file\n\
5178 args: tuple or list of arguments\n\
5179 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005180
5181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005182posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005183{
Victor Stinner8c62be82010-05-06 00:08:46 +00005184 PyObject *opath;
5185 char *path;
5186 PyObject *argv, *env;
5187 char **argvlist;
5188 char **envlist;
5189 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005190 int mode;
5191 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 Py_intptr_t spawnval;
5193 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5194 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005195
Victor Stinner8c62be82010-05-06 00:08:46 +00005196 /* spawnve has four arguments: (mode, path, argv, env), where
5197 argv is a list or tuple of strings and env is a dictionary
5198 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005199
Victor Stinner8c62be82010-05-06 00:08:46 +00005200 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5201 PyUnicode_FSConverter,
5202 &opath, &argv, &env))
5203 return NULL;
5204 path = PyBytes_AsString(opath);
5205 if (PyList_Check(argv)) {
5206 argc = PyList_Size(argv);
5207 getitem = PyList_GetItem;
5208 }
5209 else if (PyTuple_Check(argv)) {
5210 argc = PyTuple_Size(argv);
5211 getitem = PyTuple_GetItem;
5212 }
5213 else {
5214 PyErr_SetString(PyExc_TypeError,
5215 "spawnve() arg 2 must be a tuple or list");
5216 goto fail_0;
5217 }
5218 if (!PyMapping_Check(env)) {
5219 PyErr_SetString(PyExc_TypeError,
5220 "spawnve() arg 3 must be a mapping object");
5221 goto fail_0;
5222 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005223
Victor Stinner8c62be82010-05-06 00:08:46 +00005224 argvlist = PyMem_NEW(char *, argc+1);
5225 if (argvlist == NULL) {
5226 PyErr_NoMemory();
5227 goto fail_0;
5228 }
5229 for (i = 0; i < argc; i++) {
5230 if (!fsconvert_strdup((*getitem)(argv, i),
5231 &argvlist[i]))
5232 {
5233 lastarg = i;
5234 goto fail_1;
5235 }
5236 }
5237 lastarg = argc;
5238 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005239
Victor Stinner8c62be82010-05-06 00:08:46 +00005240 envlist = parse_envlist(env, &envc);
5241 if (envlist == NULL)
5242 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005243
Victor Stinner8c62be82010-05-06 00:08:46 +00005244 if (mode == _OLD_P_OVERLAY)
5245 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005246
Victor Stinner8c62be82010-05-06 00:08:46 +00005247 Py_BEGIN_ALLOW_THREADS
5248 spawnval = _spawnve(mode, path, argvlist, envlist);
5249 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005250
Victor Stinner8c62be82010-05-06 00:08:46 +00005251 if (spawnval == -1)
5252 (void) posix_error();
5253 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005254 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005255
Victor Stinner8c62be82010-05-06 00:08:46 +00005256 while (--envc >= 0)
5257 PyMem_DEL(envlist[envc]);
5258 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005259 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005260 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005261 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005262 Py_DECREF(opath);
5263 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005264}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005265
Guido van Rossuma1065681999-01-25 23:20:23 +00005266#endif /* HAVE_SPAWNV */
5267
5268
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005269#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005270PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005271"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005272Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5273\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005274Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005275
5276static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005277posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005278{
Victor Stinner8c62be82010-05-06 00:08:46 +00005279 pid_t pid;
5280 int result = 0;
5281 _PyImport_AcquireLock();
5282 pid = fork1();
5283 if (pid == 0) {
5284 /* child: this clobbers and resets the import lock. */
5285 PyOS_AfterFork();
5286 } else {
5287 /* parent: release the import lock. */
5288 result = _PyImport_ReleaseLock();
5289 }
5290 if (pid == -1)
5291 return posix_error();
5292 if (result < 0) {
5293 /* Don't clobber the OSError if the fork failed. */
5294 PyErr_SetString(PyExc_RuntimeError,
5295 "not holding the import lock");
5296 return NULL;
5297 }
5298 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005299}
5300#endif
5301
5302
Guido van Rossumad0ee831995-03-01 10:34:45 +00005303#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005304PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005305"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005306Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005307Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005308
Barry Warsaw53699e91996-12-10 23:23:01 +00005309static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005310posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005311{
Victor Stinner8c62be82010-05-06 00:08:46 +00005312 pid_t pid;
5313 int result = 0;
5314 _PyImport_AcquireLock();
5315 pid = fork();
5316 if (pid == 0) {
5317 /* child: this clobbers and resets the import lock. */
5318 PyOS_AfterFork();
5319 } else {
5320 /* parent: release the import lock. */
5321 result = _PyImport_ReleaseLock();
5322 }
5323 if (pid == -1)
5324 return posix_error();
5325 if (result < 0) {
5326 /* Don't clobber the OSError if the fork failed. */
5327 PyErr_SetString(PyExc_RuntimeError,
5328 "not holding the import lock");
5329 return NULL;
5330 }
5331 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005332}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005333#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005334
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005335#ifdef HAVE_SCHED_H
5336
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005337#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5338
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005339PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5340"sched_get_priority_max(policy)\n\n\
5341Get the maximum scheduling priority for *policy*.");
5342
5343static PyObject *
5344posix_sched_get_priority_max(PyObject *self, PyObject *args)
5345{
5346 int policy, max;
5347
5348 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5349 return NULL;
5350 max = sched_get_priority_max(policy);
5351 if (max < 0)
5352 return posix_error();
5353 return PyLong_FromLong(max);
5354}
5355
5356PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5357"sched_get_priority_min(policy)\n\n\
5358Get the minimum scheduling priority for *policy*.");
5359
5360static PyObject *
5361posix_sched_get_priority_min(PyObject *self, PyObject *args)
5362{
5363 int policy, min;
5364
5365 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5366 return NULL;
5367 min = sched_get_priority_min(policy);
5368 if (min < 0)
5369 return posix_error();
5370 return PyLong_FromLong(min);
5371}
5372
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005373#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5374
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005375#ifdef HAVE_SCHED_SETSCHEDULER
5376
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005377PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5378"sched_getscheduler(pid)\n\n\
5379Get the scheduling policy for the process with a PID of *pid*.\n\
5380Passing a PID of 0 returns the scheduling policy for the calling process.");
5381
5382static PyObject *
5383posix_sched_getscheduler(PyObject *self, PyObject *args)
5384{
5385 pid_t pid;
5386 int policy;
5387
5388 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5389 return NULL;
5390 policy = sched_getscheduler(pid);
5391 if (policy < 0)
5392 return posix_error();
5393 return PyLong_FromLong(policy);
5394}
5395
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005396#endif
5397
5398#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5399
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005400static PyObject *
5401sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5402{
5403 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005404 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005405
5406 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5407 return NULL;
5408 res = PyStructSequence_New(type);
5409 if (!res)
5410 return NULL;
5411 Py_INCREF(priority);
5412 PyStructSequence_SET_ITEM(res, 0, priority);
5413 return res;
5414}
5415
5416PyDoc_STRVAR(sched_param__doc__,
5417"sched_param(sched_priority): A scheduling parameter.\n\n\
5418Current has only one field: sched_priority");
5419
5420static PyStructSequence_Field sched_param_fields[] = {
5421 {"sched_priority", "the scheduling priority"},
5422 {0}
5423};
5424
5425static PyStructSequence_Desc sched_param_desc = {
5426 "sched_param", /* name */
5427 sched_param__doc__, /* doc */
5428 sched_param_fields,
5429 1
5430};
5431
5432static int
5433convert_sched_param(PyObject *param, struct sched_param *res)
5434{
5435 long priority;
5436
5437 if (Py_TYPE(param) != &SchedParamType) {
5438 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5439 return 0;
5440 }
5441 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5442 if (priority == -1 && PyErr_Occurred())
5443 return 0;
5444 if (priority > INT_MAX || priority < INT_MIN) {
5445 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5446 return 0;
5447 }
5448 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5449 return 1;
5450}
5451
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005452#endif
5453
5454#ifdef HAVE_SCHED_SETSCHEDULER
5455
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005456PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5457"sched_setscheduler(pid, policy, param)\n\n\
5458Set the scheduling policy, *policy*, for *pid*.\n\
5459If *pid* is 0, the calling process is changed.\n\
5460*param* is an instance of sched_param.");
5461
5462static PyObject *
5463posix_sched_setscheduler(PyObject *self, PyObject *args)
5464{
5465 pid_t pid;
5466 int policy;
5467 struct sched_param param;
5468
5469 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5470 &pid, &policy, &convert_sched_param, &param))
5471 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005472
5473 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005474 ** sched_setscheduler() returns 0 in Linux, but the previous
5475 ** scheduling policy under Solaris/Illumos, and others.
5476 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005477 */
5478 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005479 return posix_error();
5480 Py_RETURN_NONE;
5481}
5482
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005483#endif
5484
5485#ifdef HAVE_SCHED_SETPARAM
5486
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005487PyDoc_STRVAR(posix_sched_getparam__doc__,
5488"sched_getparam(pid) -> sched_param\n\n\
5489Returns scheduling parameters for the process with *pid* as an instance of the\n\
5490sched_param class. A PID of 0 means the calling process.");
5491
5492static PyObject *
5493posix_sched_getparam(PyObject *self, PyObject *args)
5494{
5495 pid_t pid;
5496 struct sched_param param;
5497 PyObject *res, *priority;
5498
5499 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5500 return NULL;
5501 if (sched_getparam(pid, &param))
5502 return posix_error();
5503 res = PyStructSequence_New(&SchedParamType);
5504 if (!res)
5505 return NULL;
5506 priority = PyLong_FromLong(param.sched_priority);
5507 if (!priority) {
5508 Py_DECREF(res);
5509 return NULL;
5510 }
5511 PyStructSequence_SET_ITEM(res, 0, priority);
5512 return res;
5513}
5514
5515PyDoc_STRVAR(posix_sched_setparam__doc__,
5516"sched_setparam(pid, param)\n\n\
5517Set scheduling parameters for a process with PID *pid*.\n\
5518A PID of 0 means the calling process.");
5519
5520static PyObject *
5521posix_sched_setparam(PyObject *self, PyObject *args)
5522{
5523 pid_t pid;
5524 struct sched_param param;
5525
5526 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5527 &pid, &convert_sched_param, &param))
5528 return NULL;
5529 if (sched_setparam(pid, &param))
5530 return posix_error();
5531 Py_RETURN_NONE;
5532}
5533
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005534#endif
5535
5536#ifdef HAVE_SCHED_RR_GET_INTERVAL
5537
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005538PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5539"sched_rr_get_interval(pid) -> float\n\n\
5540Return the round-robin quantum for the process with PID *pid* in seconds.");
5541
5542static PyObject *
5543posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5544{
5545 pid_t pid;
5546 struct timespec interval;
5547
5548 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5549 return NULL;
5550 if (sched_rr_get_interval(pid, &interval))
5551 return posix_error();
5552 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5553}
5554
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005555#endif
5556
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005557PyDoc_STRVAR(posix_sched_yield__doc__,
5558"sched_yield()\n\n\
5559Voluntarily relinquish the CPU.");
5560
5561static PyObject *
5562posix_sched_yield(PyObject *self, PyObject *noargs)
5563{
5564 if (sched_yield())
5565 return posix_error();
5566 Py_RETURN_NONE;
5567}
5568
Benjamin Peterson2740af82011-08-02 17:41:34 -05005569#ifdef HAVE_SCHED_SETAFFINITY
5570
Antoine Pitrou84869872012-08-04 16:16:35 +02005571/* The minimum number of CPUs allocated in a cpu_set_t */
5572static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005573
5574PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5575"sched_setaffinity(pid, cpu_set)\n\n\
5576Set the affinity of the process with PID *pid* to *cpu_set*.");
5577
5578static PyObject *
5579posix_sched_setaffinity(PyObject *self, PyObject *args)
5580{
5581 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005582 int ncpus;
5583 size_t setsize;
5584 cpu_set_t *mask = NULL;
5585 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005586
Antoine Pitrou84869872012-08-04 16:16:35 +02005587 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5588 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005589 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005590
5591 iterator = PyObject_GetIter(iterable);
5592 if (iterator == NULL)
5593 return NULL;
5594
5595 ncpus = NCPUS_START;
5596 setsize = CPU_ALLOC_SIZE(ncpus);
5597 mask = CPU_ALLOC(ncpus);
5598 if (mask == NULL) {
5599 PyErr_NoMemory();
5600 goto error;
5601 }
5602 CPU_ZERO_S(setsize, mask);
5603
5604 while ((item = PyIter_Next(iterator))) {
5605 long cpu;
5606 if (!PyLong_Check(item)) {
5607 PyErr_Format(PyExc_TypeError,
5608 "expected an iterator of ints, "
5609 "but iterator yielded %R",
5610 Py_TYPE(item));
5611 Py_DECREF(item);
5612 goto error;
5613 }
5614 cpu = PyLong_AsLong(item);
5615 Py_DECREF(item);
5616 if (cpu < 0) {
5617 if (!PyErr_Occurred())
5618 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5619 goto error;
5620 }
5621 if (cpu > INT_MAX - 1) {
5622 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5623 goto error;
5624 }
5625 if (cpu >= ncpus) {
5626 /* Grow CPU mask to fit the CPU number */
5627 int newncpus = ncpus;
5628 cpu_set_t *newmask;
5629 size_t newsetsize;
5630 while (newncpus <= cpu) {
5631 if (newncpus > INT_MAX / 2)
5632 newncpus = cpu + 1;
5633 else
5634 newncpus = newncpus * 2;
5635 }
5636 newmask = CPU_ALLOC(newncpus);
5637 if (newmask == NULL) {
5638 PyErr_NoMemory();
5639 goto error;
5640 }
5641 newsetsize = CPU_ALLOC_SIZE(newncpus);
5642 CPU_ZERO_S(newsetsize, newmask);
5643 memcpy(newmask, mask, setsize);
5644 CPU_FREE(mask);
5645 setsize = newsetsize;
5646 mask = newmask;
5647 ncpus = newncpus;
5648 }
5649 CPU_SET_S(cpu, setsize, mask);
5650 }
5651 Py_CLEAR(iterator);
5652
5653 if (sched_setaffinity(pid, setsize, mask)) {
5654 posix_error();
5655 goto error;
5656 }
5657 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005658 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005659
5660error:
5661 if (mask)
5662 CPU_FREE(mask);
5663 Py_XDECREF(iterator);
5664 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005665}
5666
5667PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5668"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5669Return the affinity of the process with PID *pid*.\n\
5670The returned cpu_set will be of size *ncpus*.");
5671
5672static PyObject *
5673posix_sched_getaffinity(PyObject *self, PyObject *args)
5674{
5675 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005676 int cpu, ncpus, count;
5677 size_t setsize;
5678 cpu_set_t *mask = NULL;
5679 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005680
Antoine Pitrou84869872012-08-04 16:16:35 +02005681 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5682 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005683 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005684
5685 ncpus = NCPUS_START;
5686 while (1) {
5687 setsize = CPU_ALLOC_SIZE(ncpus);
5688 mask = CPU_ALLOC(ncpus);
5689 if (mask == NULL)
5690 return PyErr_NoMemory();
5691 if (sched_getaffinity(pid, setsize, mask) == 0)
5692 break;
5693 CPU_FREE(mask);
5694 if (errno != EINVAL)
5695 return posix_error();
5696 if (ncpus > INT_MAX / 2) {
5697 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5698 "a large enough CPU set");
5699 return NULL;
5700 }
5701 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005702 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005703
5704 res = PySet_New(NULL);
5705 if (res == NULL)
5706 goto error;
5707 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5708 if (CPU_ISSET_S(cpu, setsize, mask)) {
5709 PyObject *cpu_num = PyLong_FromLong(cpu);
5710 --count;
5711 if (cpu_num == NULL)
5712 goto error;
5713 if (PySet_Add(res, cpu_num)) {
5714 Py_DECREF(cpu_num);
5715 goto error;
5716 }
5717 Py_DECREF(cpu_num);
5718 }
5719 }
5720 CPU_FREE(mask);
5721 return res;
5722
5723error:
5724 if (mask)
5725 CPU_FREE(mask);
5726 Py_XDECREF(res);
5727 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005728}
5729
Benjamin Peterson2740af82011-08-02 17:41:34 -05005730#endif /* HAVE_SCHED_SETAFFINITY */
5731
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005732#endif /* HAVE_SCHED_H */
5733
Neal Norwitzb59798b2003-03-21 01:43:31 +00005734/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005735/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5736#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005737#define DEV_PTY_FILE "/dev/ptc"
5738#define HAVE_DEV_PTMX
5739#else
5740#define DEV_PTY_FILE "/dev/ptmx"
5741#endif
5742
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005743#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005744#ifdef HAVE_PTY_H
5745#include <pty.h>
5746#else
5747#ifdef HAVE_LIBUTIL_H
5748#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005749#else
5750#ifdef HAVE_UTIL_H
5751#include <util.h>
5752#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005753#endif /* HAVE_LIBUTIL_H */
5754#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005755#ifdef HAVE_STROPTS_H
5756#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005757#endif
5758#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005759
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005760#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005761PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005762"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005763Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005764
5765static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005766posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005767{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005768 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005769#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005770 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005771#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005772#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005773 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005774#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005775 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005776#endif
5777#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005778
Thomas Wouters70c21a12000-07-14 14:28:33 +00005779#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005780 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005781 goto posix_error;
5782
5783 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5784 goto error;
5785 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5786 goto error;
5787
Neal Norwitzb59798b2003-03-21 01:43:31 +00005788#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005789 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5790 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005791 goto posix_error;
5792 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5793 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005794
Victor Stinnerdaf45552013-08-28 00:53:59 +02005795 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005796 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005797 goto posix_error;
5798
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005799#else
Victor Stinnerdaf45552013-08-28 00:53:59 +02005800 master_fd = _Py_open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005801 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005802 goto posix_error;
5803
Victor Stinner8c62be82010-05-06 00:08:46 +00005804 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005805
Victor Stinner8c62be82010-05-06 00:08:46 +00005806 /* change permission of slave */
5807 if (grantpt(master_fd) < 0) {
5808 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005809 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005810 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005811
Victor Stinner8c62be82010-05-06 00:08:46 +00005812 /* unlock slave */
5813 if (unlockpt(master_fd) < 0) {
5814 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005815 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005816 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005817
Victor Stinner8c62be82010-05-06 00:08:46 +00005818 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005819
Victor Stinner8c62be82010-05-06 00:08:46 +00005820 slave_name = ptsname(master_fd); /* get name of slave */
5821 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005822 goto posix_error;
5823
5824 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00005825 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005826 goto posix_error;
Neal Norwitzb59798b2003-03-21 01:43:31 +00005827#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005828 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5829 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005830#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005831 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005832#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005833#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005834#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005835
Victor Stinner8c62be82010-05-06 00:08:46 +00005836 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005837
Victor Stinnerdaf45552013-08-28 00:53:59 +02005838posix_error:
5839 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02005840#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005841error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02005842#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02005843 if (master_fd != -1)
5844 close(master_fd);
5845 if (slave_fd != -1)
5846 close(slave_fd);
5847 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005848}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005849#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005850
5851#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005852PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005853"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005854Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5855Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005856To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005857
5858static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005859posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005860{
Victor Stinner8c62be82010-05-06 00:08:46 +00005861 int master_fd = -1, result = 0;
5862 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005863
Victor Stinner8c62be82010-05-06 00:08:46 +00005864 _PyImport_AcquireLock();
5865 pid = forkpty(&master_fd, NULL, NULL, NULL);
5866 if (pid == 0) {
5867 /* child: this clobbers and resets the import lock. */
5868 PyOS_AfterFork();
5869 } else {
5870 /* parent: release the import lock. */
5871 result = _PyImport_ReleaseLock();
5872 }
5873 if (pid == -1)
5874 return posix_error();
5875 if (result < 0) {
5876 /* Don't clobber the OSError if the fork failed. */
5877 PyErr_SetString(PyExc_RuntimeError,
5878 "not holding the import lock");
5879 return NULL;
5880 }
5881 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005882}
5883#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005884
Ross Lagerwall7807c352011-03-17 20:20:30 +02005885
Guido van Rossumad0ee831995-03-01 10:34:45 +00005886#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005887PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005888"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005889Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005890
Barry Warsaw53699e91996-12-10 23:23:01 +00005891static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005892posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005893{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005894 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005895}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005896#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005898
Guido van Rossumad0ee831995-03-01 10:34:45 +00005899#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005900PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005901"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005902Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005903
Barry Warsaw53699e91996-12-10 23:23:01 +00005904static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005905posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005906{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005907 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005908}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005909#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005911
Guido van Rossumad0ee831995-03-01 10:34:45 +00005912#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005913PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005914"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005915Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005916
Barry Warsaw53699e91996-12-10 23:23:01 +00005917static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005918posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005919{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005920 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005921}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005922#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005923
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005924
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005925PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005926"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005927Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005928
Barry Warsaw53699e91996-12-10 23:23:01 +00005929static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005930posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005931{
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005933}
5934
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005935#ifdef HAVE_GETGROUPLIST
5936PyDoc_STRVAR(posix_getgrouplist__doc__,
5937"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5938Returns a list of groups to which a user belongs.\n\n\
5939 user: username to lookup\n\
5940 group: base group id of the user");
5941
5942static PyObject *
5943posix_getgrouplist(PyObject *self, PyObject *args)
5944{
5945#ifdef NGROUPS_MAX
5946#define MAX_GROUPS NGROUPS_MAX
5947#else
5948 /* defined to be 16 on Solaris7, so this should be a small number */
5949#define MAX_GROUPS 64
5950#endif
5951
5952 const char *user;
5953 int i, ngroups;
5954 PyObject *list;
5955#ifdef __APPLE__
5956 int *groups, basegid;
5957#else
5958 gid_t *groups, basegid;
5959#endif
5960 ngroups = MAX_GROUPS;
5961
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005962#ifdef __APPLE__
5963 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005964 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005965#else
5966 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
5967 _Py_Gid_Converter, &basegid))
5968 return NULL;
5969#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005970
5971#ifdef __APPLE__
5972 groups = PyMem_Malloc(ngroups * sizeof(int));
5973#else
5974 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5975#endif
5976 if (groups == NULL)
5977 return PyErr_NoMemory();
5978
5979 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5980 PyMem_Del(groups);
5981 return posix_error();
5982 }
5983
5984 list = PyList_New(ngroups);
5985 if (list == NULL) {
5986 PyMem_Del(groups);
5987 return NULL;
5988 }
5989
5990 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005991#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005992 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005993#else
5994 PyObject *o = _PyLong_FromGid(groups[i]);
5995#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005996 if (o == NULL) {
5997 Py_DECREF(list);
5998 PyMem_Del(groups);
5999 return NULL;
6000 }
6001 PyList_SET_ITEM(list, i, o);
6002 }
6003
6004 PyMem_Del(groups);
6005
6006 return list;
6007}
6008#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006009
Fred Drakec9680921999-12-13 16:37:25 +00006010#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006011PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006012"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006013Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006014
6015static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006016posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006017{
6018 PyObject *result = NULL;
6019
Fred Drakec9680921999-12-13 16:37:25 +00006020#ifdef NGROUPS_MAX
6021#define MAX_GROUPS NGROUPS_MAX
6022#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006023 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006024#define MAX_GROUPS 64
6025#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006026 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006027
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006028 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006029 * This is a helper variable to store the intermediate result when
6030 * that happens.
6031 *
6032 * To keep the code readable the OSX behaviour is unconditional,
6033 * according to the POSIX spec this should be safe on all unix-y
6034 * systems.
6035 */
6036 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006037 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006038
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006039#ifdef __APPLE__
6040 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6041 * there are more groups than can fit in grouplist. Therefore, on OS X
6042 * always first call getgroups with length 0 to get the actual number
6043 * of groups.
6044 */
6045 n = getgroups(0, NULL);
6046 if (n < 0) {
6047 return posix_error();
6048 } else if (n <= MAX_GROUPS) {
6049 /* groups will fit in existing array */
6050 alt_grouplist = grouplist;
6051 } else {
6052 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6053 if (alt_grouplist == NULL) {
6054 errno = EINVAL;
6055 return posix_error();
6056 }
6057 }
6058
6059 n = getgroups(n, alt_grouplist);
6060 if (n == -1) {
6061 if (alt_grouplist != grouplist) {
6062 PyMem_Free(alt_grouplist);
6063 }
6064 return posix_error();
6065 }
6066#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006067 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006068 if (n < 0) {
6069 if (errno == EINVAL) {
6070 n = getgroups(0, NULL);
6071 if (n == -1) {
6072 return posix_error();
6073 }
6074 if (n == 0) {
6075 /* Avoid malloc(0) */
6076 alt_grouplist = grouplist;
6077 } else {
6078 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6079 if (alt_grouplist == NULL) {
6080 errno = EINVAL;
6081 return posix_error();
6082 }
6083 n = getgroups(n, alt_grouplist);
6084 if (n == -1) {
6085 PyMem_Free(alt_grouplist);
6086 return posix_error();
6087 }
6088 }
6089 } else {
6090 return posix_error();
6091 }
6092 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006093#endif
6094
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006095 result = PyList_New(n);
6096 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006097 int i;
6098 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006099 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006100 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006101 Py_DECREF(result);
6102 result = NULL;
6103 break;
Fred Drakec9680921999-12-13 16:37:25 +00006104 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006105 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006106 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006107 }
6108
6109 if (alt_grouplist != grouplist) {
6110 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006111 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006112
Fred Drakec9680921999-12-13 16:37:25 +00006113 return result;
6114}
6115#endif
6116
Antoine Pitroub7572f02009-12-02 20:46:48 +00006117#ifdef HAVE_INITGROUPS
6118PyDoc_STRVAR(posix_initgroups__doc__,
6119"initgroups(username, gid) -> None\n\n\
6120Call the system initgroups() to initialize the group access list with all of\n\
6121the groups of which the specified username is a member, plus the specified\n\
6122group id.");
6123
6124static PyObject *
6125posix_initgroups(PyObject *self, PyObject *args)
6126{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006127 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006128 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006129 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006130#ifdef __APPLE__
6131 int gid;
6132#else
6133 gid_t gid;
6134#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006135
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006136#ifdef __APPLE__
6137 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6138 PyUnicode_FSConverter, &oname,
6139 &gid))
6140#else
6141 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6142 PyUnicode_FSConverter, &oname,
6143 _Py_Gid_Converter, &gid))
6144#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006145 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006146 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006147
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006148 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006149 Py_DECREF(oname);
6150 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006151 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006152
Victor Stinner8c62be82010-05-06 00:08:46 +00006153 Py_INCREF(Py_None);
6154 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006155}
6156#endif
6157
Martin v. Löwis606edc12002-06-13 21:09:11 +00006158#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006159PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006160"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006161Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006162
6163static PyObject *
6164posix_getpgid(PyObject *self, PyObject *args)
6165{
Victor Stinner8c62be82010-05-06 00:08:46 +00006166 pid_t pid, pgid;
6167 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6168 return NULL;
6169 pgid = getpgid(pid);
6170 if (pgid < 0)
6171 return posix_error();
6172 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006173}
6174#endif /* HAVE_GETPGID */
6175
6176
Guido van Rossumb6775db1994-08-01 11:34:53 +00006177#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006178PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006179"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006180Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006181
Barry Warsaw53699e91996-12-10 23:23:01 +00006182static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006183posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006184{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006185#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006186 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006187#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006188 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006189#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006190}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006191#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006192
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006193
Guido van Rossumb6775db1994-08-01 11:34:53 +00006194#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006195PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006196"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006197Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006198
Barry Warsaw53699e91996-12-10 23:23:01 +00006199static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006200posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006201{
Guido van Rossum64933891994-10-20 21:56:42 +00006202#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006203 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006204#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006205 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006206#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006207 return posix_error();
6208 Py_INCREF(Py_None);
6209 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006210}
6211
Guido van Rossumb6775db1994-08-01 11:34:53 +00006212#endif /* HAVE_SETPGRP */
6213
Guido van Rossumad0ee831995-03-01 10:34:45 +00006214#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006215
6216#ifdef MS_WINDOWS
6217#include <tlhelp32.h>
6218
6219static PyObject*
6220win32_getppid()
6221{
6222 HANDLE snapshot;
6223 pid_t mypid;
6224 PyObject* result = NULL;
6225 BOOL have_record;
6226 PROCESSENTRY32 pe;
6227
6228 mypid = getpid(); /* This function never fails */
6229
6230 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6231 if (snapshot == INVALID_HANDLE_VALUE)
6232 return PyErr_SetFromWindowsErr(GetLastError());
6233
6234 pe.dwSize = sizeof(pe);
6235 have_record = Process32First(snapshot, &pe);
6236 while (have_record) {
6237 if (mypid == (pid_t)pe.th32ProcessID) {
6238 /* We could cache the ulong value in a static variable. */
6239 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6240 break;
6241 }
6242
6243 have_record = Process32Next(snapshot, &pe);
6244 }
6245
6246 /* If our loop exits and our pid was not found (result will be NULL)
6247 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6248 * error anyway, so let's raise it. */
6249 if (!result)
6250 result = PyErr_SetFromWindowsErr(GetLastError());
6251
6252 CloseHandle(snapshot);
6253
6254 return result;
6255}
6256#endif /*MS_WINDOWS*/
6257
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006258PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006259"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006260Return the parent's process id. If the parent process has already exited,\n\
6261Windows machines will still return its id; others systems will return the id\n\
6262of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006263
Barry Warsaw53699e91996-12-10 23:23:01 +00006264static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006265posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006266{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006267#ifdef MS_WINDOWS
6268 return win32_getppid();
6269#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006270 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006271#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006272}
6273#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006274
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006275
Fred Drake12c6e2d1999-12-14 21:25:03 +00006276#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006277PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006278"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006279Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006280
6281static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006282posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006283{
Victor Stinner8c62be82010-05-06 00:08:46 +00006284 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006285#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006286 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006287 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006288
6289 if (GetUserNameW(user_name, &num_chars)) {
6290 /* num_chars is the number of unicode chars plus null terminator */
6291 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006292 }
6293 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006294 result = PyErr_SetFromWindowsErr(GetLastError());
6295#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 char *name;
6297 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006298
Victor Stinner8c62be82010-05-06 00:08:46 +00006299 errno = 0;
6300 name = getlogin();
6301 if (name == NULL) {
6302 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006303 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006304 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006305 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006306 }
6307 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006308 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006309 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006310#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006311 return result;
6312}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006313#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006314
Guido van Rossumad0ee831995-03-01 10:34:45 +00006315#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006316PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006317"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006318Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006319
Barry Warsaw53699e91996-12-10 23:23:01 +00006320static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006321posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006322{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006323 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006324}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006325#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006327
Guido van Rossumad0ee831995-03-01 10:34:45 +00006328#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006329PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006330"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006331Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006332
Barry Warsaw53699e91996-12-10 23:23:01 +00006333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006334posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006335{
Victor Stinner8c62be82010-05-06 00:08:46 +00006336 pid_t pid;
6337 int sig;
6338 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6339 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 if (kill(pid, sig) == -1)
6341 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006342 Py_INCREF(Py_None);
6343 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006344}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006345#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006346
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006347#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006348PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006349"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006350Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006351
6352static PyObject *
6353posix_killpg(PyObject *self, PyObject *args)
6354{
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 int sig;
6356 pid_t pgid;
6357 /* XXX some man pages make the `pgid` parameter an int, others
6358 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6359 take the same type. Moreover, pid_t is always at least as wide as
6360 int (else compilation of this module fails), which is safe. */
6361 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6362 return NULL;
6363 if (killpg(pgid, sig) == -1)
6364 return posix_error();
6365 Py_INCREF(Py_None);
6366 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006367}
6368#endif
6369
Brian Curtineb24d742010-04-12 17:16:38 +00006370#ifdef MS_WINDOWS
6371PyDoc_STRVAR(win32_kill__doc__,
6372"kill(pid, sig)\n\n\
6373Kill a process with a signal.");
6374
6375static PyObject *
6376win32_kill(PyObject *self, PyObject *args)
6377{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006378 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006379 pid_t pid;
6380 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006382
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006383 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006385
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 /* Console processes which share a common console can be sent CTRL+C or
6387 CTRL+BREAK events, provided they handle said events. */
6388 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006389 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006390 err = GetLastError();
6391 PyErr_SetFromWindowsErr(err);
6392 }
6393 else
6394 Py_RETURN_NONE;
6395 }
Brian Curtineb24d742010-04-12 17:16:38 +00006396
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6398 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006399 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 if (handle == NULL) {
6401 err = GetLastError();
6402 return PyErr_SetFromWindowsErr(err);
6403 }
Brian Curtineb24d742010-04-12 17:16:38 +00006404
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 if (TerminateProcess(handle, sig) == 0) {
6406 err = GetLastError();
6407 result = PyErr_SetFromWindowsErr(err);
6408 } else {
6409 Py_INCREF(Py_None);
6410 result = Py_None;
6411 }
Brian Curtineb24d742010-04-12 17:16:38 +00006412
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 CloseHandle(handle);
6414 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006415}
6416#endif /* MS_WINDOWS */
6417
Guido van Rossumc0125471996-06-28 18:55:32 +00006418#ifdef HAVE_PLOCK
6419
6420#ifdef HAVE_SYS_LOCK_H
6421#include <sys/lock.h>
6422#endif
6423
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006424PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006425"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006426Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006427
Barry Warsaw53699e91996-12-10 23:23:01 +00006428static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006429posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006430{
Victor Stinner8c62be82010-05-06 00:08:46 +00006431 int op;
6432 if (!PyArg_ParseTuple(args, "i:plock", &op))
6433 return NULL;
6434 if (plock(op) == -1)
6435 return posix_error();
6436 Py_INCREF(Py_None);
6437 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006438}
6439#endif
6440
Guido van Rossumb6775db1994-08-01 11:34:53 +00006441#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006442PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006443"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006444Set the current process's user id.");
6445
Barry Warsaw53699e91996-12-10 23:23:01 +00006446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006447posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006448{
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006450 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006451 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 if (setuid(uid) < 0)
6453 return posix_error();
6454 Py_INCREF(Py_None);
6455 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006456}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006457#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006458
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006459
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006460#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006461PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006462"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006463Set the current process's effective user id.");
6464
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006465static PyObject *
6466posix_seteuid (PyObject *self, PyObject *args)
6467{
Victor Stinner8c62be82010-05-06 00:08:46 +00006468 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006469 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006470 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006471 if (seteuid(euid) < 0) {
6472 return posix_error();
6473 } else {
6474 Py_INCREF(Py_None);
6475 return Py_None;
6476 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006477}
6478#endif /* HAVE_SETEUID */
6479
6480#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006481PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006482"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006483Set the current process's effective group id.");
6484
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006485static PyObject *
6486posix_setegid (PyObject *self, PyObject *args)
6487{
Victor Stinner8c62be82010-05-06 00:08:46 +00006488 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006489 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006490 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006491 if (setegid(egid) < 0) {
6492 return posix_error();
6493 } else {
6494 Py_INCREF(Py_None);
6495 return Py_None;
6496 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006497}
6498#endif /* HAVE_SETEGID */
6499
6500#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006501PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006502"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006503Set the current process's real and effective user ids.");
6504
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006505static PyObject *
6506posix_setreuid (PyObject *self, PyObject *args)
6507{
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006509 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6510 _Py_Uid_Converter, &ruid,
6511 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006512 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006513 if (setreuid(ruid, euid) < 0) {
6514 return posix_error();
6515 } else {
6516 Py_INCREF(Py_None);
6517 return Py_None;
6518 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006519}
6520#endif /* HAVE_SETREUID */
6521
6522#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006523PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006524"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006525Set the current process's real and effective group ids.");
6526
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006527static PyObject *
6528posix_setregid (PyObject *self, PyObject *args)
6529{
Victor Stinner8c62be82010-05-06 00:08:46 +00006530 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006531 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6532 _Py_Gid_Converter, &rgid,
6533 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006534 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006535 if (setregid(rgid, egid) < 0) {
6536 return posix_error();
6537 } else {
6538 Py_INCREF(Py_None);
6539 return Py_None;
6540 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006541}
6542#endif /* HAVE_SETREGID */
6543
Guido van Rossumb6775db1994-08-01 11:34:53 +00006544#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006545PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006546"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006547Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006548
Barry Warsaw53699e91996-12-10 23:23:01 +00006549static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006550posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006551{
Victor Stinner8c62be82010-05-06 00:08:46 +00006552 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006553 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006555 if (setgid(gid) < 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_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006561
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006562#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006563PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006564"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006565Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006566
6567static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006568posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006569{
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 int i, len;
6571 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006572
Victor Stinner8c62be82010-05-06 00:08:46 +00006573 if (!PySequence_Check(groups)) {
6574 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6575 return NULL;
6576 }
6577 len = PySequence_Size(groups);
6578 if (len > MAX_GROUPS) {
6579 PyErr_SetString(PyExc_ValueError, "too many groups");
6580 return NULL;
6581 }
6582 for(i = 0; i < len; i++) {
6583 PyObject *elem;
6584 elem = PySequence_GetItem(groups, i);
6585 if (!elem)
6586 return NULL;
6587 if (!PyLong_Check(elem)) {
6588 PyErr_SetString(PyExc_TypeError,
6589 "groups must be integers");
6590 Py_DECREF(elem);
6591 return NULL;
6592 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006593 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006594 Py_DECREF(elem);
6595 return NULL;
6596 }
6597 }
6598 Py_DECREF(elem);
6599 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006600
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 if (setgroups(len, grouplist) < 0)
6602 return posix_error();
6603 Py_INCREF(Py_None);
6604 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006605}
6606#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006607
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006608#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6609static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006610wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006611{
Victor Stinner8c62be82010-05-06 00:08:46 +00006612 PyObject *result;
6613 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006614 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006615
Victor Stinner8c62be82010-05-06 00:08:46 +00006616 if (pid == -1)
6617 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006618
Victor Stinner8c62be82010-05-06 00:08:46 +00006619 if (struct_rusage == NULL) {
6620 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6621 if (m == NULL)
6622 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006623 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006624 Py_DECREF(m);
6625 if (struct_rusage == NULL)
6626 return NULL;
6627 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006628
Victor Stinner8c62be82010-05-06 00:08:46 +00006629 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6630 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6631 if (!result)
6632 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006633
6634#ifndef doubletime
6635#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6636#endif
6637
Victor Stinner8c62be82010-05-06 00:08:46 +00006638 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006639 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006640 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006641 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006642#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006643 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6644 SET_INT(result, 2, ru->ru_maxrss);
6645 SET_INT(result, 3, ru->ru_ixrss);
6646 SET_INT(result, 4, ru->ru_idrss);
6647 SET_INT(result, 5, ru->ru_isrss);
6648 SET_INT(result, 6, ru->ru_minflt);
6649 SET_INT(result, 7, ru->ru_majflt);
6650 SET_INT(result, 8, ru->ru_nswap);
6651 SET_INT(result, 9, ru->ru_inblock);
6652 SET_INT(result, 10, ru->ru_oublock);
6653 SET_INT(result, 11, ru->ru_msgsnd);
6654 SET_INT(result, 12, ru->ru_msgrcv);
6655 SET_INT(result, 13, ru->ru_nsignals);
6656 SET_INT(result, 14, ru->ru_nvcsw);
6657 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006658#undef SET_INT
6659
Victor Stinner8c62be82010-05-06 00:08:46 +00006660 if (PyErr_Occurred()) {
6661 Py_DECREF(result);
6662 return NULL;
6663 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006664
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006666}
6667#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6668
6669#ifdef HAVE_WAIT3
6670PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006671"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006672Wait for completion of a child process.");
6673
6674static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006675posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006676{
Victor Stinner8c62be82010-05-06 00:08:46 +00006677 pid_t pid;
6678 int options;
6679 struct rusage ru;
6680 WAIT_TYPE status;
6681 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006682
Victor Stinner4195b5c2012-02-08 23:03:19 +01006683 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006684 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006685
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 Py_BEGIN_ALLOW_THREADS
6687 pid = wait3(&status, options, &ru);
6688 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006689
Victor Stinner4195b5c2012-02-08 23:03:19 +01006690 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006691}
6692#endif /* HAVE_WAIT3 */
6693
6694#ifdef HAVE_WAIT4
6695PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006696"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006697Wait for completion of a given child process.");
6698
6699static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006700posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006701{
Victor Stinner8c62be82010-05-06 00:08:46 +00006702 pid_t pid;
6703 int options;
6704 struct rusage ru;
6705 WAIT_TYPE status;
6706 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006707
Victor Stinner4195b5c2012-02-08 23:03:19 +01006708 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006709 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006710
Victor Stinner8c62be82010-05-06 00:08:46 +00006711 Py_BEGIN_ALLOW_THREADS
6712 pid = wait4(pid, &status, options, &ru);
6713 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006714
Victor Stinner4195b5c2012-02-08 23:03:19 +01006715 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006716}
6717#endif /* HAVE_WAIT4 */
6718
Ross Lagerwall7807c352011-03-17 20:20:30 +02006719#if defined(HAVE_WAITID) && !defined(__APPLE__)
6720PyDoc_STRVAR(posix_waitid__doc__,
6721"waitid(idtype, id, options) -> waitid_result\n\n\
6722Wait for the completion of one or more child processes.\n\n\
6723idtype can be P_PID, P_PGID or P_ALL.\n\
6724id specifies the pid to wait on.\n\
6725options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6726or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6727Returns either waitid_result or None if WNOHANG is specified and there are\n\
6728no children in a waitable state.");
6729
6730static PyObject *
6731posix_waitid(PyObject *self, PyObject *args)
6732{
6733 PyObject *result;
6734 idtype_t idtype;
6735 id_t id;
6736 int options, res;
6737 siginfo_t si;
6738 si.si_pid = 0;
6739 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6740 return NULL;
6741 Py_BEGIN_ALLOW_THREADS
6742 res = waitid(idtype, id, &si, options);
6743 Py_END_ALLOW_THREADS
6744 if (res == -1)
6745 return posix_error();
6746
6747 if (si.si_pid == 0)
6748 Py_RETURN_NONE;
6749
6750 result = PyStructSequence_New(&WaitidResultType);
6751 if (!result)
6752 return NULL;
6753
6754 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006755 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006756 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6757 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6758 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6759 if (PyErr_Occurred()) {
6760 Py_DECREF(result);
6761 return NULL;
6762 }
6763
6764 return result;
6765}
6766#endif
6767
Guido van Rossumb6775db1994-08-01 11:34:53 +00006768#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006769PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006770"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006771Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006772
Barry Warsaw53699e91996-12-10 23:23:01 +00006773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006774posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006775{
Victor Stinner8c62be82010-05-06 00:08:46 +00006776 pid_t pid;
6777 int options;
6778 WAIT_TYPE status;
6779 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006780
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6782 return NULL;
6783 Py_BEGIN_ALLOW_THREADS
6784 pid = waitpid(pid, &status, options);
6785 Py_END_ALLOW_THREADS
6786 if (pid == -1)
6787 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006788
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006790}
6791
Tim Petersab034fa2002-02-01 11:27:43 +00006792#elif defined(HAVE_CWAIT)
6793
6794/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006795PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006796"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006797"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006798
6799static PyObject *
6800posix_waitpid(PyObject *self, PyObject *args)
6801{
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 Py_intptr_t pid;
6803 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006804
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006805 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 return NULL;
6807 Py_BEGIN_ALLOW_THREADS
6808 pid = _cwait(&status, pid, options);
6809 Py_END_ALLOW_THREADS
6810 if (pid == -1)
6811 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006812
Victor Stinner8c62be82010-05-06 00:08:46 +00006813 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006814 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006815}
6816#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006817
Guido van Rossumad0ee831995-03-01 10:34:45 +00006818#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006819PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006820"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006821Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006822
Barry Warsaw53699e91996-12-10 23:23:01 +00006823static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006824posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006825{
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 pid_t pid;
6827 WAIT_TYPE status;
6828 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006829
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 Py_BEGIN_ALLOW_THREADS
6831 pid = wait(&status);
6832 Py_END_ALLOW_THREADS
6833 if (pid == -1)
6834 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006835
Victor Stinner8c62be82010-05-06 00:08:46 +00006836 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006837}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006838#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006839
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006840
Larry Hastings9cf065c2012-06-22 16:30:09 -07006841#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6842PyDoc_STRVAR(readlink__doc__,
6843"readlink(path, *, dir_fd=None) -> path\n\n\
6844Return a string representing the path to which the symbolic link points.\n\
6845\n\
6846If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6847 and path should be relative; path will then be relative to that directory.\n\
6848dir_fd may not be implemented on your platform.\n\
6849 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006850#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006851
Guido van Rossumb6775db1994-08-01 11:34:53 +00006852#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006853
Barry Warsaw53699e91996-12-10 23:23:01 +00006854static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006855posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006856{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006857 path_t path;
6858 int dir_fd = DEFAULT_DIR_FD;
6859 char buffer[MAXPATHLEN];
6860 ssize_t length;
6861 PyObject *return_value = NULL;
6862 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006863
Larry Hastings9cf065c2012-06-22 16:30:09 -07006864 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01006865 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006866 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6867 path_converter, &path,
6868#ifdef HAVE_READLINKAT
6869 dir_fd_converter, &dir_fd
6870#else
6871 dir_fd_unavailable, &dir_fd
6872#endif
6873 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006875
Victor Stinner8c62be82010-05-06 00:08:46 +00006876 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006877#ifdef HAVE_READLINKAT
6878 if (dir_fd != DEFAULT_DIR_FD)
6879 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006880 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006881#endif
6882 length = readlink(path.narrow, buffer, sizeof(buffer));
6883 Py_END_ALLOW_THREADS
6884
6885 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01006886 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006887 goto exit;
6888 }
6889
6890 if (PyUnicode_Check(path.object))
6891 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6892 else
6893 return_value = PyBytes_FromStringAndSize(buffer, length);
6894exit:
6895 path_cleanup(&path);
6896 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006897}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006898
6899
Guido van Rossumb6775db1994-08-01 11:34:53 +00006900#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006901
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006902
Larry Hastings9cf065c2012-06-22 16:30:09 -07006903#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006904PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006905"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
6906Create a symbolic link pointing to src named dst.\n\n\
6907target_is_directory is required on Windows if the target is to be\n\
6908 interpreted as a directory. (On Windows, symlink requires\n\
6909 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
6910 target_is_directory is ignored on non-Windows platforms.\n\
6911\n\
6912If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6913 and path should be relative; path will then be relative to that directory.\n\
6914dir_fd may not be implemented on your platform.\n\
6915 If it is unavailable, using it will raise a NotImplementedError.");
6916
6917#if defined(MS_WINDOWS)
6918
6919/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6920static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
6921static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02006922
Larry Hastings9cf065c2012-06-22 16:30:09 -07006923static int
Victor Stinner31b3b922013-06-05 01:49:17 +02006924check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07006925{
6926 HINSTANCE hKernel32;
6927 /* only recheck */
6928 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
6929 return 1;
6930 hKernel32 = GetModuleHandleW(L"KERNEL32");
6931 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6932 "CreateSymbolicLinkW");
6933 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
6934 "CreateSymbolicLinkA");
6935 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
6936}
6937
Victor Stinner31b3b922013-06-05 01:49:17 +02006938/* Remove the last portion of the path */
6939static void
6940_dirnameW(WCHAR *path)
6941{
Jason R. Coombs3a092862013-05-27 23:21:28 -04006942 WCHAR *ptr;
6943
6944 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02006945 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02006946 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04006947 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04006948 }
6949 *ptr = 0;
6950}
6951
Victor Stinner31b3b922013-06-05 01:49:17 +02006952/* Remove the last portion of the path */
6953static void
6954_dirnameA(char *path)
6955{
Jason R. Coombs3a092862013-05-27 23:21:28 -04006956 char *ptr;
6957
6958 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02006959 for(ptr = path + strlen(path); ptr != path; ptr--) {
6960 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04006961 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04006962 }
6963 *ptr = 0;
6964}
6965
Victor Stinner31b3b922013-06-05 01:49:17 +02006966/* Is this path absolute? */
6967static int
6968_is_absW(const WCHAR *path)
6969{
Jason R. Coombs3a092862013-05-27 23:21:28 -04006970 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
6971
6972}
6973
Victor Stinner31b3b922013-06-05 01:49:17 +02006974/* Is this path absolute? */
6975static int
6976_is_absA(const char *path)
6977{
Jason R. Coombs3a092862013-05-27 23:21:28 -04006978 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
6979
6980}
6981
Victor Stinner31b3b922013-06-05 01:49:17 +02006982/* join root and rest with a backslash */
6983static void
6984_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
6985{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02006986 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04006987
Victor Stinner31b3b922013-06-05 01:49:17 +02006988 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04006989 wcscpy(dest_path, rest);
6990 return;
6991 }
6992
6993 root_len = wcslen(root);
6994
6995 wcscpy(dest_path, root);
6996 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02006997 dest_path[root_len] = L'\\';
6998 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04006999 }
7000 wcscpy(dest_path+root_len, rest);
7001}
7002
Victor Stinner31b3b922013-06-05 01:49:17 +02007003/* join root and rest with a backslash */
7004static void
7005_joinA(char *dest_path, const char *root, const char *rest)
7006{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007007 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007008
Victor Stinner31b3b922013-06-05 01:49:17 +02007009 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007010 strcpy(dest_path, rest);
7011 return;
7012 }
7013
7014 root_len = strlen(root);
7015
7016 strcpy(dest_path, root);
7017 if(root_len) {
7018 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007019 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007020 }
7021 strcpy(dest_path+root_len, rest);
7022}
7023
Victor Stinner31b3b922013-06-05 01:49:17 +02007024/* Return True if the path at src relative to dest is a directory */
7025static int
7026_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007027{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007028 WIN32_FILE_ATTRIBUTE_DATA src_info;
7029 WCHAR dest_parent[MAX_PATH];
7030 WCHAR src_resolved[MAX_PATH] = L"";
7031
7032 /* dest_parent = os.path.dirname(dest) */
7033 wcscpy(dest_parent, dest);
7034 _dirnameW(dest_parent);
7035 /* src_resolved = os.path.join(dest_parent, src) */
7036 _joinW(src_resolved, dest_parent, src);
7037 return (
7038 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7039 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7040 );
7041}
7042
Victor Stinner31b3b922013-06-05 01:49:17 +02007043/* Return True if the path at src relative to dest is a directory */
7044static int
7045_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007046{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007047 WIN32_FILE_ATTRIBUTE_DATA src_info;
7048 char dest_parent[MAX_PATH];
7049 char src_resolved[MAX_PATH] = "";
7050
7051 /* dest_parent = os.path.dirname(dest) */
7052 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007053 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007054 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007055 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007056 return (
7057 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7058 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7059 );
7060}
7061
Larry Hastings9cf065c2012-06-22 16:30:09 -07007062#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007063
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007064static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007065posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007066{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007067 path_t src;
7068 path_t dst;
7069 int dir_fd = DEFAULT_DIR_FD;
7070 int target_is_directory = 0;
7071 static char *keywords[] = {"src", "dst", "target_is_directory",
7072 "dir_fd", NULL};
7073 PyObject *return_value;
7074#ifdef MS_WINDOWS
7075 DWORD result;
7076#else
7077 int result;
7078#endif
7079
7080 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007081 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007082 src.argument_name = "src";
7083 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007084 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007085 dst.argument_name = "dst";
7086
7087#ifdef MS_WINDOWS
7088 if (!check_CreateSymbolicLink()) {
7089 PyErr_SetString(PyExc_NotImplementedError,
7090 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007091 return NULL;
7092 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007093 if (!win32_can_symlink) {
7094 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007095 return NULL;
7096 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007097#endif
7098
7099 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7100 keywords,
7101 path_converter, &src,
7102 path_converter, &dst,
7103 &target_is_directory,
7104#ifdef HAVE_SYMLINKAT
7105 dir_fd_converter, &dir_fd
7106#else
7107 dir_fd_unavailable, &dir_fd
7108#endif
7109 ))
7110 return NULL;
7111
7112 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7113 PyErr_SetString(PyExc_ValueError,
7114 "symlink: src and dst must be the same type");
7115 return_value = NULL;
7116 goto exit;
7117 }
7118
7119#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007120
Larry Hastings9cf065c2012-06-22 16:30:09 -07007121 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007122 if (dst.wide) {
7123 /* if src is a directory, ensure target_is_directory==1 */
7124 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007125 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7126 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007127 }
7128 else {
7129 /* if src is a directory, ensure target_is_directory==1 */
7130 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007131 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7132 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007133 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007134 Py_END_ALLOW_THREADS
7135
7136 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01007137 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007138 goto exit;
7139 }
7140
7141#else
7142
7143 Py_BEGIN_ALLOW_THREADS
7144#if HAVE_SYMLINKAT
7145 if (dir_fd != DEFAULT_DIR_FD)
7146 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7147 else
7148#endif
7149 result = symlink(src.narrow, dst.narrow);
7150 Py_END_ALLOW_THREADS
7151
7152 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01007153 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007154 goto exit;
7155 }
7156#endif
7157
7158 return_value = Py_None;
7159 Py_INCREF(Py_None);
7160 goto exit; /* silence "unused label" warning */
7161exit:
7162 path_cleanup(&src);
7163 path_cleanup(&dst);
7164 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007165}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007166
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007167#endif /* HAVE_SYMLINK */
7168
Larry Hastings9cf065c2012-06-22 16:30:09 -07007169
Brian Curtind40e6f72010-07-08 21:39:08 +00007170#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7171
Brian Curtind40e6f72010-07-08 21:39:08 +00007172static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007173win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007174{
7175 wchar_t *path;
7176 DWORD n_bytes_returned;
7177 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007178 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007179 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007180 HANDLE reparse_point_handle;
7181
7182 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7183 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7184 wchar_t *print_name;
7185
Larry Hastings9cf065c2012-06-22 16:30:09 -07007186 static char *keywords[] = {"path", "dir_fd", NULL};
7187
7188 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7189 &po,
7190 dir_fd_unavailable, &dir_fd
7191 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007192 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007193
Victor Stinnereb5657a2011-09-30 01:44:27 +02007194 path = PyUnicode_AsUnicode(po);
7195 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007196 return NULL;
7197
7198 /* First get a handle to the reparse point */
7199 Py_BEGIN_ALLOW_THREADS
7200 reparse_point_handle = CreateFileW(
7201 path,
7202 0,
7203 0,
7204 0,
7205 OPEN_EXISTING,
7206 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7207 0);
7208 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007209
Brian Curtind40e6f72010-07-08 21:39:08 +00007210 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007211 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007212
Brian Curtind40e6f72010-07-08 21:39:08 +00007213 Py_BEGIN_ALLOW_THREADS
7214 /* New call DeviceIoControl to read the reparse point */
7215 io_result = DeviceIoControl(
7216 reparse_point_handle,
7217 FSCTL_GET_REPARSE_POINT,
7218 0, 0, /* in buffer */
7219 target_buffer, sizeof(target_buffer),
7220 &n_bytes_returned,
7221 0 /* we're not using OVERLAPPED_IO */
7222 );
7223 CloseHandle(reparse_point_handle);
7224 Py_END_ALLOW_THREADS
7225
7226 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007227 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007228
7229 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7230 {
7231 PyErr_SetString(PyExc_ValueError,
7232 "not a symbolic link");
7233 return NULL;
7234 }
Brian Curtin74e45612010-07-09 15:58:59 +00007235 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7236 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7237
7238 result = PyUnicode_FromWideChar(print_name,
7239 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007240 return result;
7241}
7242
7243#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7244
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007245
Larry Hastings605a62d2012-06-24 04:33:36 -07007246static PyStructSequence_Field times_result_fields[] = {
7247 {"user", "user time"},
7248 {"system", "system time"},
7249 {"children_user", "user time of children"},
7250 {"children_system", "system time of children"},
7251 {"elapsed", "elapsed time since an arbitrary point in the past"},
7252 {NULL}
7253};
7254
7255PyDoc_STRVAR(times_result__doc__,
7256"times_result: Result from os.times().\n\n\
7257This object may be accessed either as a tuple of\n\
7258 (user, system, children_user, children_system, elapsed),\n\
7259or via the attributes user, system, children_user, children_system,\n\
7260and elapsed.\n\
7261\n\
7262See os.times for more information.");
7263
7264static PyStructSequence_Desc times_result_desc = {
7265 "times_result", /* name */
7266 times_result__doc__, /* doc */
7267 times_result_fields,
7268 5
7269};
7270
7271static PyTypeObject TimesResultType;
7272
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007273#ifdef MS_WINDOWS
7274#define HAVE_TIMES /* mandatory, for the method table */
7275#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007276
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007277#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007278
7279static PyObject *
7280build_times_result(double user, double system,
7281 double children_user, double children_system,
7282 double elapsed)
7283{
7284 PyObject *value = PyStructSequence_New(&TimesResultType);
7285 if (value == NULL)
7286 return NULL;
7287
7288#define SET(i, field) \
7289 { \
7290 PyObject *o = PyFloat_FromDouble(field); \
7291 if (!o) { \
7292 Py_DECREF(value); \
7293 return NULL; \
7294 } \
7295 PyStructSequence_SET_ITEM(value, i, o); \
7296 } \
7297
7298 SET(0, user);
7299 SET(1, system);
7300 SET(2, children_user);
7301 SET(3, children_system);
7302 SET(4, elapsed);
7303
7304#undef SET
7305
7306 return value;
7307}
7308
7309PyDoc_STRVAR(posix_times__doc__,
7310"times() -> times_result\n\n\
7311Return an object containing floating point numbers indicating process\n\
7312times. The object behaves like a named tuple with these fields:\n\
7313 (utime, stime, cutime, cstime, elapsed_time)");
7314
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007315#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007316static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007317posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007318{
Victor Stinner8c62be82010-05-06 00:08:46 +00007319 FILETIME create, exit, kernel, user;
7320 HANDLE hProc;
7321 hProc = GetCurrentProcess();
7322 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7323 /* The fields of a FILETIME structure are the hi and lo part
7324 of a 64-bit value expressed in 100 nanosecond units.
7325 1e7 is one second in such units; 1e-7 the inverse.
7326 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7327 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007328 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007329 (double)(user.dwHighDateTime*429.4967296 +
7330 user.dwLowDateTime*1e-7),
7331 (double)(kernel.dwHighDateTime*429.4967296 +
7332 kernel.dwLowDateTime*1e-7),
7333 (double)0,
7334 (double)0,
7335 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007336}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007337#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007338#define NEED_TICKS_PER_SECOND
7339static long ticks_per_second = -1;
7340static PyObject *
7341posix_times(PyObject *self, PyObject *noargs)
7342{
7343 struct tms t;
7344 clock_t c;
7345 errno = 0;
7346 c = times(&t);
7347 if (c == (clock_t) -1)
7348 return posix_error();
7349 return build_times_result(
7350 (double)t.tms_utime / ticks_per_second,
7351 (double)t.tms_stime / ticks_per_second,
7352 (double)t.tms_cutime / ticks_per_second,
7353 (double)t.tms_cstime / ticks_per_second,
7354 (double)c / ticks_per_second);
7355}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007356#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007357
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007358#endif /* HAVE_TIMES */
7359
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007360
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007361#ifdef HAVE_GETSID
7362PyDoc_STRVAR(posix_getsid__doc__,
7363"getsid(pid) -> sid\n\n\
7364Call the system call getsid().");
7365
7366static PyObject *
7367posix_getsid(PyObject *self, PyObject *args)
7368{
Victor Stinner8c62be82010-05-06 00:08:46 +00007369 pid_t pid;
7370 int sid;
7371 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7372 return NULL;
7373 sid = getsid(pid);
7374 if (sid < 0)
7375 return posix_error();
7376 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007377}
7378#endif /* HAVE_GETSID */
7379
7380
Guido van Rossumb6775db1994-08-01 11:34:53 +00007381#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007382PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007383"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007384Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007385
Barry Warsaw53699e91996-12-10 23:23:01 +00007386static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007387posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007388{
Victor Stinner8c62be82010-05-06 00:08:46 +00007389 if (setsid() < 0)
7390 return posix_error();
7391 Py_INCREF(Py_None);
7392 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007393}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007394#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007395
Guido van Rossumb6775db1994-08-01 11:34:53 +00007396#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007397PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007398"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007399Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007400
Barry Warsaw53699e91996-12-10 23:23:01 +00007401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007402posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007403{
Victor Stinner8c62be82010-05-06 00:08:46 +00007404 pid_t pid;
7405 int pgrp;
7406 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7407 return NULL;
7408 if (setpgid(pid, pgrp) < 0)
7409 return posix_error();
7410 Py_INCREF(Py_None);
7411 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007412}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007413#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007414
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007415
Guido van Rossumb6775db1994-08-01 11:34:53 +00007416#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007417PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007418"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007419Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007420
Barry Warsaw53699e91996-12-10 23:23:01 +00007421static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007422posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007423{
Victor Stinner8c62be82010-05-06 00:08:46 +00007424 int fd;
7425 pid_t pgid;
7426 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7427 return NULL;
7428 pgid = tcgetpgrp(fd);
7429 if (pgid < 0)
7430 return posix_error();
7431 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007432}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007433#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007434
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007435
Guido van Rossumb6775db1994-08-01 11:34:53 +00007436#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007437PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007438"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007439Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007440
Barry Warsaw53699e91996-12-10 23:23:01 +00007441static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007442posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007443{
Victor Stinner8c62be82010-05-06 00:08:46 +00007444 int fd;
7445 pid_t pgid;
7446 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7447 return NULL;
7448 if (tcsetpgrp(fd, pgid) < 0)
7449 return posix_error();
7450 Py_INCREF(Py_None);
7451 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007452}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007453#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007454
Guido van Rossum687dd131993-05-17 08:34:16 +00007455/* Functions acting on file descriptors */
7456
Victor Stinnerdaf45552013-08-28 00:53:59 +02007457#ifdef O_CLOEXEC
7458extern int _Py_open_cloexec_works;
7459#endif
7460
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007461PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007462"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7463Open a file for low level IO. Returns a file handle (integer).\n\
7464\n\
7465If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7466 and path should be relative; path will then be relative to that directory.\n\
7467dir_fd may not be implemented on your platform.\n\
7468 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007469
Barry Warsaw53699e91996-12-10 23:23:01 +00007470static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007471posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007472{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007473 path_t path;
7474 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007475 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007476 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007477 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007478 PyObject *return_value = NULL;
7479 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Victor Stinnerdaf45552013-08-28 00:53:59 +02007480#ifdef O_CLOEXEC
7481 int *atomic_flag_works = &_Py_open_cloexec_works;
7482#elif !defined(MS_WINDOWS)
7483 int *atomic_flag_works = NULL;
7484#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007485
Larry Hastings9cf065c2012-06-22 16:30:09 -07007486 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007487 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007488 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7489 path_converter, &path,
7490 &flags, &mode,
7491#ifdef HAVE_OPENAT
7492 dir_fd_converter, &dir_fd
7493#else
7494 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007495#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007496 ))
7497 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007498
Victor Stinnerdaf45552013-08-28 00:53:59 +02007499#ifdef MS_WINDOWS
7500 flags |= O_NOINHERIT;
7501#elif defined(O_CLOEXEC)
7502 flags |= O_CLOEXEC;
7503#endif
7504
Victor Stinner8c62be82010-05-06 00:08:46 +00007505 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007506#ifdef MS_WINDOWS
7507 if (path.wide)
7508 fd = _wopen(path.wide, flags, mode);
7509 else
7510#endif
7511#ifdef HAVE_OPENAT
7512 if (dir_fd != DEFAULT_DIR_FD)
7513 fd = openat(dir_fd, path.narrow, flags, mode);
7514 else
7515#endif
7516 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007517 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007518
Larry Hastings9cf065c2012-06-22 16:30:09 -07007519 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007520 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007521 goto exit;
7522 }
7523
Victor Stinnerdaf45552013-08-28 00:53:59 +02007524#ifndef MS_WINDOWS
7525 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7526 close(fd);
7527 goto exit;
7528 }
7529#endif
7530
Larry Hastings9cf065c2012-06-22 16:30:09 -07007531 return_value = PyLong_FromLong((long)fd);
7532
7533exit:
7534 path_cleanup(&path);
7535 return return_value;
7536}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007537
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007538PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007539"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007540Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007541
Barry Warsaw53699e91996-12-10 23:23:01 +00007542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007543posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007544{
Victor Stinner8c62be82010-05-06 00:08:46 +00007545 int fd, res;
7546 if (!PyArg_ParseTuple(args, "i:close", &fd))
7547 return NULL;
7548 if (!_PyVerify_fd(fd))
7549 return posix_error();
7550 Py_BEGIN_ALLOW_THREADS
7551 res = close(fd);
7552 Py_END_ALLOW_THREADS
7553 if (res < 0)
7554 return posix_error();
7555 Py_INCREF(Py_None);
7556 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007557}
7558
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007559
Victor Stinner8c62be82010-05-06 00:08:46 +00007560PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007561"closerange(fd_low, fd_high)\n\n\
7562Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7563
7564static PyObject *
7565posix_closerange(PyObject *self, PyObject *args)
7566{
Victor Stinner8c62be82010-05-06 00:08:46 +00007567 int fd_from, fd_to, i;
7568 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7569 return NULL;
7570 Py_BEGIN_ALLOW_THREADS
7571 for (i = fd_from; i < fd_to; i++)
7572 if (_PyVerify_fd(i))
7573 close(i);
7574 Py_END_ALLOW_THREADS
7575 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007576}
7577
7578
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007579PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007580"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007581Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007582
Barry Warsaw53699e91996-12-10 23:23:01 +00007583static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007584posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007585{
Victor Stinner8c62be82010-05-06 00:08:46 +00007586 int fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007587
Victor Stinner8c62be82010-05-06 00:08:46 +00007588 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7589 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007590
7591 fd = _Py_dup(fd);
7592 if (fd == -1)
7593 return NULL;
7594
Victor Stinner8c62be82010-05-06 00:08:46 +00007595 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007596}
7597
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007598
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007599PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007600"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007601Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007602
Barry Warsaw53699e91996-12-10 23:23:01 +00007603static PyObject *
Victor Stinnerdaf45552013-08-28 00:53:59 +02007604posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007605{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007606 static char *keywords[] = {"fd", "fd2", "inheritable", NULL};
7607 int fd, fd2;
7608 int inheritable = 1;
7609 int res;
7610#if defined(HAVE_DUP3) && \
7611 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7612 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7613 int dup3_works = -1;
7614#endif
7615
7616 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords,
7617 &fd, &fd2, &inheritable))
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007619
Victor Stinner8c62be82010-05-06 00:08:46 +00007620 if (!_PyVerify_fd_dup2(fd, fd2))
7621 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007622
7623#ifdef MS_WINDOWS
7624 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007625 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007626 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007627 if (res < 0)
7628 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007629
7630 /* Character files like console cannot be make non-inheritable */
7631 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7632 close(fd2);
7633 return NULL;
7634 }
7635
7636#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7637 Py_BEGIN_ALLOW_THREADS
7638 if (!inheritable)
7639 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7640 else
7641 res = dup2(fd, fd2);
7642 Py_END_ALLOW_THREADS
7643 if (res < 0)
7644 return posix_error();
7645
7646#else
7647
7648#ifdef HAVE_DUP3
7649 if (!inheritable && dup3_works != 0) {
7650 Py_BEGIN_ALLOW_THREADS
7651 res = dup3(fd, fd2, O_CLOEXEC);
7652 Py_END_ALLOW_THREADS
7653 if (res < 0) {
7654 if (dup3_works == -1)
7655 dup3_works = (errno != ENOSYS);
7656 if (dup3_works)
7657 return posix_error();
7658 }
7659 }
7660
7661 if (inheritable || dup3_works == 0)
7662 {
7663#endif
7664 Py_BEGIN_ALLOW_THREADS
7665 res = dup2(fd, fd2);
7666 Py_END_ALLOW_THREADS
7667 if (res < 0)
7668 return posix_error();
7669
7670 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7671 close(fd2);
7672 return NULL;
7673 }
7674#ifdef HAVE_DUP3
7675 }
7676#endif
7677
7678#endif
7679
Victor Stinner8c62be82010-05-06 00:08:46 +00007680 Py_INCREF(Py_None);
7681 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007682}
7683
Ross Lagerwall7807c352011-03-17 20:20:30 +02007684#ifdef HAVE_LOCKF
7685PyDoc_STRVAR(posix_lockf__doc__,
7686"lockf(fd, cmd, len)\n\n\
7687Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7688fd is an open file descriptor.\n\
7689cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7690F_TEST.\n\
7691len specifies the section of the file to lock.");
7692
7693static PyObject *
7694posix_lockf(PyObject *self, PyObject *args)
7695{
7696 int fd, cmd, res;
7697 off_t len;
7698 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7699 &fd, &cmd, _parse_off_t, &len))
7700 return NULL;
7701
7702 Py_BEGIN_ALLOW_THREADS
7703 res = lockf(fd, cmd, len);
7704 Py_END_ALLOW_THREADS
7705
7706 if (res < 0)
7707 return posix_error();
7708
7709 Py_RETURN_NONE;
7710}
7711#endif
7712
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007713
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007714PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007715"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007716Set the current position of a file descriptor.\n\
7717Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007718
Barry Warsaw53699e91996-12-10 23:23:01 +00007719static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007720posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007721{
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007723#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007724 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007725#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007726 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007727#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007728 PyObject *posobj;
7729 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007730 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007731#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007732 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7733 switch (how) {
7734 case 0: how = SEEK_SET; break;
7735 case 1: how = SEEK_CUR; break;
7736 case 2: how = SEEK_END; break;
7737 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007738#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007739
Ross Lagerwall8e749672011-03-17 21:54:07 +02007740#if !defined(HAVE_LARGEFILE_SUPPORT)
7741 pos = PyLong_AsLong(posobj);
7742#else
7743 pos = PyLong_AsLongLong(posobj);
7744#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007745 if (PyErr_Occurred())
7746 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007747
Victor Stinner8c62be82010-05-06 00:08:46 +00007748 if (!_PyVerify_fd(fd))
7749 return posix_error();
7750 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02007751#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007752 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007753#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007755#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007756 Py_END_ALLOW_THREADS
7757 if (res < 0)
7758 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007759
7760#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007761 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007762#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007763 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007764#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007765}
7766
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007767
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007768PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07007769"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007770Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007771
Barry Warsaw53699e91996-12-10 23:23:01 +00007772static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007773posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007774{
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 int fd, size;
7776 Py_ssize_t n;
7777 PyObject *buffer;
7778 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7779 return NULL;
7780 if (size < 0) {
7781 errno = EINVAL;
7782 return posix_error();
7783 }
7784 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7785 if (buffer == NULL)
7786 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007787 if (!_PyVerify_fd(fd)) {
7788 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007789 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007790 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 Py_BEGIN_ALLOW_THREADS
7792 n = read(fd, PyBytes_AS_STRING(buffer), size);
7793 Py_END_ALLOW_THREADS
7794 if (n < 0) {
7795 Py_DECREF(buffer);
7796 return posix_error();
7797 }
7798 if (n != size)
7799 _PyBytes_Resize(&buffer, n);
7800 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007801}
7802
Ross Lagerwall7807c352011-03-17 20:20:30 +02007803#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7804 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007805static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007806iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7807{
7808 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007809 Py_ssize_t blen, total = 0;
7810
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007811 *iov = PyMem_New(struct iovec, cnt);
7812 if (*iov == NULL) {
7813 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007814 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007815 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007816
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007817 *buf = PyMem_New(Py_buffer, cnt);
7818 if (*buf == NULL) {
7819 PyMem_Del(*iov);
7820 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007821 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007822 }
7823
7824 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007825 PyObject *item = PySequence_GetItem(seq, i);
7826 if (item == NULL)
7827 goto fail;
7828 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7829 Py_DECREF(item);
7830 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007831 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007832 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007833 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007834 blen = (*buf)[i].len;
7835 (*iov)[i].iov_len = blen;
7836 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007837 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007838 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007839
7840fail:
7841 PyMem_Del(*iov);
7842 for (j = 0; j < i; j++) {
7843 PyBuffer_Release(&(*buf)[j]);
7844 }
7845 PyMem_Del(*buf);
7846 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007847}
7848
7849static void
7850iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7851{
7852 int i;
7853 PyMem_Del(iov);
7854 for (i = 0; i < cnt; i++) {
7855 PyBuffer_Release(&buf[i]);
7856 }
7857 PyMem_Del(buf);
7858}
7859#endif
7860
Ross Lagerwall7807c352011-03-17 20:20:30 +02007861#ifdef HAVE_READV
7862PyDoc_STRVAR(posix_readv__doc__,
7863"readv(fd, buffers) -> bytesread\n\n\
7864Read from a file descriptor into a number of writable buffers. buffers\n\
7865is an arbitrary sequence of writable buffers.\n\
7866Returns the total number of bytes read.");
7867
7868static PyObject *
7869posix_readv(PyObject *self, PyObject *args)
7870{
7871 int fd, cnt;
7872 Py_ssize_t n;
7873 PyObject *seq;
7874 struct iovec *iov;
7875 Py_buffer *buf;
7876
7877 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7878 return NULL;
7879 if (!PySequence_Check(seq)) {
7880 PyErr_SetString(PyExc_TypeError,
7881 "readv() arg 2 must be a sequence");
7882 return NULL;
7883 }
7884 cnt = PySequence_Size(seq);
7885
7886 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7887 return NULL;
7888
7889 Py_BEGIN_ALLOW_THREADS
7890 n = readv(fd, iov, cnt);
7891 Py_END_ALLOW_THREADS
7892
7893 iov_cleanup(iov, buf, cnt);
7894 return PyLong_FromSsize_t(n);
7895}
7896#endif
7897
7898#ifdef HAVE_PREAD
7899PyDoc_STRVAR(posix_pread__doc__,
7900"pread(fd, buffersize, offset) -> string\n\n\
7901Read from a file descriptor, fd, at a position of offset. It will read up\n\
7902to buffersize number of bytes. The file offset remains unchanged.");
7903
7904static PyObject *
7905posix_pread(PyObject *self, PyObject *args)
7906{
7907 int fd, size;
7908 off_t offset;
7909 Py_ssize_t n;
7910 PyObject *buffer;
7911 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7912 return NULL;
7913
7914 if (size < 0) {
7915 errno = EINVAL;
7916 return posix_error();
7917 }
7918 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7919 if (buffer == NULL)
7920 return NULL;
7921 if (!_PyVerify_fd(fd)) {
7922 Py_DECREF(buffer);
7923 return posix_error();
7924 }
7925 Py_BEGIN_ALLOW_THREADS
7926 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7927 Py_END_ALLOW_THREADS
7928 if (n < 0) {
7929 Py_DECREF(buffer);
7930 return posix_error();
7931 }
7932 if (n != size)
7933 _PyBytes_Resize(&buffer, n);
7934 return buffer;
7935}
7936#endif
7937
7938PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07007939"write(fd, data) -> byteswritten\n\n\
7940Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02007941
7942static PyObject *
7943posix_write(PyObject *self, PyObject *args)
7944{
7945 Py_buffer pbuf;
7946 int fd;
7947 Py_ssize_t size, len;
7948
7949 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7950 return NULL;
7951 if (!_PyVerify_fd(fd)) {
7952 PyBuffer_Release(&pbuf);
7953 return posix_error();
7954 }
7955 len = pbuf.len;
7956 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02007957#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02007958 if (len > INT_MAX)
7959 len = INT_MAX;
7960 size = write(fd, pbuf.buf, (int)len);
7961#else
7962 size = write(fd, pbuf.buf, len);
7963#endif
7964 Py_END_ALLOW_THREADS
7965 PyBuffer_Release(&pbuf);
7966 if (size < 0)
7967 return posix_error();
7968 return PyLong_FromSsize_t(size);
7969}
7970
7971#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007972PyDoc_STRVAR(posix_sendfile__doc__,
7973"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7974sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7975 -> byteswritten\n\
7976Copy nbytes bytes from file descriptor in to file descriptor out.");
7977
7978static PyObject *
7979posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7980{
7981 int in, out;
7982 Py_ssize_t ret;
7983 off_t offset;
7984
7985#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7986#ifndef __APPLE__
7987 Py_ssize_t len;
7988#endif
7989 PyObject *headers = NULL, *trailers = NULL;
7990 Py_buffer *hbuf, *tbuf;
7991 off_t sbytes;
7992 struct sf_hdtr sf;
7993 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007994 static char *keywords[] = {"out", "in",
7995 "offset", "count",
7996 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007997
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02007998 sf.headers = NULL;
7999 sf.trailers = NULL;
8000
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008001#ifdef __APPLE__
8002 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008003 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008004#else
8005 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008006 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008007#endif
8008 &headers, &trailers, &flags))
8009 return NULL;
8010 if (headers != NULL) {
8011 if (!PySequence_Check(headers)) {
8012 PyErr_SetString(PyExc_TypeError,
8013 "sendfile() headers must be a sequence or None");
8014 return NULL;
8015 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008016 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008017 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008018 if (sf.hdr_cnt > 0 &&
8019 !(i = iov_setup(&(sf.headers), &hbuf,
8020 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008021 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008022#ifdef __APPLE__
8023 sbytes += i;
8024#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008025 }
8026 }
8027 if (trailers != NULL) {
8028 if (!PySequence_Check(trailers)) {
8029 PyErr_SetString(PyExc_TypeError,
8030 "sendfile() trailers must be a sequence or None");
8031 return NULL;
8032 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008033 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008034 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008035 if (sf.trl_cnt > 0 &&
8036 !(i = iov_setup(&(sf.trailers), &tbuf,
8037 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008038 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008039#ifdef __APPLE__
8040 sbytes += i;
8041#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008042 }
8043 }
8044
8045 Py_BEGIN_ALLOW_THREADS
8046#ifdef __APPLE__
8047 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8048#else
8049 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8050#endif
8051 Py_END_ALLOW_THREADS
8052
8053 if (sf.headers != NULL)
8054 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8055 if (sf.trailers != NULL)
8056 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8057
8058 if (ret < 0) {
8059 if ((errno == EAGAIN) || (errno == EBUSY)) {
8060 if (sbytes != 0) {
8061 // some data has been sent
8062 goto done;
8063 }
8064 else {
8065 // no data has been sent; upper application is supposed
8066 // to retry on EAGAIN or EBUSY
8067 return posix_error();
8068 }
8069 }
8070 return posix_error();
8071 }
8072 goto done;
8073
8074done:
8075 #if !defined(HAVE_LARGEFILE_SUPPORT)
8076 return Py_BuildValue("l", sbytes);
8077 #else
8078 return Py_BuildValue("L", sbytes);
8079 #endif
8080
8081#else
8082 Py_ssize_t count;
8083 PyObject *offobj;
8084 static char *keywords[] = {"out", "in",
8085 "offset", "count", NULL};
8086 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8087 keywords, &out, &in, &offobj, &count))
8088 return NULL;
8089#ifdef linux
8090 if (offobj == Py_None) {
8091 Py_BEGIN_ALLOW_THREADS
8092 ret = sendfile(out, in, NULL, count);
8093 Py_END_ALLOW_THREADS
8094 if (ret < 0)
8095 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008096 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008097 }
8098#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008099 if (!_parse_off_t(offobj, &offset))
8100 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008101 Py_BEGIN_ALLOW_THREADS
8102 ret = sendfile(out, in, &offset, count);
8103 Py_END_ALLOW_THREADS
8104 if (ret < 0)
8105 return posix_error();
8106 return Py_BuildValue("n", ret);
8107#endif
8108}
8109#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008110
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008111PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008112"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008113Like stat(), but for an open file descriptor.\n\
8114Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008115
Barry Warsaw53699e91996-12-10 23:23:01 +00008116static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008117posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008118{
Victor Stinner8c62be82010-05-06 00:08:46 +00008119 int fd;
8120 STRUCT_STAT st;
8121 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008122 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008123 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008124#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008125 /* on OpenVMS we must ensure that all bytes are written to the file */
8126 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008127#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008128 Py_BEGIN_ALLOW_THREADS
8129 res = FSTAT(fd, &st);
8130 Py_END_ALLOW_THREADS
8131 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008132#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008133 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008134#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008135 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008136#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008137 }
Tim Peters5aa91602002-01-30 05:46:57 +00008138
Victor Stinner4195b5c2012-02-08 23:03:19 +01008139 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008140}
8141
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008142PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008143"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008144Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008145connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008146
8147static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008148posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008149{
Victor Stinner8c62be82010-05-06 00:08:46 +00008150 int fd;
8151 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8152 return NULL;
8153 if (!_PyVerify_fd(fd))
8154 return PyBool_FromLong(0);
8155 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008156}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008157
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008158#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008159PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008160"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008161Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008162
Barry Warsaw53699e91996-12-10 23:23:01 +00008163static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008164posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008165{
Victor Stinner8c62be82010-05-06 00:08:46 +00008166 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008167#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008168 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008169 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008170 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008171#else
8172 int res;
8173#endif
8174
8175#ifdef MS_WINDOWS
8176 attr.nLength = sizeof(attr);
8177 attr.lpSecurityDescriptor = NULL;
8178 attr.bInheritHandle = FALSE;
8179
8180 Py_BEGIN_ALLOW_THREADS
8181 ok = CreatePipe(&read, &write, &attr, 0);
8182 if (ok) {
8183 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8184 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8185 if (fds[0] == -1 || fds[1] == -1) {
8186 CloseHandle(read);
8187 CloseHandle(write);
8188 ok = 0;
8189 }
8190 }
8191 Py_END_ALLOW_THREADS
8192
Victor Stinner8c62be82010-05-06 00:08:46 +00008193 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008194 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008195#else
8196
8197#ifdef HAVE_PIPE2
8198 Py_BEGIN_ALLOW_THREADS
8199 res = pipe2(fds, O_CLOEXEC);
8200 Py_END_ALLOW_THREADS
8201
8202 if (res != 0 && errno == ENOSYS)
8203 {
8204#endif
8205 Py_BEGIN_ALLOW_THREADS
8206 res = pipe(fds);
8207 Py_END_ALLOW_THREADS
8208
8209 if (res == 0) {
8210 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8211 close(fds[0]);
8212 close(fds[1]);
8213 return NULL;
8214 }
8215 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8216 close(fds[0]);
8217 close(fds[1]);
8218 return NULL;
8219 }
8220 }
8221#ifdef HAVE_PIPE2
8222 }
8223#endif
8224
8225 if (res != 0)
8226 return PyErr_SetFromErrno(PyExc_OSError);
8227#endif /* !MS_WINDOWS */
8228 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008229}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008230#endif /* HAVE_PIPE */
8231
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008232#ifdef HAVE_PIPE2
8233PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008234"pipe2(flags) -> (read_end, write_end)\n\n\
8235Create a pipe with flags set atomically.\n\
8236flags can be constructed by ORing together one or more of these values:\n\
8237O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008238");
8239
8240static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008241posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008242{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008243 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008244 int fds[2];
8245 int res;
8246
Serhiy Storchaka78980432013-01-15 01:12:17 +02008247 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008248 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008249 return NULL;
8250
8251 res = pipe2(fds, flags);
8252 if (res != 0)
8253 return posix_error();
8254 return Py_BuildValue("(ii)", fds[0], fds[1]);
8255}
8256#endif /* HAVE_PIPE2 */
8257
Ross Lagerwall7807c352011-03-17 20:20:30 +02008258#ifdef HAVE_WRITEV
8259PyDoc_STRVAR(posix_writev__doc__,
8260"writev(fd, buffers) -> byteswritten\n\n\
8261Write the contents of buffers to a file descriptor, where buffers is an\n\
8262arbitrary sequence of buffers.\n\
8263Returns the total bytes written.");
8264
8265static PyObject *
8266posix_writev(PyObject *self, PyObject *args)
8267{
8268 int fd, cnt;
8269 Py_ssize_t res;
8270 PyObject *seq;
8271 struct iovec *iov;
8272 Py_buffer *buf;
8273 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8274 return NULL;
8275 if (!PySequence_Check(seq)) {
8276 PyErr_SetString(PyExc_TypeError,
8277 "writev() arg 2 must be a sequence");
8278 return NULL;
8279 }
8280 cnt = PySequence_Size(seq);
8281
8282 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8283 return NULL;
8284 }
8285
8286 Py_BEGIN_ALLOW_THREADS
8287 res = writev(fd, iov, cnt);
8288 Py_END_ALLOW_THREADS
8289
8290 iov_cleanup(iov, buf, cnt);
8291 return PyLong_FromSsize_t(res);
8292}
8293#endif
8294
8295#ifdef HAVE_PWRITE
8296PyDoc_STRVAR(posix_pwrite__doc__,
8297"pwrite(fd, string, offset) -> byteswritten\n\n\
8298Write string to a file descriptor, fd, from offset, leaving the file\n\
8299offset unchanged.");
8300
8301static PyObject *
8302posix_pwrite(PyObject *self, PyObject *args)
8303{
8304 Py_buffer pbuf;
8305 int fd;
8306 off_t offset;
8307 Py_ssize_t size;
8308
8309 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8310 return NULL;
8311
8312 if (!_PyVerify_fd(fd)) {
8313 PyBuffer_Release(&pbuf);
8314 return posix_error();
8315 }
8316 Py_BEGIN_ALLOW_THREADS
8317 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8318 Py_END_ALLOW_THREADS
8319 PyBuffer_Release(&pbuf);
8320 if (size < 0)
8321 return posix_error();
8322 return PyLong_FromSsize_t(size);
8323}
8324#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008325
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008326#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008327PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008328"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8329Create a FIFO (a POSIX named pipe).\n\
8330\n\
8331If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8332 and path should be relative; path will then be relative to that directory.\n\
8333dir_fd may not be implemented on your platform.\n\
8334 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008335
Barry Warsaw53699e91996-12-10 23:23:01 +00008336static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008337posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008338{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008339 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008340 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008341 int dir_fd = DEFAULT_DIR_FD;
8342 int result;
8343 PyObject *return_value = NULL;
8344 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8345
8346 memset(&path, 0, sizeof(path));
8347 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8348 path_converter, &path,
8349 &mode,
8350#ifdef HAVE_MKFIFOAT
8351 dir_fd_converter, &dir_fd
8352#else
8353 dir_fd_unavailable, &dir_fd
8354#endif
8355 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008356 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008357
Victor Stinner8c62be82010-05-06 00:08:46 +00008358 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008359#ifdef HAVE_MKFIFOAT
8360 if (dir_fd != DEFAULT_DIR_FD)
8361 result = mkfifoat(dir_fd, path.narrow, mode);
8362 else
8363#endif
8364 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008365 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008366
8367 if (result < 0) {
8368 return_value = posix_error();
8369 goto exit;
8370 }
8371
8372 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008373 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008374
8375exit:
8376 path_cleanup(&path);
8377 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008378}
8379#endif
8380
Neal Norwitz11690112002-07-30 01:08:28 +00008381#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008382PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008383"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008384Create a filesystem node (file, device special file or named pipe)\n\
8385named filename. mode specifies both the permissions to use and the\n\
8386type of node to be created, being combined (bitwise OR) with one of\n\
8387S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008388device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008389os.makedev()), otherwise it is ignored.\n\
8390\n\
8391If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8392 and path should be relative; path will then be relative to that directory.\n\
8393dir_fd may not be implemented on your platform.\n\
8394 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008395
8396
8397static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008398posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008399{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008400 path_t path;
8401 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008402 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008403 int dir_fd = DEFAULT_DIR_FD;
8404 int result;
8405 PyObject *return_value = NULL;
8406 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8407
8408 memset(&path, 0, sizeof(path));
8409 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8410 path_converter, &path,
8411 &mode, &device,
8412#ifdef HAVE_MKNODAT
8413 dir_fd_converter, &dir_fd
8414#else
8415 dir_fd_unavailable, &dir_fd
8416#endif
8417 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008419
Victor Stinner8c62be82010-05-06 00:08:46 +00008420 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008421#ifdef HAVE_MKNODAT
8422 if (dir_fd != DEFAULT_DIR_FD)
8423 result = mknodat(dir_fd, path.narrow, mode, device);
8424 else
8425#endif
8426 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008427 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008428
8429 if (result < 0) {
8430 return_value = posix_error();
8431 goto exit;
8432 }
8433
8434 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008435 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008436
Larry Hastings9cf065c2012-06-22 16:30:09 -07008437exit:
8438 path_cleanup(&path);
8439 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008440}
8441#endif
8442
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008443#ifdef HAVE_DEVICE_MACROS
8444PyDoc_STRVAR(posix_major__doc__,
8445"major(device) -> major number\n\
8446Extracts a device major number from a raw device number.");
8447
8448static PyObject *
8449posix_major(PyObject *self, PyObject *args)
8450{
Victor Stinner8c62be82010-05-06 00:08:46 +00008451 int device;
8452 if (!PyArg_ParseTuple(args, "i:major", &device))
8453 return NULL;
8454 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008455}
8456
8457PyDoc_STRVAR(posix_minor__doc__,
8458"minor(device) -> minor number\n\
8459Extracts a device minor number from a raw device number.");
8460
8461static PyObject *
8462posix_minor(PyObject *self, PyObject *args)
8463{
Victor Stinner8c62be82010-05-06 00:08:46 +00008464 int device;
8465 if (!PyArg_ParseTuple(args, "i:minor", &device))
8466 return NULL;
8467 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008468}
8469
8470PyDoc_STRVAR(posix_makedev__doc__,
8471"makedev(major, minor) -> device number\n\
8472Composes a raw device number from the major and minor device numbers.");
8473
8474static PyObject *
8475posix_makedev(PyObject *self, PyObject *args)
8476{
Victor Stinner8c62be82010-05-06 00:08:46 +00008477 int major, minor;
8478 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8479 return NULL;
8480 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008481}
8482#endif /* device macros */
8483
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008484
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008485#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008486PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008487"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008488Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008489
Barry Warsaw53699e91996-12-10 23:23:01 +00008490static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008491posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008492{
Victor Stinner8c62be82010-05-06 00:08:46 +00008493 int fd;
8494 off_t length;
8495 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008496
Ross Lagerwall7807c352011-03-17 20:20:30 +02008497 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008498 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008499
Victor Stinner8c62be82010-05-06 00:08:46 +00008500 Py_BEGIN_ALLOW_THREADS
8501 res = ftruncate(fd, length);
8502 Py_END_ALLOW_THREADS
8503 if (res < 0)
8504 return posix_error();
8505 Py_INCREF(Py_None);
8506 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008507}
8508#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008509
Ross Lagerwall7807c352011-03-17 20:20:30 +02008510#ifdef HAVE_TRUNCATE
8511PyDoc_STRVAR(posix_truncate__doc__,
8512"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008513Truncate the file given by path to length bytes.\n\
8514On some platforms, path may also be specified as an open file descriptor.\n\
8515 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008516
8517static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008518posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008519{
Georg Brandl306336b2012-06-24 12:55:33 +02008520 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008521 off_t length;
8522 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008523 PyObject *result = NULL;
8524 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008525
Georg Brandl306336b2012-06-24 12:55:33 +02008526 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008527 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008528#ifdef HAVE_FTRUNCATE
8529 path.allow_fd = 1;
8530#endif
8531 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8532 path_converter, &path,
8533 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008534 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008535
8536 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008537#ifdef HAVE_FTRUNCATE
8538 if (path.fd != -1)
8539 res = ftruncate(path.fd, length);
8540 else
8541#endif
8542 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008543 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008544 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008545 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008546 else {
8547 Py_INCREF(Py_None);
8548 result = Py_None;
8549 }
8550 path_cleanup(&path);
8551 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008552}
8553#endif
8554
8555#ifdef HAVE_POSIX_FALLOCATE
8556PyDoc_STRVAR(posix_posix_fallocate__doc__,
8557"posix_fallocate(fd, offset, len)\n\n\
8558Ensures that enough disk space is allocated for the file specified by fd\n\
8559starting from offset and continuing for len bytes.");
8560
8561static PyObject *
8562posix_posix_fallocate(PyObject *self, PyObject *args)
8563{
8564 off_t len, offset;
8565 int res, fd;
8566
8567 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8568 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8569 return NULL;
8570
8571 Py_BEGIN_ALLOW_THREADS
8572 res = posix_fallocate(fd, offset, len);
8573 Py_END_ALLOW_THREADS
8574 if (res != 0) {
8575 errno = res;
8576 return posix_error();
8577 }
8578 Py_RETURN_NONE;
8579}
8580#endif
8581
8582#ifdef HAVE_POSIX_FADVISE
8583PyDoc_STRVAR(posix_posix_fadvise__doc__,
8584"posix_fadvise(fd, offset, len, advice)\n\n\
8585Announces an intention to access data in a specific pattern thus allowing\n\
8586the kernel to make optimizations.\n\
8587The advice applies to the region of the file specified by fd starting at\n\
8588offset and continuing for len bytes.\n\
8589advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8590POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8591POSIX_FADV_DONTNEED.");
8592
8593static PyObject *
8594posix_posix_fadvise(PyObject *self, PyObject *args)
8595{
8596 off_t len, offset;
8597 int res, fd, advice;
8598
8599 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8600 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8601 return NULL;
8602
8603 Py_BEGIN_ALLOW_THREADS
8604 res = posix_fadvise(fd, offset, len, advice);
8605 Py_END_ALLOW_THREADS
8606 if (res != 0) {
8607 errno = res;
8608 return posix_error();
8609 }
8610 Py_RETURN_NONE;
8611}
8612#endif
8613
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008614#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008615PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008616"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008617Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008618
Fred Drake762e2061999-08-26 17:23:54 +00008619/* Save putenv() parameters as values here, so we can collect them when they
8620 * get re-set with another call for the same key. */
8621static PyObject *posix_putenv_garbage;
8622
Tim Peters5aa91602002-01-30 05:46:57 +00008623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008624posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008625{
Victor Stinner84ae1182010-05-06 22:05:07 +00008626 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008627#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008628 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008629 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008630
Victor Stinner8c62be82010-05-06 00:08:46 +00008631 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008632 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008633 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008634 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008635
Victor Stinner65170952011-11-22 22:16:17 +01008636 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008637 if (newstr == NULL) {
8638 PyErr_NoMemory();
8639 goto error;
8640 }
Victor Stinner65170952011-11-22 22:16:17 +01008641 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8642 PyErr_Format(PyExc_ValueError,
8643 "the environment variable is longer than %u characters",
8644 _MAX_ENV);
8645 goto error;
8646 }
8647
Victor Stinner8c62be82010-05-06 00:08:46 +00008648 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008649 if (newenv == NULL)
8650 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008651 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008652 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008653 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008654 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008655#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008656 PyObject *os1, *os2;
8657 char *s1, *s2;
8658 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008659
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008660 if (!PyArg_ParseTuple(args,
8661 "O&O&:putenv",
8662 PyUnicode_FSConverter, &os1,
8663 PyUnicode_FSConverter, &os2))
8664 return NULL;
8665 s1 = PyBytes_AsString(os1);
8666 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008667
Victor Stinner65170952011-11-22 22:16:17 +01008668 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008669 if (newstr == NULL) {
8670 PyErr_NoMemory();
8671 goto error;
8672 }
8673
Victor Stinner8c62be82010-05-06 00:08:46 +00008674 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008675 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008676 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008677 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008678 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008679#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008680
Victor Stinner8c62be82010-05-06 00:08:46 +00008681 /* Install the first arg and newstr in posix_putenv_garbage;
8682 * this will cause previous value to be collected. This has to
8683 * happen after the real putenv() call because the old value
8684 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008685 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008686 /* really not much we can do; just leak */
8687 PyErr_Clear();
8688 }
8689 else {
8690 Py_DECREF(newstr);
8691 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008692
Martin v. Löwis011e8422009-05-05 04:43:17 +00008693#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 Py_DECREF(os1);
8695 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008696#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008697 Py_RETURN_NONE;
8698
8699error:
8700#ifndef MS_WINDOWS
8701 Py_DECREF(os1);
8702 Py_DECREF(os2);
8703#endif
8704 Py_XDECREF(newstr);
8705 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008706}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008707#endif /* putenv */
8708
Guido van Rossumc524d952001-10-19 01:31:59 +00008709#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008710PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008711"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008712Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008713
8714static PyObject *
8715posix_unsetenv(PyObject *self, PyObject *args)
8716{
Victor Stinner65170952011-11-22 22:16:17 +01008717 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008718#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008719 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008720#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008721
8722 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008723
Victor Stinner65170952011-11-22 22:16:17 +01008724 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008725 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008726
Victor Stinner984890f2011-11-24 13:53:38 +01008727#ifdef HAVE_BROKEN_UNSETENV
8728 unsetenv(PyBytes_AS_STRING(name));
8729#else
Victor Stinner65170952011-11-22 22:16:17 +01008730 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008731 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008732 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008733 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008734 }
Victor Stinner984890f2011-11-24 13:53:38 +01008735#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008736
Victor Stinner8c62be82010-05-06 00:08:46 +00008737 /* Remove the key from posix_putenv_garbage;
8738 * this will cause it to be collected. This has to
8739 * happen after the real unsetenv() call because the
8740 * old value was still accessible until then.
8741 */
Victor Stinner65170952011-11-22 22:16:17 +01008742 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008743 /* really not much we can do; just leak */
8744 PyErr_Clear();
8745 }
Victor Stinner65170952011-11-22 22:16:17 +01008746 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008747 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008748}
8749#endif /* unsetenv */
8750
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008751PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008752"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008753Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008754
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008756posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008757{
Victor Stinner8c62be82010-05-06 00:08:46 +00008758 int code;
8759 char *message;
8760 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8761 return NULL;
8762 message = strerror(code);
8763 if (message == NULL) {
8764 PyErr_SetString(PyExc_ValueError,
8765 "strerror() argument out of range");
8766 return NULL;
8767 }
Victor Stinner1b579672011-12-17 05:47:23 +01008768 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008769}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008770
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008771
Guido van Rossumc9641791998-08-04 15:26:23 +00008772#ifdef HAVE_SYS_WAIT_H
8773
Fred Drake106c1a02002-04-23 15:58:02 +00008774#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008775PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008776"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008777Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008778
8779static PyObject *
8780posix_WCOREDUMP(PyObject *self, PyObject *args)
8781{
Victor Stinner8c62be82010-05-06 00:08:46 +00008782 WAIT_TYPE status;
8783 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008784
Victor Stinner8c62be82010-05-06 00:08:46 +00008785 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8786 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008787
Victor Stinner8c62be82010-05-06 00:08:46 +00008788 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008789}
8790#endif /* WCOREDUMP */
8791
8792#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008793PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008794"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008795Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008796job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008797
8798static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008799posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008800{
Victor Stinner8c62be82010-05-06 00:08:46 +00008801 WAIT_TYPE status;
8802 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008803
Victor Stinner8c62be82010-05-06 00:08:46 +00008804 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8805 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008806
Victor Stinner8c62be82010-05-06 00:08:46 +00008807 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008808}
8809#endif /* WIFCONTINUED */
8810
Guido van Rossumc9641791998-08-04 15:26:23 +00008811#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008812PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008813"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008814Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008815
8816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008817posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008818{
Victor Stinner8c62be82010-05-06 00:08:46 +00008819 WAIT_TYPE status;
8820 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008821
Victor Stinner8c62be82010-05-06 00:08:46 +00008822 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8823 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008824
Victor Stinner8c62be82010-05-06 00:08:46 +00008825 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008826}
8827#endif /* WIFSTOPPED */
8828
8829#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008830PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008831"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008832Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008833
8834static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008835posix_WIFSIGNALED(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:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8841 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008842
Victor Stinner8c62be82010-05-06 00:08:46 +00008843 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008844}
8845#endif /* WIFSIGNALED */
8846
8847#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008848PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008849"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008850Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008851system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008852
8853static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008854posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008855{
Victor Stinner8c62be82010-05-06 00:08:46 +00008856 WAIT_TYPE status;
8857 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008858
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8860 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008861
Victor Stinner8c62be82010-05-06 00:08:46 +00008862 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008863}
8864#endif /* WIFEXITED */
8865
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008866#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008867PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008868"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008869Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008870
8871static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008872posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008873{
Victor Stinner8c62be82010-05-06 00:08:46 +00008874 WAIT_TYPE status;
8875 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008876
Victor Stinner8c62be82010-05-06 00:08:46 +00008877 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8878 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008879
Victor Stinner8c62be82010-05-06 00:08:46 +00008880 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008881}
8882#endif /* WEXITSTATUS */
8883
8884#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008885PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008886"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008887Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008888value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008889
8890static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008891posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008892{
Victor Stinner8c62be82010-05-06 00:08:46 +00008893 WAIT_TYPE status;
8894 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008895
Victor Stinner8c62be82010-05-06 00:08:46 +00008896 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8897 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008898
Victor Stinner8c62be82010-05-06 00:08:46 +00008899 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008900}
8901#endif /* WTERMSIG */
8902
8903#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008904PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008905"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008906Return the signal that stopped the process that provided\n\
8907the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008908
8909static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008910posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008911{
Victor Stinner8c62be82010-05-06 00:08:46 +00008912 WAIT_TYPE status;
8913 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008914
Victor Stinner8c62be82010-05-06 00:08:46 +00008915 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8916 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008917
Victor Stinner8c62be82010-05-06 00:08:46 +00008918 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008919}
8920#endif /* WSTOPSIG */
8921
8922#endif /* HAVE_SYS_WAIT_H */
8923
8924
Thomas Wouters477c8d52006-05-27 19:21:47 +00008925#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008926#ifdef _SCO_DS
8927/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8928 needed definitions in sys/statvfs.h */
8929#define _SVID3
8930#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008931#include <sys/statvfs.h>
8932
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008933static PyObject*
8934_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8936 if (v == NULL)
8937 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008938
8939#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008940 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8941 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8942 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8943 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8944 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8945 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8946 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8947 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8948 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8949 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008950#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8952 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8953 PyStructSequence_SET_ITEM(v, 2,
8954 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8955 PyStructSequence_SET_ITEM(v, 3,
8956 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8957 PyStructSequence_SET_ITEM(v, 4,
8958 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8959 PyStructSequence_SET_ITEM(v, 5,
8960 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8961 PyStructSequence_SET_ITEM(v, 6,
8962 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8963 PyStructSequence_SET_ITEM(v, 7,
8964 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8965 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8966 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008967#endif
8968
Victor Stinner8c62be82010-05-06 00:08:46 +00008969 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008970}
8971
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008972PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008973"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008974Perform an fstatvfs system call on the given fd.\n\
8975Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008976
8977static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008978posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008979{
Victor Stinner8c62be82010-05-06 00:08:46 +00008980 int fd, res;
8981 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008982
Victor Stinner8c62be82010-05-06 00:08:46 +00008983 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8984 return NULL;
8985 Py_BEGIN_ALLOW_THREADS
8986 res = fstatvfs(fd, &st);
8987 Py_END_ALLOW_THREADS
8988 if (res != 0)
8989 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008990
Victor Stinner8c62be82010-05-06 00:08:46 +00008991 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008992}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008993#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008994
8995
Thomas Wouters477c8d52006-05-27 19:21:47 +00008996#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008997#include <sys/statvfs.h>
8998
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008999PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009000"statvfs(path)\n\n\
9001Perform a statvfs system call on the given path.\n\
9002\n\
9003path may always be specified as a string.\n\
9004On some platforms, path may also be specified as an open file descriptor.\n\
9005 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009006
9007static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009008posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009009{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009010 static char *keywords[] = {"path", NULL};
9011 path_t path;
9012 int result;
9013 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009014 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009015
Larry Hastings9cf065c2012-06-22 16:30:09 -07009016 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009017 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009018#ifdef HAVE_FSTATVFS
9019 path.allow_fd = 1;
9020#endif
9021 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9022 path_converter, &path
9023 ))
9024 return NULL;
9025
9026 Py_BEGIN_ALLOW_THREADS
9027#ifdef HAVE_FSTATVFS
9028 if (path.fd != -1) {
9029#ifdef __APPLE__
9030 /* handle weak-linking on Mac OS X 10.3 */
9031 if (fstatvfs == NULL) {
9032 fd_specified("statvfs", path.fd);
9033 goto exit;
9034 }
9035#endif
9036 result = fstatvfs(path.fd, &st);
9037 }
9038 else
9039#endif
9040 result = statvfs(path.narrow, &st);
9041 Py_END_ALLOW_THREADS
9042
9043 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009044 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009045 goto exit;
9046 }
9047
9048 return_value = _pystatvfs_fromstructstatvfs(st);
9049
9050exit:
9051 path_cleanup(&path);
9052 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009053}
9054#endif /* HAVE_STATVFS */
9055
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009056#ifdef MS_WINDOWS
9057PyDoc_STRVAR(win32__getdiskusage__doc__,
9058"_getdiskusage(path) -> (total, free)\n\n\
9059Return disk usage statistics about the given path as (total, free) tuple.");
9060
9061static PyObject *
9062win32__getdiskusage(PyObject *self, PyObject *args)
9063{
9064 BOOL retval;
9065 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009066 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009067
Victor Stinner6139c1b2011-11-09 22:14:14 +01009068 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009069 return NULL;
9070
9071 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009072 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009073 Py_END_ALLOW_THREADS
9074 if (retval == 0)
9075 return PyErr_SetFromWindowsErr(0);
9076
9077 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9078}
9079#endif
9080
9081
Fred Drakec9680921999-12-13 16:37:25 +00009082/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9083 * It maps strings representing configuration variable names to
9084 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009085 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009086 * rarely-used constants. There are three separate tables that use
9087 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009088 *
9089 * This code is always included, even if none of the interfaces that
9090 * need it are included. The #if hackery needed to avoid it would be
9091 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009092 */
9093struct constdef {
9094 char *name;
9095 long value;
9096};
9097
Fred Drake12c6e2d1999-12-14 21:25:03 +00009098static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009099conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009100 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009101{
Christian Heimes217cfd12007-12-02 14:31:20 +00009102 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009103 *valuep = PyLong_AS_LONG(arg);
9104 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009105 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009106 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009107 /* look up the value in the table using a binary search */
9108 size_t lo = 0;
9109 size_t mid;
9110 size_t hi = tablesize;
9111 int cmp;
9112 const char *confname;
9113 if (!PyUnicode_Check(arg)) {
9114 PyErr_SetString(PyExc_TypeError,
9115 "configuration names must be strings or integers");
9116 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009117 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009118 confname = _PyUnicode_AsString(arg);
9119 if (confname == NULL)
9120 return 0;
9121 while (lo < hi) {
9122 mid = (lo + hi) / 2;
9123 cmp = strcmp(confname, table[mid].name);
9124 if (cmp < 0)
9125 hi = mid;
9126 else if (cmp > 0)
9127 lo = mid + 1;
9128 else {
9129 *valuep = table[mid].value;
9130 return 1;
9131 }
9132 }
9133 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9134 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009135 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009136}
9137
9138
9139#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9140static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009141#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009142 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009143#endif
9144#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009145 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009146#endif
Fred Drakec9680921999-12-13 16:37:25 +00009147#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009148 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009149#endif
9150#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009151 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009152#endif
9153#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009154 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009155#endif
9156#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009157 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009158#endif
9159#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009160 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009161#endif
9162#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009163 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009164#endif
9165#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009166 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009167#endif
9168#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009169 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009170#endif
9171#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009172 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009173#endif
9174#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009175 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009176#endif
9177#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009178 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009179#endif
9180#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009181 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009182#endif
9183#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009184 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009185#endif
9186#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009187 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009188#endif
9189#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009190 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009191#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009192#ifdef _PC_ACL_ENABLED
9193 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9194#endif
9195#ifdef _PC_MIN_HOLE_SIZE
9196 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9197#endif
9198#ifdef _PC_ALLOC_SIZE_MIN
9199 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9200#endif
9201#ifdef _PC_REC_INCR_XFER_SIZE
9202 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9203#endif
9204#ifdef _PC_REC_MAX_XFER_SIZE
9205 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9206#endif
9207#ifdef _PC_REC_MIN_XFER_SIZE
9208 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9209#endif
9210#ifdef _PC_REC_XFER_ALIGN
9211 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9212#endif
9213#ifdef _PC_SYMLINK_MAX
9214 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9215#endif
9216#ifdef _PC_XATTR_ENABLED
9217 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9218#endif
9219#ifdef _PC_XATTR_EXISTS
9220 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9221#endif
9222#ifdef _PC_TIMESTAMP_RESOLUTION
9223 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9224#endif
Fred Drakec9680921999-12-13 16:37:25 +00009225};
9226
Fred Drakec9680921999-12-13 16:37:25 +00009227static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009228conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009229{
9230 return conv_confname(arg, valuep, posix_constants_pathconf,
9231 sizeof(posix_constants_pathconf)
9232 / sizeof(struct constdef));
9233}
9234#endif
9235
9236#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009237PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009238"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009239Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009240If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009241
9242static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009243posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009244{
9245 PyObject *result = NULL;
9246 int name, fd;
9247
Fred Drake12c6e2d1999-12-14 21:25:03 +00009248 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9249 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009250 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009251
Stefan Krah0e803b32010-11-26 16:16:47 +00009252 errno = 0;
9253 limit = fpathconf(fd, name);
9254 if (limit == -1 && errno != 0)
9255 posix_error();
9256 else
9257 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009258 }
9259 return result;
9260}
9261#endif
9262
9263
9264#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009265PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009266"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009267Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009268If there is no limit, return -1.\n\
9269On some platforms, path may also be specified as an open file descriptor.\n\
9270 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009271
9272static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009273posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009274{
Georg Brandl306336b2012-06-24 12:55:33 +02009275 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009276 PyObject *result = NULL;
9277 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009278 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009279
Georg Brandl306336b2012-06-24 12:55:33 +02009280 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009281 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009282#ifdef HAVE_FPATHCONF
9283 path.allow_fd = 1;
9284#endif
9285 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9286 path_converter, &path,
9287 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009288 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009289
Victor Stinner8c62be82010-05-06 00:08:46 +00009290 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009291#ifdef HAVE_FPATHCONF
9292 if (path.fd != -1)
9293 limit = fpathconf(path.fd, name);
9294 else
9295#endif
9296 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009297 if (limit == -1 && errno != 0) {
9298 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009299 /* could be a path or name problem */
9300 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009301 else
Victor Stinner292c8352012-10-30 02:17:38 +01009302 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009303 }
9304 else
9305 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009306 }
Georg Brandl306336b2012-06-24 12:55:33 +02009307 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009308 return result;
9309}
9310#endif
9311
9312#ifdef HAVE_CONFSTR
9313static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009314#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009315 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009316#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009317#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009318 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009319#endif
9320#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009321 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009322#endif
Fred Draked86ed291999-12-15 15:34:33 +00009323#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009324 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009325#endif
9326#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009327 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009328#endif
9329#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009330 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009331#endif
9332#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009333 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009334#endif
Fred Drakec9680921999-12-13 16:37:25 +00009335#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009336 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009337#endif
9338#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009339 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009340#endif
9341#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009342 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009343#endif
9344#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009345 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009346#endif
9347#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009348 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009349#endif
9350#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009351 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009352#endif
9353#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009354 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009355#endif
9356#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009357 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009358#endif
Fred Draked86ed291999-12-15 15:34:33 +00009359#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009360 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009361#endif
Fred Drakec9680921999-12-13 16:37:25 +00009362#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009364#endif
Fred Draked86ed291999-12-15 15:34:33 +00009365#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009366 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009367#endif
9368#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009369 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009370#endif
9371#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009372 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009373#endif
9374#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009375 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009376#endif
Fred Drakec9680921999-12-13 16:37:25 +00009377#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009378 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009379#endif
9380#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009382#endif
9383#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009385#endif
9386#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009387 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009388#endif
9389#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009391#endif
9392#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009393 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009394#endif
9395#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009396 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009397#endif
9398#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009399 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009400#endif
9401#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009402 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009403#endif
9404#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009405 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009406#endif
9407#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009408 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009409#endif
9410#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009411 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009412#endif
9413#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009414 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009415#endif
9416#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009417 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009418#endif
9419#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009420 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009421#endif
9422#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009423 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009424#endif
Fred Draked86ed291999-12-15 15:34:33 +00009425#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009426 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009427#endif
9428#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009429 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009430#endif
9431#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009432 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009433#endif
9434#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009435 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009436#endif
9437#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009438 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009439#endif
9440#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009441 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009442#endif
9443#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009444 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009445#endif
9446#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009447 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009448#endif
9449#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009450 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009451#endif
9452#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009453 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009454#endif
9455#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009456 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009457#endif
9458#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009459 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009460#endif
9461#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009462 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009463#endif
Fred Drakec9680921999-12-13 16:37:25 +00009464};
9465
9466static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009467conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009468{
9469 return conv_confname(arg, valuep, posix_constants_confstr,
9470 sizeof(posix_constants_confstr)
9471 / sizeof(struct constdef));
9472}
9473
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009474PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009475"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009476Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009477
9478static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009479posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009480{
9481 PyObject *result = NULL;
9482 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009483 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009484 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009485
Victor Stinnercb043522010-09-10 23:49:04 +00009486 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9487 return NULL;
9488
9489 errno = 0;
9490 len = confstr(name, buffer, sizeof(buffer));
9491 if (len == 0) {
9492 if (errno) {
9493 posix_error();
9494 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009495 }
9496 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009497 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009498 }
9499 }
Victor Stinnercb043522010-09-10 23:49:04 +00009500
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009501 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009502 char *buf = PyMem_Malloc(len);
9503 if (buf == NULL)
9504 return PyErr_NoMemory();
9505 confstr(name, buf, len);
9506 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9507 PyMem_Free(buf);
9508 }
9509 else
9510 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009511 return result;
9512}
9513#endif
9514
9515
9516#ifdef HAVE_SYSCONF
9517static struct constdef posix_constants_sysconf[] = {
9518#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009519 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009520#endif
9521#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009523#endif
9524#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009526#endif
9527#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009529#endif
9530#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009532#endif
9533#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009535#endif
9536#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009538#endif
9539#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009541#endif
9542#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009544#endif
9545#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009547#endif
Fred Draked86ed291999-12-15 15:34:33 +00009548#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009550#endif
9551#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009553#endif
Fred Drakec9680921999-12-13 16:37:25 +00009554#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009556#endif
Fred Drakec9680921999-12-13 16:37:25 +00009557#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009559#endif
9560#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009562#endif
9563#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009565#endif
9566#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009568#endif
9569#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009571#endif
Fred Draked86ed291999-12-15 15:34:33 +00009572#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009574#endif
Fred Drakec9680921999-12-13 16:37:25 +00009575#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009577#endif
9578#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009580#endif
9581#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009583#endif
9584#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009586#endif
9587#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009589#endif
Fred Draked86ed291999-12-15 15:34:33 +00009590#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009592#endif
Fred Drakec9680921999-12-13 16:37:25 +00009593#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009595#endif
9596#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009598#endif
9599#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009601#endif
9602#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009604#endif
9605#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009607#endif
9608#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009610#endif
9611#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009613#endif
9614#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009616#endif
9617#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009619#endif
9620#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009622#endif
9623#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009625#endif
9626#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009628#endif
9629#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009630 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009631#endif
9632#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009633 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009634#endif
9635#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009636 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009637#endif
9638#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009640#endif
9641#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009643#endif
9644#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009646#endif
9647#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009649#endif
9650#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009652#endif
9653#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009655#endif
9656#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009658#endif
9659#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009661#endif
Fred Draked86ed291999-12-15 15:34:33 +00009662#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009664#endif
Fred Drakec9680921999-12-13 16:37:25 +00009665#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009666 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009667#endif
9668#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009670#endif
9671#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009673#endif
Fred Draked86ed291999-12-15 15:34:33 +00009674#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009676#endif
Fred Drakec9680921999-12-13 16:37:25 +00009677#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009679#endif
Fred Draked86ed291999-12-15 15:34:33 +00009680#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009682#endif
9683#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009685#endif
Fred Drakec9680921999-12-13 16:37:25 +00009686#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009688#endif
9689#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009691#endif
9692#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009694#endif
9695#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009697#endif
Fred Draked86ed291999-12-15 15:34:33 +00009698#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009700#endif
Fred Drakec9680921999-12-13 16:37:25 +00009701#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009703#endif
9704#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009706#endif
9707#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009709#endif
9710#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009712#endif
9713#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009715#endif
9716#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009718#endif
9719#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009721#endif
Fred Draked86ed291999-12-15 15:34:33 +00009722#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009724#endif
Fred Drakec9680921999-12-13 16:37:25 +00009725#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
Fred Draked86ed291999-12-15 15:34:33 +00009731#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009733#endif
Fred Drakec9680921999-12-13 16:37:25 +00009734#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
Fred Draked86ed291999-12-15 15:34:33 +00009761#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009763#endif
9764#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009766#endif
Fred Drakec9680921999-12-13 16:37:25 +00009767#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
Fred Draked86ed291999-12-15 15:34:33 +00009872#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009874#endif
Fred Drakec9680921999-12-13 16:37:25 +00009875#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
9884#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
9887#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
9890#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
9893#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
9908#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010};
10011
10012static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010013conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010014{
10015 return conv_confname(arg, valuep, posix_constants_sysconf,
10016 sizeof(posix_constants_sysconf)
10017 / sizeof(struct constdef));
10018}
10019
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010020PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010021"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010022Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010023
10024static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010025posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010026{
10027 PyObject *result = NULL;
10028 int name;
10029
10030 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +020010031 long value;
Fred Drakec9680921999-12-13 16:37:25 +000010032
10033 errno = 0;
10034 value = sysconf(name);
10035 if (value == -1 && errno != 0)
10036 posix_error();
10037 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010038 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010039 }
10040 return result;
10041}
10042#endif
10043
10044
Fred Drakebec628d1999-12-15 18:31:10 +000010045/* This code is used to ensure that the tables of configuration value names
10046 * are in sorted order as required by conv_confname(), and also to build the
10047 * the exported dictionaries that are used to publish information about the
10048 * names available on the host platform.
10049 *
10050 * Sorting the table at runtime ensures that the table is properly ordered
10051 * when used, even for platforms we're not able to test on. It also makes
10052 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010053 */
Fred Drakebec628d1999-12-15 18:31:10 +000010054
10055static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010056cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010057{
10058 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010060 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010062
10063 return strcmp(c1->name, c2->name);
10064}
10065
10066static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010067setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010069{
Fred Drakebec628d1999-12-15 18:31:10 +000010070 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010071 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010072
10073 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10074 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010075 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010077
Barry Warsaw3155db32000-04-13 15:20:40 +000010078 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 PyObject *o = PyLong_FromLong(table[i].value);
10080 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10081 Py_XDECREF(o);
10082 Py_DECREF(d);
10083 return -1;
10084 }
10085 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010086 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010087 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010088}
10089
Fred Drakebec628d1999-12-15 18:31:10 +000010090/* Return -1 on failure, 0 on success. */
10091static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010092setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010093{
10094#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010095 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010096 sizeof(posix_constants_pathconf)
10097 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010098 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010099 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010100#endif
10101#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010102 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010103 sizeof(posix_constants_confstr)
10104 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010105 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010106 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010107#endif
10108#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010109 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010110 sizeof(posix_constants_sysconf)
10111 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010112 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010113 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010114#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010115 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010116}
Fred Draked86ed291999-12-15 15:34:33 +000010117
10118
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010119PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010120"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010121Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010122in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010123
10124static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010125posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010126{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010127 abort();
10128 /*NOTREACHED*/
10129 Py_FatalError("abort() called from Python code didn't abort!");
10130 return NULL;
10131}
Fred Drakebec628d1999-12-15 18:31:10 +000010132
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010133#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010134PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010135"startfile(filepath [, operation]) - Start a file with its associated\n\
10136application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010137\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010138When \"operation\" is not specified or \"open\", this acts like\n\
10139double-clicking the file in Explorer, or giving the file name as an\n\
10140argument to the DOS \"start\" command: the file is opened with whatever\n\
10141application (if any) its extension is associated.\n\
10142When another \"operation\" is given, it specifies what should be done with\n\
10143the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010144\n\
10145startfile returns as soon as the associated application is launched.\n\
10146There is no option to wait for the application to close, and no way\n\
10147to retrieve the application's exit status.\n\
10148\n\
10149The filepath is relative to the current directory. If you want to use\n\
10150an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010151the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010152
10153static PyObject *
10154win32_startfile(PyObject *self, PyObject *args)
10155{
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 PyObject *ofilepath;
10157 char *filepath;
10158 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010159 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010161
Victor Stinnereb5657a2011-09-30 01:44:27 +020010162 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 if (!PyArg_ParseTuple(args, "U|s:startfile",
10164 &unipath, &operation)) {
10165 PyErr_Clear();
10166 goto normal;
10167 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010168
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010170 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010172 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 PyErr_Clear();
10174 operation = NULL;
10175 goto normal;
10176 }
10177 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010178
Victor Stinnereb5657a2011-09-30 01:44:27 +020010179 wpath = PyUnicode_AsUnicode(unipath);
10180 if (wpath == NULL)
10181 goto normal;
10182 if (uoperation) {
10183 woperation = PyUnicode_AsUnicode(uoperation);
10184 if (woperation == NULL)
10185 goto normal;
10186 }
10187 else
10188 woperation = NULL;
10189
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010191 rc = ShellExecuteW((HWND)0, woperation, wpath,
10192 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 Py_END_ALLOW_THREADS
10194
Victor Stinnereb5657a2011-09-30 01:44:27 +020010195 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010197 win32_error_object("startfile", unipath);
10198 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 }
10200 Py_INCREF(Py_None);
10201 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010202
10203normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10205 PyUnicode_FSConverter, &ofilepath,
10206 &operation))
10207 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010208 if (win32_warn_bytes_api()) {
10209 Py_DECREF(ofilepath);
10210 return NULL;
10211 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 filepath = PyBytes_AsString(ofilepath);
10213 Py_BEGIN_ALLOW_THREADS
10214 rc = ShellExecute((HWND)0, operation, filepath,
10215 NULL, NULL, SW_SHOWNORMAL);
10216 Py_END_ALLOW_THREADS
10217 if (rc <= (HINSTANCE)32) {
10218 PyObject *errval = win32_error("startfile", filepath);
10219 Py_DECREF(ofilepath);
10220 return errval;
10221 }
10222 Py_DECREF(ofilepath);
10223 Py_INCREF(Py_None);
10224 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010225}
10226#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010227
Martin v. Löwis438b5342002-12-27 10:16:42 +000010228#ifdef HAVE_GETLOADAVG
10229PyDoc_STRVAR(posix_getloadavg__doc__,
10230"getloadavg() -> (float, float, float)\n\n\
10231Return the number of processes in the system run queue averaged over\n\
10232the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10233was unobtainable");
10234
10235static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010236posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010237{
10238 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010239 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010240 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10241 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010242 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010243 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010244}
10245#endif
10246
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010247PyDoc_STRVAR(device_encoding__doc__,
10248"device_encoding(fd) -> str\n\n\
10249Return a string describing the encoding of the device\n\
10250if the output is a terminal; else return None.");
10251
10252static PyObject *
10253device_encoding(PyObject *self, PyObject *args)
10254{
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010256
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10258 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010259
10260 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010261}
10262
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010263#ifdef HAVE_SETRESUID
10264PyDoc_STRVAR(posix_setresuid__doc__,
10265"setresuid(ruid, euid, suid)\n\n\
10266Set the current process's real, effective, and saved user ids.");
10267
10268static PyObject*
10269posix_setresuid (PyObject *self, PyObject *args)
10270{
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010272 uid_t ruid, euid, suid;
10273 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10274 _Py_Uid_Converter, &ruid,
10275 _Py_Uid_Converter, &euid,
10276 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 return NULL;
10278 if (setresuid(ruid, euid, suid) < 0)
10279 return posix_error();
10280 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010281}
10282#endif
10283
10284#ifdef HAVE_SETRESGID
10285PyDoc_STRVAR(posix_setresgid__doc__,
10286"setresgid(rgid, egid, sgid)\n\n\
10287Set the current process's real, effective, and saved group ids.");
10288
10289static PyObject*
10290posix_setresgid (PyObject *self, PyObject *args)
10291{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010292 gid_t rgid, egid, sgid;
10293 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10294 _Py_Gid_Converter, &rgid,
10295 _Py_Gid_Converter, &egid,
10296 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010297 return NULL;
10298 if (setresgid(rgid, egid, sgid) < 0)
10299 return posix_error();
10300 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010301}
10302#endif
10303
10304#ifdef HAVE_GETRESUID
10305PyDoc_STRVAR(posix_getresuid__doc__,
10306"getresuid() -> (ruid, euid, suid)\n\n\
10307Get tuple of the current process's real, effective, and saved user ids.");
10308
10309static PyObject*
10310posix_getresuid (PyObject *self, PyObject *noargs)
10311{
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 if (getresuid(&ruid, &euid, &suid) < 0)
10314 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010315 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10316 _PyLong_FromUid(euid),
10317 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010318}
10319#endif
10320
10321#ifdef HAVE_GETRESGID
10322PyDoc_STRVAR(posix_getresgid__doc__,
10323"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010324Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010325
10326static PyObject*
10327posix_getresgid (PyObject *self, PyObject *noargs)
10328{
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 if (getresgid(&rgid, &egid, &sgid) < 0)
10331 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010332 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10333 _PyLong_FromGid(egid),
10334 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010335}
10336#endif
10337
Benjamin Peterson9428d532011-09-14 11:45:52 -040010338#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010339
Benjamin Peterson799bd802011-08-31 22:15:17 -040010340PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010341"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10342Return the value of extended attribute attribute on path.\n\
10343\n\
10344path may be either a string or an open file descriptor.\n\
10345If follow_symlinks is False, and the last element of the path is a symbolic\n\
10346 link, getxattr will examine the symbolic link itself instead of the file\n\
10347 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010348
10349static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010350posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010351{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010352 path_t path;
10353 path_t attribute;
10354 int follow_symlinks = 1;
10355 PyObject *buffer = NULL;
10356 int i;
10357 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010358
Larry Hastings9cf065c2012-06-22 16:30:09 -070010359 memset(&path, 0, sizeof(path));
10360 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010361 path.function_name = "getxattr";
10362 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010363 path.allow_fd = 1;
10364 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10365 path_converter, &path,
10366 path_converter, &attribute,
10367 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010368 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010369
Larry Hastings9cf065c2012-06-22 16:30:09 -070010370 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10371 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010372
Larry Hastings9cf065c2012-06-22 16:30:09 -070010373 for (i = 0; ; i++) {
10374 void *ptr;
10375 ssize_t result;
10376 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10377 Py_ssize_t buffer_size = buffer_sizes[i];
10378 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010379 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010380 goto exit;
10381 }
10382 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10383 if (!buffer)
10384 goto exit;
10385 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010386
Larry Hastings9cf065c2012-06-22 16:30:09 -070010387 Py_BEGIN_ALLOW_THREADS;
10388 if (path.fd >= 0)
10389 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10390 else if (follow_symlinks)
10391 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10392 else
10393 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10394 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010395
Larry Hastings9cf065c2012-06-22 16:30:09 -070010396 if (result < 0) {
10397 Py_DECREF(buffer);
10398 buffer = NULL;
10399 if (errno == ERANGE)
10400 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010401 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010402 goto exit;
10403 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010404
Larry Hastings9cf065c2012-06-22 16:30:09 -070010405 if (result != buffer_size) {
10406 /* Can only shrink. */
10407 _PyBytes_Resize(&buffer, result);
10408 }
10409 break;
10410 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010411
Larry Hastings9cf065c2012-06-22 16:30:09 -070010412exit:
10413 path_cleanup(&path);
10414 path_cleanup(&attribute);
10415 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010416}
10417
10418PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010419"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10420Set extended attribute attribute on path to value.\n\
10421path may be either a string or an open file descriptor.\n\
10422If follow_symlinks is False, and the last element of the path is a symbolic\n\
10423 link, setxattr will modify the symbolic link itself instead of the file\n\
10424 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010425
10426static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010427posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010428{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010429 path_t path;
10430 path_t attribute;
10431 Py_buffer value;
10432 int flags = 0;
10433 int follow_symlinks = 1;
10434 int result;
10435 PyObject *return_value = NULL;
10436 static char *keywords[] = {"path", "attribute", "value",
10437 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010438
Larry Hastings9cf065c2012-06-22 16:30:09 -070010439 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010440 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010441 path.allow_fd = 1;
10442 memset(&attribute, 0, sizeof(attribute));
10443 memset(&value, 0, sizeof(value));
10444 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10445 keywords,
10446 path_converter, &path,
10447 path_converter, &attribute,
10448 &value, &flags,
10449 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010450 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010451
10452 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10453 goto exit;
10454
Benjamin Peterson799bd802011-08-31 22:15:17 -040010455 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010456 if (path.fd > -1)
10457 result = fsetxattr(path.fd, attribute.narrow,
10458 value.buf, value.len, flags);
10459 else if (follow_symlinks)
10460 result = setxattr(path.narrow, attribute.narrow,
10461 value.buf, value.len, flags);
10462 else
10463 result = lsetxattr(path.narrow, attribute.narrow,
10464 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010465 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010466
Larry Hastings9cf065c2012-06-22 16:30:09 -070010467 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010468 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010469 goto exit;
10470 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010471
Larry Hastings9cf065c2012-06-22 16:30:09 -070010472 return_value = Py_None;
10473 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010474
Larry Hastings9cf065c2012-06-22 16:30:09 -070010475exit:
10476 path_cleanup(&path);
10477 path_cleanup(&attribute);
10478 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010479
Larry Hastings9cf065c2012-06-22 16:30:09 -070010480 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010481}
10482
10483PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010484"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10485Remove extended attribute attribute on path.\n\
10486path may be either a string or an open file descriptor.\n\
10487If follow_symlinks is False, and the last element of the path is a symbolic\n\
10488 link, removexattr will modify the symbolic link itself instead of the file\n\
10489 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010490
10491static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010492posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010493{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010494 path_t path;
10495 path_t attribute;
10496 int follow_symlinks = 1;
10497 int result;
10498 PyObject *return_value = NULL;
10499 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010500
Larry Hastings9cf065c2012-06-22 16:30:09 -070010501 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010502 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010503 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010504 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010505 path.allow_fd = 1;
10506 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10507 keywords,
10508 path_converter, &path,
10509 path_converter, &attribute,
10510 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010511 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010512
10513 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10514 goto exit;
10515
Benjamin Peterson799bd802011-08-31 22:15:17 -040010516 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010517 if (path.fd > -1)
10518 result = fremovexattr(path.fd, attribute.narrow);
10519 else if (follow_symlinks)
10520 result = removexattr(path.narrow, attribute.narrow);
10521 else
10522 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010523 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010524
Larry Hastings9cf065c2012-06-22 16:30:09 -070010525 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010526 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010527 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010528 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010529
Larry Hastings9cf065c2012-06-22 16:30:09 -070010530 return_value = Py_None;
10531 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010532
Larry Hastings9cf065c2012-06-22 16:30:09 -070010533exit:
10534 path_cleanup(&path);
10535 path_cleanup(&attribute);
10536
10537 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010538}
10539
10540PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010541"listxattr(path='.', *, follow_symlinks=True)\n\n\
10542Return a list of extended attributes on path.\n\
10543\n\
10544path may be either None, a string, or an open file descriptor.\n\
10545if path is None, listxattr will examine the current directory.\n\
10546If follow_symlinks is False, and the last element of the path is a symbolic\n\
10547 link, listxattr will examine the symbolic link itself instead of the file\n\
10548 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010549
10550static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010551posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010552{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010553 path_t path;
10554 int follow_symlinks = 1;
10555 Py_ssize_t i;
10556 PyObject *result = NULL;
10557 char *buffer = NULL;
10558 char *name;
10559 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010560
Larry Hastings9cf065c2012-06-22 16:30:09 -070010561 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010562 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010563 path.allow_fd = 1;
10564 path.fd = -1;
10565 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10566 path_converter, &path,
10567 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010568 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010569
Larry Hastings9cf065c2012-06-22 16:30:09 -070010570 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10571 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010572
Larry Hastings9cf065c2012-06-22 16:30:09 -070010573 name = path.narrow ? path.narrow : ".";
10574 for (i = 0; ; i++) {
10575 char *start, *trace, *end;
10576 ssize_t length;
10577 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10578 Py_ssize_t buffer_size = buffer_sizes[i];
10579 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010580 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010581 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010582 break;
10583 }
10584 buffer = PyMem_MALLOC(buffer_size);
10585 if (!buffer) {
10586 PyErr_NoMemory();
10587 break;
10588 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010589
Larry Hastings9cf065c2012-06-22 16:30:09 -070010590 Py_BEGIN_ALLOW_THREADS;
10591 if (path.fd > -1)
10592 length = flistxattr(path.fd, buffer, buffer_size);
10593 else if (follow_symlinks)
10594 length = listxattr(name, buffer, buffer_size);
10595 else
10596 length = llistxattr(name, buffer, buffer_size);
10597 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010598
Larry Hastings9cf065c2012-06-22 16:30:09 -070010599 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010600 if (errno == ERANGE) {
10601 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010602 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010603 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010604 }
Victor Stinner292c8352012-10-30 02:17:38 +010010605 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010606 break;
10607 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010608
Larry Hastings9cf065c2012-06-22 16:30:09 -070010609 result = PyList_New(0);
10610 if (!result) {
10611 goto exit;
10612 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010613
Larry Hastings9cf065c2012-06-22 16:30:09 -070010614 end = buffer + length;
10615 for (trace = start = buffer; trace != end; trace++) {
10616 if (!*trace) {
10617 int error;
10618 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10619 trace - start);
10620 if (!attribute) {
10621 Py_DECREF(result);
10622 result = NULL;
10623 goto exit;
10624 }
10625 error = PyList_Append(result, attribute);
10626 Py_DECREF(attribute);
10627 if (error) {
10628 Py_DECREF(result);
10629 result = NULL;
10630 goto exit;
10631 }
10632 start = trace + 1;
10633 }
10634 }
10635 break;
10636 }
10637exit:
10638 path_cleanup(&path);
10639 if (buffer)
10640 PyMem_FREE(buffer);
10641 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010642}
10643
Benjamin Peterson9428d532011-09-14 11:45:52 -040010644#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010645
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010646
Georg Brandl2fb477c2012-02-21 00:33:36 +010010647PyDoc_STRVAR(posix_urandom__doc__,
10648"urandom(n) -> str\n\n\
10649Return n random bytes suitable for cryptographic use.");
10650
10651static PyObject *
10652posix_urandom(PyObject *self, PyObject *args)
10653{
10654 Py_ssize_t size;
10655 PyObject *result;
10656 int ret;
10657
10658 /* Read arguments */
10659 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10660 return NULL;
10661 if (size < 0)
10662 return PyErr_Format(PyExc_ValueError,
10663 "negative argument not allowed");
10664 result = PyBytes_FromStringAndSize(NULL, size);
10665 if (result == NULL)
10666 return NULL;
10667
10668 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10669 PyBytes_GET_SIZE(result));
10670 if (ret == -1) {
10671 Py_DECREF(result);
10672 return NULL;
10673 }
10674 return result;
10675}
10676
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010677/* Terminal size querying */
10678
10679static PyTypeObject TerminalSizeType;
10680
10681PyDoc_STRVAR(TerminalSize_docstring,
10682 "A tuple of (columns, lines) for holding terminal window size");
10683
10684static PyStructSequence_Field TerminalSize_fields[] = {
10685 {"columns", "width of the terminal window in characters"},
10686 {"lines", "height of the terminal window in characters"},
10687 {NULL, NULL}
10688};
10689
10690static PyStructSequence_Desc TerminalSize_desc = {
10691 "os.terminal_size",
10692 TerminalSize_docstring,
10693 TerminalSize_fields,
10694 2,
10695};
10696
10697#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10698PyDoc_STRVAR(termsize__doc__,
10699 "Return the size of the terminal window as (columns, lines).\n" \
10700 "\n" \
10701 "The optional argument fd (default standard output) specifies\n" \
10702 "which file descriptor should be queried.\n" \
10703 "\n" \
10704 "If the file descriptor is not connected to a terminal, an OSError\n" \
10705 "is thrown.\n" \
10706 "\n" \
10707 "This function will only be defined if an implementation is\n" \
10708 "available for this system.\n" \
10709 "\n" \
10710 "shutil.get_terminal_size is the high-level function which should \n" \
10711 "normally be used, os.get_terminal_size is the low-level implementation.");
10712
10713static PyObject*
10714get_terminal_size(PyObject *self, PyObject *args)
10715{
10716 int columns, lines;
10717 PyObject *termsize;
10718
10719 int fd = fileno(stdout);
10720 /* Under some conditions stdout may not be connected and
10721 * fileno(stdout) may point to an invalid file descriptor. For example
10722 * GUI apps don't have valid standard streams by default.
10723 *
10724 * If this happens, and the optional fd argument is not present,
10725 * the ioctl below will fail returning EBADF. This is what we want.
10726 */
10727
10728 if (!PyArg_ParseTuple(args, "|i", &fd))
10729 return NULL;
10730
10731#ifdef TERMSIZE_USE_IOCTL
10732 {
10733 struct winsize w;
10734 if (ioctl(fd, TIOCGWINSZ, &w))
10735 return PyErr_SetFromErrno(PyExc_OSError);
10736 columns = w.ws_col;
10737 lines = w.ws_row;
10738 }
10739#endif /* TERMSIZE_USE_IOCTL */
10740
10741#ifdef TERMSIZE_USE_CONIO
10742 {
10743 DWORD nhandle;
10744 HANDLE handle;
10745 CONSOLE_SCREEN_BUFFER_INFO csbi;
10746 switch (fd) {
10747 case 0: nhandle = STD_INPUT_HANDLE;
10748 break;
10749 case 1: nhandle = STD_OUTPUT_HANDLE;
10750 break;
10751 case 2: nhandle = STD_ERROR_HANDLE;
10752 break;
10753 default:
10754 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10755 }
10756 handle = GetStdHandle(nhandle);
10757 if (handle == NULL)
10758 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10759 if (handle == INVALID_HANDLE_VALUE)
10760 return PyErr_SetFromWindowsErr(0);
10761
10762 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10763 return PyErr_SetFromWindowsErr(0);
10764
10765 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10766 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10767 }
10768#endif /* TERMSIZE_USE_CONIO */
10769
10770 termsize = PyStructSequence_New(&TerminalSizeType);
10771 if (termsize == NULL)
10772 return NULL;
10773 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10774 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10775 if (PyErr_Occurred()) {
10776 Py_DECREF(termsize);
10777 return NULL;
10778 }
10779 return termsize;
10780}
10781#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10782
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010783PyDoc_STRVAR(posix_cpu_count__doc__,
10784"cpu_count() -> integer\n\n\
10785Return the number of CPUs in the system, or None if this value cannot be\n\
10786established.");
10787
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010788static PyObject *
10789posix_cpu_count(PyObject *self)
10790{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010791 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010792#ifdef MS_WINDOWS
10793 SYSTEM_INFO sysinfo;
10794 GetSystemInfo(&sysinfo);
10795 ncpu = sysinfo.dwNumberOfProcessors;
10796#elif defined(__hpux)
10797 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10798#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10799 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010800#elif defined(__DragonFly__) || \
10801 defined(__OpenBSD__) || \
10802 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010803 defined(__NetBSD__) || \
10804 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020010805 int mib[2];
10806 size_t len = sizeof(ncpu);
10807 mib[0] = CTL_HW;
10808 mib[1] = HW_NCPU;
10809 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
10810 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010811#endif
10812 if (ncpu >= 1)
10813 return PyLong_FromLong(ncpu);
10814 else
10815 Py_RETURN_NONE;
10816}
10817
Victor Stinnerdaf45552013-08-28 00:53:59 +020010818PyDoc_STRVAR(get_inheritable__doc__,
10819 "get_inheritable(fd) -> bool\n" \
10820 "\n" \
10821 "Get the close-on-exe flag of the specified file descriptor.");
10822
10823static PyObject*
10824posix_get_inheritable(PyObject *self, PyObject *args)
10825{
10826 int fd;
10827 int inheritable;
10828
10829 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd))
10830 return NULL;
10831
10832 if (!_PyVerify_fd(fd))
10833 return posix_error();
10834
10835 inheritable = _Py_get_inheritable(fd);
10836 if (inheritable < 0)
10837 return NULL;
10838 return PyBool_FromLong(inheritable);
10839}
10840
10841PyDoc_STRVAR(set_inheritable__doc__,
10842 "set_inheritable(fd, inheritable)\n" \
10843 "\n" \
10844 "Set the inheritable flag of the specified file descriptor.");
10845
10846static PyObject*
10847posix_set_inheritable(PyObject *self, PyObject *args)
10848{
10849 int fd, inheritable;
10850
10851 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable))
10852 return NULL;
10853
10854 if (!_PyVerify_fd(fd))
10855 return posix_error();
10856
10857 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
10858 return NULL;
10859 Py_RETURN_NONE;
10860}
10861
10862
10863#ifdef MS_WINDOWS
10864PyDoc_STRVAR(get_handle_inheritable__doc__,
10865 "get_handle_inheritable(fd) -> bool\n" \
10866 "\n" \
10867 "Get the close-on-exe flag of the specified file descriptor.");
10868
10869static PyObject*
10870posix_get_handle_inheritable(PyObject *self, PyObject *args)
10871{
10872 Py_intptr_t handle;
10873 DWORD flags;
10874
10875 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle))
10876 return NULL;
10877
10878 if (!GetHandleInformation((HANDLE)handle, &flags)) {
10879 PyErr_SetFromWindowsErr(0);
10880 return NULL;
10881 }
10882
10883 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT);
10884}
10885
10886PyDoc_STRVAR(set_handle_inheritable__doc__,
10887 "set_handle_inheritable(fd, inheritable)\n" \
10888 "\n" \
10889 "Set the inheritable flag of the specified handle.");
10890
10891static PyObject*
10892posix_set_handle_inheritable(PyObject *self, PyObject *args)
10893{
10894 int inheritable = 1;
10895 Py_intptr_t handle;
10896 DWORD flags;
10897
10898 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable",
10899 &handle, &inheritable))
10900 return NULL;
10901
10902 if (inheritable)
10903 flags = HANDLE_FLAG_INHERIT;
10904 else
10905 flags = 0;
10906 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
10907 PyErr_SetFromWindowsErr(0);
10908 return NULL;
10909 }
10910 Py_RETURN_NONE;
10911}
10912#endif /* MS_WINDOWS */
10913
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010914
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010915static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010916 {"access", (PyCFunction)posix_access,
10917 METH_VARARGS | METH_KEYWORDS,
10918 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010919#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010920 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010921#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010922 {"chdir", (PyCFunction)posix_chdir,
10923 METH_VARARGS | METH_KEYWORDS,
10924 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010925#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010926 {"chflags", (PyCFunction)posix_chflags,
10927 METH_VARARGS | METH_KEYWORDS,
10928 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010929#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010930 {"chmod", (PyCFunction)posix_chmod,
10931 METH_VARARGS | METH_KEYWORDS,
10932 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010933#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010934 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010935#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010936#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010937 {"chown", (PyCFunction)posix_chown,
10938 METH_VARARGS | METH_KEYWORDS,
10939 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010940#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010941#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010942 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010943#endif /* HAVE_LCHMOD */
10944#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010945 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010946#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010947#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010948 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010949#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010950#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010951 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010952#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010953#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010954 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010955#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010956#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010958#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010959 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10960 METH_NOARGS, posix_getcwd__doc__},
10961 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10962 METH_NOARGS, posix_getcwdb__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010963#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10964 {"link", (PyCFunction)posix_link,
10965 METH_VARARGS | METH_KEYWORDS,
10966 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010967#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010968 {"listdir", (PyCFunction)posix_listdir,
10969 METH_VARARGS | METH_KEYWORDS,
10970 posix_listdir__doc__},
10971 {"lstat", (PyCFunction)posix_lstat,
10972 METH_VARARGS | METH_KEYWORDS,
10973 posix_lstat__doc__},
10974 {"mkdir", (PyCFunction)posix_mkdir,
10975 METH_VARARGS | METH_KEYWORDS,
10976 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010977#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010978 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010979#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010980#ifdef HAVE_GETPRIORITY
10981 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10982#endif /* HAVE_GETPRIORITY */
10983#ifdef HAVE_SETPRIORITY
10984 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10985#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010986#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010987 {"readlink", (PyCFunction)posix_readlink,
10988 METH_VARARGS | METH_KEYWORDS,
10989 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010990#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010991#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010992 {"readlink", (PyCFunction)win_readlink,
10993 METH_VARARGS | METH_KEYWORDS,
10994 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010995#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010996 {"rename", (PyCFunction)posix_rename,
10997 METH_VARARGS | METH_KEYWORDS,
10998 posix_rename__doc__},
10999 {"replace", (PyCFunction)posix_replace,
11000 METH_VARARGS | METH_KEYWORDS,
11001 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011002 {"rmdir", (PyCFunction)posix_rmdir,
11003 METH_VARARGS | METH_KEYWORDS,
11004 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011005 {"stat", (PyCFunction)posix_stat,
11006 METH_VARARGS | METH_KEYWORDS,
11007 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011008 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011009#if defined(HAVE_SYMLINK)
11010 {"symlink", (PyCFunction)posix_symlink,
11011 METH_VARARGS | METH_KEYWORDS,
11012 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011013#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011014#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011015 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011016#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011017 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011018#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011019 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011020#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011021 {"unlink", (PyCFunction)posix_unlink,
11022 METH_VARARGS | METH_KEYWORDS,
11023 posix_unlink__doc__},
11024 {"remove", (PyCFunction)posix_unlink,
11025 METH_VARARGS | METH_KEYWORDS,
11026 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011027 {"utime", (PyCFunction)posix_utime,
11028 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011029#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011030 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011031#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011033#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011034 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011035 {"execve", (PyCFunction)posix_execve,
11036 METH_VARARGS | METH_KEYWORDS,
11037 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011038#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011039#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011040 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11041 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000011042#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011043#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011045#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011046#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011048#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011049#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011050#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011051 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11052 {"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 +020011053#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011054#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011055 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011056#endif
11057#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011058 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011059#endif
11060#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011061 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011062#endif
11063#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011064 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011065#endif
11066#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011067 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011068#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011069 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011070#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011071 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11072 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11073#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011074#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011075#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011076 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011077#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011078#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011079 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011080#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011081#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011082 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011083#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011084#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011085 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011086#endif /* HAVE_GETEUID */
11087#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011088 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011089#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011090#ifdef HAVE_GETGROUPLIST
11091 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11092#endif
Fred Drakec9680921999-12-13 16:37:25 +000011093#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011094 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011095#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011096 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011097#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011098 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011099#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011100#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011102#endif /* HAVE_GETPPID */
11103#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011105#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011106#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011108#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011109#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011111#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011112#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011114#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011115#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011117#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011118#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11120 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011121#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011122#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011123 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011124#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011125#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011126 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011127#endif /* HAVE_SETEUID */
11128#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011129 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011130#endif /* HAVE_SETEGID */
11131#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011132 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011133#endif /* HAVE_SETREUID */
11134#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011135 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011136#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011137#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011138 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011139#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011140#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011141 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011142#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011143#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011144 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011145#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011146#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011147 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011148#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011149#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011150 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011151#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011152#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011153 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011154#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011155#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011156 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011157#endif /* HAVE_WAIT3 */
11158#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011159 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011160#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011161#if defined(HAVE_WAITID) && !defined(__APPLE__)
11162 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11163#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011164#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011165 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011166#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011167#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011168 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011169#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011170#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011171 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011172#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011173#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011174 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011175#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011176#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011177 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011178#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011179#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011180 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011181#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011182 {"open", (PyCFunction)posix_open,\
11183 METH_VARARGS | METH_KEYWORDS,
11184 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011185 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11186 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11187 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11188 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011189 {"dup2", (PyCFunction)posix_dup2,
11190 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011191#ifdef HAVE_LOCKF
11192 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11193#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011194 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11195 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011196#ifdef HAVE_READV
11197 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11198#endif
11199#ifdef HAVE_PREAD
11200 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11201#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011202 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011203#ifdef HAVE_WRITEV
11204 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11205#endif
11206#ifdef HAVE_PWRITE
11207 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11208#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011209#ifdef HAVE_SENDFILE
11210 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11211 posix_sendfile__doc__},
11212#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011213 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011215#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011216 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011217#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011218#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011219 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011220#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011221#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011222 {"mkfifo", (PyCFunction)posix_mkfifo,
11223 METH_VARARGS | METH_KEYWORDS,
11224 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011225#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011226#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011227 {"mknod", (PyCFunction)posix_mknod,
11228 METH_VARARGS | METH_KEYWORDS,
11229 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011230#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011231#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11233 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11234 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011235#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011236#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011237 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011238#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011239#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011240 {"truncate", (PyCFunction)posix_truncate,
11241 METH_VARARGS | METH_KEYWORDS,
11242 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011243#endif
11244#ifdef HAVE_POSIX_FALLOCATE
11245 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11246#endif
11247#ifdef HAVE_POSIX_FADVISE
11248 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11249#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011250#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011252#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011253#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011254 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011255#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011257#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011258 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011259#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011260#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011261 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011262#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011263#ifdef HAVE_SYNC
11264 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11265#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011266#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011267 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011268#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011269#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011270#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011271 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011272#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011273#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011274 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011275#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011276#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011277 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011278#endif /* WIFSTOPPED */
11279#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011281#endif /* WIFSIGNALED */
11282#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011284#endif /* WIFEXITED */
11285#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011287#endif /* WEXITSTATUS */
11288#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011290#endif /* WTERMSIG */
11291#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011293#endif /* WSTOPSIG */
11294#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011295#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011296 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011297#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011298#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011299 {"statvfs", (PyCFunction)posix_statvfs,
11300 METH_VARARGS | METH_KEYWORDS,
11301 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011302#endif
Fred Drakec9680921999-12-13 16:37:25 +000011303#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011305#endif
11306#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011308#endif
11309#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011311#endif
11312#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011313 {"pathconf", (PyCFunction)posix_pathconf,
11314 METH_VARARGS | METH_KEYWORDS,
11315 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011316#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011317 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011318#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011320 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011321 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011322 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011323 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011324#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011325#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011326 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011327#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011328 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011329#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011330 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011331#endif
11332#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011333 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011334#endif
11335#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011336 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011337#endif
11338#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011339 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011340#endif
11341
Benjamin Peterson9428d532011-09-14 11:45:52 -040011342#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011343 {"setxattr", (PyCFunction)posix_setxattr,
11344 METH_VARARGS | METH_KEYWORDS,
11345 posix_setxattr__doc__},
11346 {"getxattr", (PyCFunction)posix_getxattr,
11347 METH_VARARGS | METH_KEYWORDS,
11348 posix_getxattr__doc__},
11349 {"removexattr", (PyCFunction)posix_removexattr,
11350 METH_VARARGS | METH_KEYWORDS,
11351 posix_removexattr__doc__},
11352 {"listxattr", (PyCFunction)posix_listxattr,
11353 METH_VARARGS | METH_KEYWORDS,
11354 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011355#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011356#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11357 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11358#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011359 {"cpu_count", (PyCFunction)posix_cpu_count,
11360 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011361 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__},
11362 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__},
11363#ifdef MS_WINDOWS
11364 {"get_handle_inheritable", posix_get_handle_inheritable,
11365 METH_VARARGS, get_handle_inheritable__doc__},
11366 {"set_handle_inheritable", posix_set_handle_inheritable,
11367 METH_VARARGS, set_handle_inheritable__doc__},
11368#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011369 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011370};
11371
11372
Brian Curtin52173d42010-12-02 18:29:18 +000011373#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011374static int
Brian Curtin52173d42010-12-02 18:29:18 +000011375enable_symlink()
11376{
11377 HANDLE tok;
11378 TOKEN_PRIVILEGES tok_priv;
11379 LUID luid;
11380 int meth_idx = 0;
11381
11382 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011383 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011384
11385 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011386 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011387
11388 tok_priv.PrivilegeCount = 1;
11389 tok_priv.Privileges[0].Luid = luid;
11390 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11391
11392 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11393 sizeof(TOKEN_PRIVILEGES),
11394 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011395 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011396
Brian Curtin3b4499c2010-12-28 14:31:47 +000011397 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11398 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011399}
11400#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11401
Barry Warsaw4a342091996-12-19 23:50:02 +000011402static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011403all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011404{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011405#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011406 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011407#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011408#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011409 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011410#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011411#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011412 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011413#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011414#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011415 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011416#endif
Fred Drakec9680921999-12-13 16:37:25 +000011417#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011418 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011419#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011420#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011421 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011422#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011423#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011424 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011425#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011426#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011427 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011428#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011429#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011430 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011431#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011432#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011433 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011434#endif
11435#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011436 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011437#endif
11438#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011439 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011440#endif
11441#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011442 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011443#endif
11444#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011445 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011446#endif
11447#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011448 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011449#endif
11450#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011451 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011452#endif
11453#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011454 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011455#endif
11456#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011457 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011458#endif
11459#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011460 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011461#endif
11462#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011463 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011464#endif
11465#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011466 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011467#endif
11468#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011469 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011470#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011471#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011472 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011473#endif
11474#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011475 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011476#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011477#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011478 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011479#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011480#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011481 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011482#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011483#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011484 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011485#endif
11486#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011487 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011488#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011489#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011490 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011491#endif
11492#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011493 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011494#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011495#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011496 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011497#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011498#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011499 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011500#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011501#ifdef O_TMPFILE
11502 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11503#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011504#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011505 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011506#endif
11507#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011508 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011509#endif
11510#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011511 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011512#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011513#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011514 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011515#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011516#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011517 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011518#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011519
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011520
Jesus Cea94363612012-06-22 18:32:07 +020011521#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011522 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011523#endif
11524#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011525 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011526#endif
11527
Tim Peters5aa91602002-01-30 05:46:57 +000011528/* MS Windows */
11529#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011530 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011531 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011532#endif
11533#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011534 /* Optimize for short life (keep in memory). */
11535 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011536 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011537#endif
11538#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011539 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011540 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011541#endif
11542#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011544 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011545#endif
11546#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011547 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011548 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011549#endif
11550
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011551/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011552#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011553 /* Send a SIGIO signal whenever input or output
11554 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011555 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011556#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011557#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011559 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011560#endif
11561#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011562 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011563 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011564#endif
11565#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011566 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011567 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011568#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011569#ifdef O_NOLINKS
11570 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011571 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011572#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011573#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011574 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011575 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011576#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011577
Victor Stinner8c62be82010-05-06 00:08:46 +000011578 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011579#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011580 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011581#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011582#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011583 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011584#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011585#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011586 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011587#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011588#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011589 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011590#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011591#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011592 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011593#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011594#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011595 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011596#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011597#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011598 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011599#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011600#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011601 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011602#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011603#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011604 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011605#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011606#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011607 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011608#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011609#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011610 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011611#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011612#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011613 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011614#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011615#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011616 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011617#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011618#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011619 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011620#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011621#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011622 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011623#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011624#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011625 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011626#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011627#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011628 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011629#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011630
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011631 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011632#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011633 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011634#endif /* ST_RDONLY */
11635#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011636 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011637#endif /* ST_NOSUID */
11638
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011639 /* FreeBSD sendfile() constants */
11640#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011641 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011642#endif
11643#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011644 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011645#endif
11646#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011647 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011648#endif
11649
Ross Lagerwall7807c352011-03-17 20:20:30 +020011650 /* constants for posix_fadvise */
11651#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011652 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011653#endif
11654#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011655 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011656#endif
11657#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011658 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011659#endif
11660#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011661 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011662#endif
11663#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011664 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011665#endif
11666#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011667 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011668#endif
11669
11670 /* constants for waitid */
11671#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011672 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11673 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
11674 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011675#endif
11676#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011677 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011678#endif
11679#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011680 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011681#endif
11682#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011683 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011684#endif
11685#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011686 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011687#endif
11688#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011689 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011690#endif
11691#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011692 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011693#endif
11694#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011695 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011696#endif
11697
11698 /* constants for lockf */
11699#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011700 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011701#endif
11702#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011703 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011704#endif
11705#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011706 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011707#endif
11708#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011709 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011710#endif
11711
Guido van Rossum246bc171999-02-01 23:54:31 +000011712#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011713 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
11714 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
11715 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
11716 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
11717 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011718#endif
11719
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011720#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011721 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
11722 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
11723 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011724#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011725 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011726#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011727#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011728 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011729#endif
11730#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011731 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011732#endif
11733#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011734 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011735#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011736#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011737 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011738#endif
11739#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011740 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011741#endif
11742#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011743 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011744#endif
11745#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011746 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011747#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011748#endif
11749
Benjamin Peterson9428d532011-09-14 11:45:52 -040011750#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011751 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
11752 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
11753 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011754#endif
11755
Victor Stinner8b905bd2011-10-25 13:34:04 +020011756#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011757 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011758#endif
11759#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011760 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011761#endif
11762#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011763 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011764#endif
11765#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011766 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011767#endif
11768#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011769 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011770#endif
11771#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011772 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011773#endif
11774#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011775 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020011776#endif
11777
Victor Stinner8c62be82010-05-06 00:08:46 +000011778 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011779}
11780
11781
Tim Peters5aa91602002-01-30 05:46:57 +000011782#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011783#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011784#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011785
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011786#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011787#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011788#define MODNAME "posix"
11789#endif
11790
Martin v. Löwis1a214512008-06-11 05:26:20 +000011791static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011792 PyModuleDef_HEAD_INIT,
11793 MODNAME,
11794 posix__doc__,
11795 -1,
11796 posix_methods,
11797 NULL,
11798 NULL,
11799 NULL,
11800 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011801};
11802
11803
Larry Hastings9cf065c2012-06-22 16:30:09 -070011804static char *have_functions[] = {
11805
11806#ifdef HAVE_FACCESSAT
11807 "HAVE_FACCESSAT",
11808#endif
11809
11810#ifdef HAVE_FCHDIR
11811 "HAVE_FCHDIR",
11812#endif
11813
11814#ifdef HAVE_FCHMOD
11815 "HAVE_FCHMOD",
11816#endif
11817
11818#ifdef HAVE_FCHMODAT
11819 "HAVE_FCHMODAT",
11820#endif
11821
11822#ifdef HAVE_FCHOWN
11823 "HAVE_FCHOWN",
11824#endif
11825
Larry Hastings00964ed2013-08-12 13:49:30 -040011826#ifdef HAVE_FCHOWNAT
11827 "HAVE_FCHOWNAT",
11828#endif
11829
Larry Hastings9cf065c2012-06-22 16:30:09 -070011830#ifdef HAVE_FEXECVE
11831 "HAVE_FEXECVE",
11832#endif
11833
11834#ifdef HAVE_FDOPENDIR
11835 "HAVE_FDOPENDIR",
11836#endif
11837
Georg Brandl306336b2012-06-24 12:55:33 +020011838#ifdef HAVE_FPATHCONF
11839 "HAVE_FPATHCONF",
11840#endif
11841
Larry Hastings9cf065c2012-06-22 16:30:09 -070011842#ifdef HAVE_FSTATAT
11843 "HAVE_FSTATAT",
11844#endif
11845
11846#ifdef HAVE_FSTATVFS
11847 "HAVE_FSTATVFS",
11848#endif
11849
Georg Brandl306336b2012-06-24 12:55:33 +020011850#ifdef HAVE_FTRUNCATE
11851 "HAVE_FTRUNCATE",
11852#endif
11853
Larry Hastings9cf065c2012-06-22 16:30:09 -070011854#ifdef HAVE_FUTIMENS
11855 "HAVE_FUTIMENS",
11856#endif
11857
11858#ifdef HAVE_FUTIMES
11859 "HAVE_FUTIMES",
11860#endif
11861
11862#ifdef HAVE_FUTIMESAT
11863 "HAVE_FUTIMESAT",
11864#endif
11865
11866#ifdef HAVE_LINKAT
11867 "HAVE_LINKAT",
11868#endif
11869
11870#ifdef HAVE_LCHFLAGS
11871 "HAVE_LCHFLAGS",
11872#endif
11873
11874#ifdef HAVE_LCHMOD
11875 "HAVE_LCHMOD",
11876#endif
11877
11878#ifdef HAVE_LCHOWN
11879 "HAVE_LCHOWN",
11880#endif
11881
11882#ifdef HAVE_LSTAT
11883 "HAVE_LSTAT",
11884#endif
11885
11886#ifdef HAVE_LUTIMES
11887 "HAVE_LUTIMES",
11888#endif
11889
11890#ifdef HAVE_MKDIRAT
11891 "HAVE_MKDIRAT",
11892#endif
11893
11894#ifdef HAVE_MKFIFOAT
11895 "HAVE_MKFIFOAT",
11896#endif
11897
11898#ifdef HAVE_MKNODAT
11899 "HAVE_MKNODAT",
11900#endif
11901
11902#ifdef HAVE_OPENAT
11903 "HAVE_OPENAT",
11904#endif
11905
11906#ifdef HAVE_READLINKAT
11907 "HAVE_READLINKAT",
11908#endif
11909
11910#ifdef HAVE_RENAMEAT
11911 "HAVE_RENAMEAT",
11912#endif
11913
11914#ifdef HAVE_SYMLINKAT
11915 "HAVE_SYMLINKAT",
11916#endif
11917
11918#ifdef HAVE_UNLINKAT
11919 "HAVE_UNLINKAT",
11920#endif
11921
11922#ifdef HAVE_UTIMENSAT
11923 "HAVE_UTIMENSAT",
11924#endif
11925
11926#ifdef MS_WINDOWS
11927 "MS_WINDOWS",
11928#endif
11929
11930 NULL
11931};
11932
11933
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011934PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011935INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011936{
Victor Stinner8c62be82010-05-06 00:08:46 +000011937 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011938 PyObject *list;
11939 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011940
Brian Curtin52173d42010-12-02 18:29:18 +000011941#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011942 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011943#endif
11944
Victor Stinner8c62be82010-05-06 00:08:46 +000011945 m = PyModule_Create(&posixmodule);
11946 if (m == NULL)
11947 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011948
Victor Stinner8c62be82010-05-06 00:08:46 +000011949 /* Initialize environ dictionary */
11950 v = convertenviron();
11951 Py_XINCREF(v);
11952 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11953 return NULL;
11954 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011955
Victor Stinner8c62be82010-05-06 00:08:46 +000011956 if (all_ins(m))
11957 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011958
Victor Stinner8c62be82010-05-06 00:08:46 +000011959 if (setup_confname_tables(m))
11960 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011961
Victor Stinner8c62be82010-05-06 00:08:46 +000011962 Py_INCREF(PyExc_OSError);
11963 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011964
Guido van Rossumb3d39562000-01-31 18:41:26 +000011965#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011966 if (posix_putenv_garbage == NULL)
11967 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011968#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011969
Victor Stinner8c62be82010-05-06 00:08:46 +000011970 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011971#if defined(HAVE_WAITID) && !defined(__APPLE__)
11972 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020011973 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
11974 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011975#endif
11976
Victor Stinner8c62be82010-05-06 00:08:46 +000011977 stat_result_desc.name = MODNAME ".stat_result";
11978 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11979 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11980 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020011981 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
11982 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011983 structseq_new = StatResultType.tp_new;
11984 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011985
Victor Stinner8c62be82010-05-06 00:08:46 +000011986 statvfs_result_desc.name = MODNAME ".statvfs_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020011987 if (PyStructSequence_InitType2(&StatVFSResultType,
11988 &statvfs_result_desc) < 0)
11989 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011990#ifdef NEED_TICKS_PER_SECOND
11991# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011992 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011993# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011994 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011995# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011996 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011997# endif
11998#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011999
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012000#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012001 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012002 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12003 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012004 SchedParamType.tp_new = sched_param_new;
12005#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012006
12007 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012008 if (PyStructSequence_InitType2(&TerminalSizeType,
12009 &TerminalSize_desc) < 0)
12010 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012011 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012012#if defined(HAVE_WAITID) && !defined(__APPLE__)
12013 Py_INCREF((PyObject*) &WaitidResultType);
12014 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12015#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012016 Py_INCREF((PyObject*) &StatResultType);
12017 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12018 Py_INCREF((PyObject*) &StatVFSResultType);
12019 PyModule_AddObject(m, "statvfs_result",
12020 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012021
12022#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012023 Py_INCREF(&SchedParamType);
12024 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012025#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012026
Larry Hastings605a62d2012-06-24 04:33:36 -070012027 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012028 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12029 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012030 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12031
12032 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012033 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12034 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012035 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12036
Thomas Wouters477c8d52006-05-27 19:21:47 +000012037#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012038 /*
12039 * Step 2 of weak-linking support on Mac OS X.
12040 *
12041 * The code below removes functions that are not available on the
12042 * currently active platform.
12043 *
12044 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012045 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012046 * OSX 10.4.
12047 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012048#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012049 if (fstatvfs == NULL) {
12050 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12051 return NULL;
12052 }
12053 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012054#endif /* HAVE_FSTATVFS */
12055
12056#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012057 if (statvfs == NULL) {
12058 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12059 return NULL;
12060 }
12061 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012062#endif /* HAVE_STATVFS */
12063
12064# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012065 if (lchown == NULL) {
12066 if (PyObject_DelAttrString(m, "lchown") == -1) {
12067 return NULL;
12068 }
12069 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012070#endif /* HAVE_LCHOWN */
12071
12072
12073#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012074
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012075 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012076 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12077
Larry Hastings6fe20b32012-04-19 15:07:49 -070012078 billion = PyLong_FromLong(1000000000);
12079 if (!billion)
12080 return NULL;
12081
Larry Hastings9cf065c2012-06-22 16:30:09 -070012082 /* suppress "function not used" warnings */
12083 {
12084 int ignored;
12085 fd_specified("", -1);
12086 follow_symlinks_specified("", 1);
12087 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12088 dir_fd_converter(Py_None, &ignored);
12089 dir_fd_unavailable(Py_None, &ignored);
12090 }
12091
12092 /*
12093 * provide list of locally available functions
12094 * so os.py can populate support_* lists
12095 */
12096 list = PyList_New(0);
12097 if (!list)
12098 return NULL;
12099 for (trace = have_functions; *trace; trace++) {
12100 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12101 if (!unicode)
12102 return NULL;
12103 if (PyList_Append(list, unicode))
12104 return NULL;
12105 Py_DECREF(unicode);
12106 }
12107 PyModule_AddObject(m, "_have_functions", list);
12108
12109 initialized = 1;
12110
Victor Stinner8c62be82010-05-06 00:08:46 +000012111 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000012112}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012113
12114#ifdef __cplusplus
12115}
12116#endif