blob: 04f0d3639cf88d751f9b06eecd66fd7936cc258b [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
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020028#ifndef MS_WINDOWS
29#include "posixmodule.h"
30#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000031
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000032#ifdef __cplusplus
33extern "C" {
34#endif
35
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000036PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000037"This module provides access to operating system functionality that is\n\
38standardized by the C Standard and the POSIX standard (a thinly\n\
39disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000040corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000042
Ross Lagerwall4d076da2011-03-18 06:56:53 +020043#ifdef HAVE_SYS_UIO_H
44#include <sys/uio.h>
45#endif
46
Thomas Wouters0e3f5912006-08-11 14:57:12 +000047#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000048#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049#endif /* HAVE_SYS_TYPES_H */
50
51#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000052#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000053#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000054
Guido van Rossum36bc6801995-06-14 22:54:23 +000055#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000056#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000057#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000058
Thomas Wouters0e3f5912006-08-11 14:57:12 +000059#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000060#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000061#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000062
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#ifdef HAVE_FCNTL_H
64#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000065#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000066
Guido van Rossuma6535fd2001-10-18 19:44:10 +000067#ifdef HAVE_GRP_H
68#include <grp.h>
69#endif
70
Barry Warsaw5676bd12003-01-07 20:57:09 +000071#ifdef HAVE_SYSEXITS_H
72#include <sysexits.h>
73#endif /* HAVE_SYSEXITS_H */
74
Anthony Baxter8a560de2004-10-13 15:30:56 +000075#ifdef HAVE_SYS_LOADAVG_H
76#include <sys/loadavg.h>
77#endif
78
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000079#ifdef HAVE_LANGINFO_H
80#include <langinfo.h>
81#endif
82
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000083#ifdef HAVE_SYS_SENDFILE_H
84#include <sys/sendfile.h>
85#endif
86
Benjamin Peterson94b580d2011-08-02 17:30:04 -050087#ifdef HAVE_SCHED_H
88#include <sched.h>
89#endif
90
Benjamin Peterson2dbda072012-03-16 10:12:55 -050091#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050092#undef HAVE_SCHED_SETAFFINITY
93#endif
94
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +020095#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -040096#define USE_XATTRS
97#endif
98
99#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400100#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400101#endif
102
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000103#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
104#ifdef HAVE_SYS_SOCKET_H
105#include <sys/socket.h>
106#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000107#endif
108
Victor Stinner8b905bd2011-10-25 13:34:04 +0200109#ifdef HAVE_DLFCN_H
110#include <dlfcn.h>
111#endif
112
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200113#ifdef __hpux
114#include <sys/mpctl.h>
115#endif
116
117#if defined(__DragonFly__) || \
118 defined(__OpenBSD__) || \
119 defined(__FreeBSD__) || \
120 defined(__NetBSD__) || \
121 defined(__APPLE__)
122#include <sys/sysctl.h>
123#endif
124
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100125#if defined(MS_WINDOWS)
126# define TERMSIZE_USE_CONIO
127#elif defined(HAVE_SYS_IOCTL_H)
128# include <sys/ioctl.h>
129# if defined(HAVE_TERMIOS_H)
130# include <termios.h>
131# endif
132# if defined(TIOCGWINSZ)
133# define TERMSIZE_USE_IOCTL
134# endif
135#endif /* MS_WINDOWS */
136
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000138/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000139#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000141#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142#include <process.h>
143#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#define HAVE_EXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#define HAVE_OPENDIR 1
147#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000148#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_WAIT 1
150#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000152#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000153#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000154#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#define HAVE_EXECV 1
156#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000157#define HAVE_SYSTEM 1
158#define HAVE_CWAIT 1
159#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000160#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000161#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162/* Unix functions that the configure script doesn't check for */
163#define HAVE_EXECV 1
164#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000166#define HAVE_FORK1 1
167#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#define HAVE_GETEGID 1
169#define HAVE_GETEUID 1
170#define HAVE_GETGID 1
171#define HAVE_GETPPID 1
172#define HAVE_GETUID 1
173#define HAVE_KILL 1
174#define HAVE_OPENDIR 1
175#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000176#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000178#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000179#endif /* _MSC_VER */
180#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000181#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000182
Victor Stinnera2f7c002012-02-08 03:36:25 +0100183
Larry Hastings61272b72014-01-07 12:41:53 -0800184/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800185module os
Larry Hastings61272b72014-01-07 12:41:53 -0800186[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -0800187/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8cff096d1133288f]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100188
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000189#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000190
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000191#if defined(__sgi)&&_COMPILER_VERSION>=700
192/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
193 (default) */
194extern char *ctermid_r(char *);
195#endif
196
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000197#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000198#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000199extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000200#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000201#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000202extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000205#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#endif
207#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int chdir(char *);
209extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000210#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000211extern int chdir(const char *);
212extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000213#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000214#ifdef __BORLANDC__
215extern int chmod(const char *, int);
216#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000218#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000219/*#ifdef HAVE_FCHMOD
220extern int fchmod(int, mode_t);
221#endif*/
222/*#ifdef HAVE_LCHMOD
223extern int lchmod(const char *, mode_t);
224#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int chown(const char *, uid_t, gid_t);
226extern char *getcwd(char *, int);
227extern char *strerror(int);
228extern int link(const char *, const char *);
229extern int rename(const char *, const char *);
230extern int stat(const char *, struct stat *);
231extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000233extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000234#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000236extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000237#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000239
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#ifdef HAVE_UTIME_H
243#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000246#ifdef HAVE_SYS_UTIME_H
247#include <sys/utime.h>
248#define HAVE_UTIME_H /* pretend we do for the rest of this file */
249#endif /* HAVE_SYS_UTIME_H */
250
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#ifdef HAVE_SYS_TIMES_H
252#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
255#ifdef HAVE_SYS_PARAM_H
256#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258
259#ifdef HAVE_SYS_UTSNAME_H
260#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000261#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000263#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000265#define NAMLEN(dirent) strlen((dirent)->d_name)
266#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000267#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000268#include <direct.h>
269#define NAMLEN(dirent) strlen((dirent)->d_name)
270#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000273#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#endif
277#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000279#endif
280#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#endif
283#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000285#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000286#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000288#endif
289#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000291#endif
292#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000295#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000296#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000297#endif
298#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000299#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000300#endif
301#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000302#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000303#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000304#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000305#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000306#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000307#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000308#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000309#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
310#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000311static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000312#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000313#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000314
Tim Petersbc2e10e2002-03-03 23:17:02 +0000315#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000316#if defined(PATH_MAX) && PATH_MAX > 1024
317#define MAXPATHLEN PATH_MAX
318#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000319#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000321#endif /* MAXPATHLEN */
322
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000323#ifdef UNION_WAIT
324/* Emulate some macros on systems that have a union instead of macros */
325
326#ifndef WIFEXITED
327#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
328#endif
329
330#ifndef WEXITSTATUS
331#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
332#endif
333
334#ifndef WTERMSIG
335#define WTERMSIG(u_wait) ((u_wait).w_termsig)
336#endif
337
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000338#define WAIT_TYPE union wait
339#define WAIT_STATUS_INT(s) (s.w_status)
340
341#else /* !UNION_WAIT */
342#define WAIT_TYPE int
343#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000344#endif /* UNION_WAIT */
345
Greg Wardb48bc172000-03-01 21:51:56 +0000346/* Don't use the "_r" form if we don't need it (also, won't have a
347 prototype for it, at least on Solaris -- maybe others as well?). */
348#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
349#define USE_CTERMID_R
350#endif
351
Fred Drake699f3522000-06-29 21:12:41 +0000352/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000353#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000354#undef FSTAT
355#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200356#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000357# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700358# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000359# define FSTAT win32_fstat
360# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000361#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000362# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700363# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000364# define FSTAT fstat
365# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000366#endif
367
Tim Peters11b23062003-04-23 02:39:17 +0000368#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000369#include <sys/mkdev.h>
370#else
371#if defined(MAJOR_IN_SYSMACROS)
372#include <sys/sysmacros.h>
373#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000374#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
375#include <sys/mkdev.h>
376#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000377#endif
Fred Drake699f3522000-06-29 21:12:41 +0000378
Victor Stinner6edddfa2013-11-24 19:22:57 +0100379#define DWORD_MAX 4294967295U
380
Larry Hastings9cf065c2012-06-22 16:30:09 -0700381
382#ifdef MS_WINDOWS
383static int
384win32_warn_bytes_api()
385{
386 return PyErr_WarnEx(PyExc_DeprecationWarning,
387 "The Windows bytes API has been deprecated, "
388 "use Unicode filenames instead",
389 1);
390}
391#endif
392
393
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200394#ifndef MS_WINDOWS
395PyObject *
396_PyLong_FromUid(uid_t uid)
397{
398 if (uid == (uid_t)-1)
399 return PyLong_FromLong(-1);
400 return PyLong_FromUnsignedLong(uid);
401}
402
403PyObject *
404_PyLong_FromGid(gid_t gid)
405{
406 if (gid == (gid_t)-1)
407 return PyLong_FromLong(-1);
408 return PyLong_FromUnsignedLong(gid);
409}
410
411int
412_Py_Uid_Converter(PyObject *obj, void *p)
413{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700414 uid_t uid;
415 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200416 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200417 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700418 unsigned long uresult;
419
420 index = PyNumber_Index(obj);
421 if (index == NULL) {
422 PyErr_Format(PyExc_TypeError,
423 "uid should be integer, not %.200s",
424 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200425 return 0;
426 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700427
428 /*
429 * Handling uid_t is complicated for two reasons:
430 * * Although uid_t is (always?) unsigned, it still
431 * accepts -1.
432 * * We don't know its size in advance--it may be
433 * bigger than an int, or it may be smaller than
434 * a long.
435 *
436 * So a bit of defensive programming is in order.
437 * Start with interpreting the value passed
438 * in as a signed long and see if it works.
439 */
440
441 result = PyLong_AsLongAndOverflow(index, &overflow);
442
443 if (!overflow) {
444 uid = (uid_t)result;
445
446 if (result == -1) {
447 if (PyErr_Occurred())
448 goto fail;
449 /* It's a legitimate -1, we're done. */
450 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200451 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700452
453 /* Any other negative number is disallowed. */
454 if (result < 0)
455 goto underflow;
456
457 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200458 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700459 (long)uid != result)
460 goto underflow;
461 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200462 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700463
464 if (overflow < 0)
465 goto underflow;
466
467 /*
468 * Okay, the value overflowed a signed long. If it
469 * fits in an *unsigned* long, it may still be okay,
470 * as uid_t may be unsigned long on this platform.
471 */
472 uresult = PyLong_AsUnsignedLong(index);
473 if (PyErr_Occurred()) {
474 if (PyErr_ExceptionMatches(PyExc_OverflowError))
475 goto overflow;
476 goto fail;
477 }
478
479 uid = (uid_t)uresult;
480
481 /*
482 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
483 * but this value would get interpreted as (uid_t)-1 by chown
484 * and its siblings. That's not what the user meant! So we
485 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100486 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700487 */
488 if (uid == (uid_t)-1)
489 goto overflow;
490
491 /* Ensure the value wasn't truncated. */
492 if (sizeof(uid_t) < sizeof(long) &&
493 (unsigned long)uid != uresult)
494 goto overflow;
495 /* fallthrough */
496
497success:
498 Py_DECREF(index);
499 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200500 return 1;
501
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700502underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200503 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700504 "uid is less than minimum");
505 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200506
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700507overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200508 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700509 "uid is greater than maximum");
510 /* fallthrough */
511
512fail:
513 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200514 return 0;
515}
516
517int
518_Py_Gid_Converter(PyObject *obj, void *p)
519{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700520 gid_t gid;
521 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200522 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200523 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524 unsigned long uresult;
525
526 index = PyNumber_Index(obj);
527 if (index == NULL) {
528 PyErr_Format(PyExc_TypeError,
529 "gid should be integer, not %.200s",
530 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200531 return 0;
532 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533
534 /*
535 * Handling gid_t is complicated for two reasons:
536 * * Although gid_t is (always?) unsigned, it still
537 * accepts -1.
538 * * We don't know its size in advance--it may be
539 * bigger than an int, or it may be smaller than
540 * a long.
541 *
542 * So a bit of defensive programming is in order.
543 * Start with interpreting the value passed
544 * in as a signed long and see if it works.
545 */
546
547 result = PyLong_AsLongAndOverflow(index, &overflow);
548
549 if (!overflow) {
550 gid = (gid_t)result;
551
552 if (result == -1) {
553 if (PyErr_Occurred())
554 goto fail;
555 /* It's a legitimate -1, we're done. */
556 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200557 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700558
559 /* Any other negative number is disallowed. */
560 if (result < 0) {
561 goto underflow;
562 }
563
564 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200565 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700566 (long)gid != result)
567 goto underflow;
568 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200569 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700570
571 if (overflow < 0)
572 goto underflow;
573
574 /*
575 * Okay, the value overflowed a signed long. If it
576 * fits in an *unsigned* long, it may still be okay,
577 * as gid_t may be unsigned long on this platform.
578 */
579 uresult = PyLong_AsUnsignedLong(index);
580 if (PyErr_Occurred()) {
581 if (PyErr_ExceptionMatches(PyExc_OverflowError))
582 goto overflow;
583 goto fail;
584 }
585
586 gid = (gid_t)uresult;
587
588 /*
589 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
590 * but this value would get interpreted as (gid_t)-1 by chown
591 * and its siblings. That's not what the user meant! So we
592 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100593 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700594 */
595 if (gid == (gid_t)-1)
596 goto overflow;
597
598 /* Ensure the value wasn't truncated. */
599 if (sizeof(gid_t) < sizeof(long) &&
600 (unsigned long)gid != uresult)
601 goto overflow;
602 /* fallthrough */
603
604success:
605 Py_DECREF(index);
606 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200607 return 1;
608
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700609underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200610 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700611 "gid is less than minimum");
612 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200613
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700614overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200615 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616 "gid is greater than maximum");
617 /* fallthrough */
618
619fail:
620 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200621 return 0;
622}
623#endif /* MS_WINDOWS */
624
625
Gregory P. Smith702dada2015-01-28 16:07:52 -0800626#ifdef HAVE_LONG_LONG
627# define _PyLong_FromDev PyLong_FromLongLong
628#else
629# define _PyLong_FromDev PyLong_FromLong
630#endif
631
632
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200633#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
634static int
635_Py_Dev_Converter(PyObject *obj, void *p)
636{
637#ifdef HAVE_LONG_LONG
638 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
639#else
640 *((dev_t *)p) = PyLong_AsUnsignedLong(obj);
641#endif
642 if (PyErr_Occurred())
643 return 0;
644 return 1;
645}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800646#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200647
648
Larry Hastings9cf065c2012-06-22 16:30:09 -0700649#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400650/*
651 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
652 * without the int cast, the value gets interpreted as uint (4291925331),
653 * which doesn't play nicely with all the initializer lines in this file that
654 * look like this:
655 * int dir_fd = DEFAULT_DIR_FD;
656 */
657#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700658#else
659#define DEFAULT_DIR_FD (-100)
660#endif
661
662static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200663_fd_converter(PyObject *o, int *p, const char *allowed)
664{
665 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700666 long long_value;
667
668 PyObject *index = PyNumber_Index(o);
669 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200670 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700671 "argument should be %s, not %.200s",
672 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700673 return 0;
674 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700675
676 long_value = PyLong_AsLongAndOverflow(index, &overflow);
677 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200678 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700679 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700681 return 0;
682 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200683 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700684 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700685 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700686 return 0;
687 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700688
Larry Hastings9cf065c2012-06-22 16:30:09 -0700689 *p = (int)long_value;
690 return 1;
691}
692
693static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200694dir_fd_converter(PyObject *o, void *p)
695{
696 if (o == Py_None) {
697 *(int *)p = DEFAULT_DIR_FD;
698 return 1;
699 }
700 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700701}
702
703
704
705/*
706 * A PyArg_ParseTuple "converter" function
707 * that handles filesystem paths in the manner
708 * preferred by the os module.
709 *
710 * path_converter accepts (Unicode) strings and their
711 * subclasses, and bytes and their subclasses. What
712 * it does with the argument depends on the platform:
713 *
714 * * On Windows, if we get a (Unicode) string we
715 * extract the wchar_t * and return it; if we get
716 * bytes we extract the char * and return that.
717 *
718 * * On all other platforms, strings are encoded
719 * to bytes using PyUnicode_FSConverter, then we
720 * extract the char * from the bytes object and
721 * return that.
722 *
723 * path_converter also optionally accepts signed
724 * integers (representing open file descriptors) instead
725 * of path strings.
726 *
727 * Input fields:
728 * path.nullable
729 * If nonzero, the path is permitted to be None.
730 * path.allow_fd
731 * If nonzero, the path is permitted to be a file handle
732 * (a signed int) instead of a string.
733 * path.function_name
734 * If non-NULL, path_converter will use that as the name
735 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700736 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700737 * path.argument_name
738 * If non-NULL, path_converter will use that as the name
739 * of the parameter in error messages.
740 * (If path.argument_name is NULL it uses "path".)
741 *
742 * Output fields:
743 * path.wide
744 * Points to the path if it was expressed as Unicode
745 * and was not encoded. (Only used on Windows.)
746 * path.narrow
747 * Points to the path if it was expressed as bytes,
748 * or it was Unicode and was encoded to bytes.
749 * path.fd
750 * Contains a file descriptor if path.accept_fd was true
751 * and the caller provided a signed integer instead of any
752 * sort of string.
753 *
754 * WARNING: if your "path" parameter is optional, and is
755 * unspecified, path_converter will never get called.
756 * So if you set allow_fd, you *MUST* initialize path.fd = -1
757 * yourself!
758 * path.length
759 * The length of the path in characters, if specified as
760 * a string.
761 * path.object
762 * The original object passed in.
763 * path.cleanup
764 * For internal use only. May point to a temporary object.
765 * (Pay no attention to the man behind the curtain.)
766 *
767 * At most one of path.wide or path.narrow will be non-NULL.
768 * If path was None and path.nullable was set,
769 * or if path was an integer and path.allow_fd was set,
770 * both path.wide and path.narrow will be NULL
771 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200772 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700773 * path_converter takes care to not write to the path_t
774 * unless it's successful. However it must reset the
775 * "cleanup" field each time it's called.
776 *
777 * Use as follows:
778 * path_t path;
779 * memset(&path, 0, sizeof(path));
780 * PyArg_ParseTuple(args, "O&", path_converter, &path);
781 * // ... use values from path ...
782 * path_cleanup(&path);
783 *
784 * (Note that if PyArg_Parse fails you don't need to call
785 * path_cleanup(). However it is safe to do so.)
786 */
787typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100788 const char *function_name;
789 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700790 int nullable;
791 int allow_fd;
792 wchar_t *wide;
793 char *narrow;
794 int fd;
795 Py_ssize_t length;
796 PyObject *object;
797 PyObject *cleanup;
798} path_t;
799
Larry Hastings31826802013-10-19 00:09:25 -0700800#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \
801 {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL}
802
Larry Hastings9cf065c2012-06-22 16:30:09 -0700803static void
804path_cleanup(path_t *path) {
805 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200806 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700807 }
808}
809
810static int
811path_converter(PyObject *o, void *p) {
812 path_t *path = (path_t *)p;
813 PyObject *unicode, *bytes;
814 Py_ssize_t length;
815 char *narrow;
816
817#define FORMAT_EXCEPTION(exc, fmt) \
818 PyErr_Format(exc, "%s%s" fmt, \
819 path->function_name ? path->function_name : "", \
820 path->function_name ? ": " : "", \
821 path->argument_name ? path->argument_name : "path")
822
823 /* Py_CLEANUP_SUPPORTED support */
824 if (o == NULL) {
825 path_cleanup(path);
826 return 1;
827 }
828
829 /* ensure it's always safe to call path_cleanup() */
830 path->cleanup = NULL;
831
832 if (o == Py_None) {
833 if (!path->nullable) {
834 FORMAT_EXCEPTION(PyExc_TypeError,
835 "can't specify None for %s argument");
836 return 0;
837 }
838 path->wide = NULL;
839 path->narrow = NULL;
840 path->length = 0;
841 path->object = o;
842 path->fd = -1;
843 return 1;
844 }
845
846 unicode = PyUnicode_FromObject(o);
847 if (unicode) {
848#ifdef MS_WINDOWS
849 wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100850
851 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
852 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700853 Py_DECREF(unicode);
854 return 0;
855 }
Victor Stinner59799a82013-11-13 14:17:30 +0100856 if (length > 32767) {
857 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700858 Py_DECREF(unicode);
859 return 0;
860 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300861 if (wcslen(wide) != length) {
862 FORMAT_EXCEPTION(PyExc_TypeError, "embedded null character");
863 Py_DECREF(unicode);
864 return 0;
865 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700866
867 path->wide = wide;
868 path->narrow = NULL;
869 path->length = length;
870 path->object = o;
871 path->fd = -1;
872 path->cleanup = unicode;
873 return Py_CLEANUP_SUPPORTED;
874#else
875 int converted = PyUnicode_FSConverter(unicode, &bytes);
876 Py_DECREF(unicode);
877 if (!converted)
878 bytes = NULL;
879#endif
880 }
881 else {
882 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200883 if (PyObject_CheckBuffer(o))
884 bytes = PyBytes_FromObject(o);
885 else
886 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700887 if (!bytes) {
888 PyErr_Clear();
889 if (path->allow_fd) {
890 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200891 int result = _fd_converter(o, &fd,
892 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700893 if (result) {
894 path->wide = NULL;
895 path->narrow = NULL;
896 path->length = 0;
897 path->object = o;
898 path->fd = fd;
899 return result;
900 }
901 }
902 }
903 }
904
905 if (!bytes) {
906 if (!PyErr_Occurred())
907 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
908 return 0;
909 }
910
911#ifdef MS_WINDOWS
912 if (win32_warn_bytes_api()) {
913 Py_DECREF(bytes);
914 return 0;
915 }
916#endif
917
918 length = PyBytes_GET_SIZE(bytes);
919#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100920 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700921 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
922 Py_DECREF(bytes);
923 return 0;
924 }
925#endif
926
927 narrow = PyBytes_AS_STRING(bytes);
928 if (length != strlen(narrow)) {
929 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
930 Py_DECREF(bytes);
931 return 0;
932 }
933
934 path->wide = NULL;
935 path->narrow = narrow;
936 path->length = length;
937 path->object = o;
938 path->fd = -1;
939 path->cleanup = bytes;
940 return Py_CLEANUP_SUPPORTED;
941}
942
943static void
944argument_unavailable_error(char *function_name, char *argument_name) {
945 PyErr_Format(PyExc_NotImplementedError,
946 "%s%s%s unavailable on this platform",
947 (function_name != NULL) ? function_name : "",
948 (function_name != NULL) ? ": ": "",
949 argument_name);
950}
951
952static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200953dir_fd_unavailable(PyObject *o, void *p)
954{
955 int dir_fd;
956 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700957 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200958 if (dir_fd != DEFAULT_DIR_FD) {
959 argument_unavailable_error(NULL, "dir_fd");
960 return 0;
961 }
962 *(int *)p = dir_fd;
963 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700964}
965
966static int
967fd_specified(char *function_name, int fd) {
968 if (fd == -1)
969 return 0;
970
971 argument_unavailable_error(function_name, "fd");
972 return 1;
973}
974
975static int
976follow_symlinks_specified(char *function_name, int follow_symlinks) {
977 if (follow_symlinks)
978 return 0;
979
980 argument_unavailable_error(function_name, "follow_symlinks");
981 return 1;
982}
983
984static int
985path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
986 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
987 PyErr_Format(PyExc_ValueError,
988 "%s: can't specify dir_fd without matching path",
989 function_name);
990 return 1;
991 }
992 return 0;
993}
994
995static int
996dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
997 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
998 PyErr_Format(PyExc_ValueError,
999 "%s: can't specify both dir_fd and fd",
1000 function_name);
1001 return 1;
1002 }
1003 return 0;
1004}
1005
1006static int
1007fd_and_follow_symlinks_invalid(char *function_name, int fd,
1008 int follow_symlinks) {
1009 if ((fd > 0) && (!follow_symlinks)) {
1010 PyErr_Format(PyExc_ValueError,
1011 "%s: cannot use fd and follow_symlinks together",
1012 function_name);
1013 return 1;
1014 }
1015 return 0;
1016}
1017
1018static int
1019dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
1020 int follow_symlinks) {
1021 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1022 PyErr_Format(PyExc_ValueError,
1023 "%s: cannot use dir_fd and follow_symlinks together",
1024 function_name);
1025 return 1;
1026 }
1027 return 0;
1028}
1029
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001030/* A helper used by a number of POSIX-only functions */
1031#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +00001032static int
1033_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001034{
1035#if !defined(HAVE_LARGEFILE_SUPPORT)
1036 *((off_t*)addr) = PyLong_AsLong(arg);
1037#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +00001038 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001039#endif
1040 if (PyErr_Occurred())
1041 return 0;
1042 return 1;
1043}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001044#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001045
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001046#if defined _MSC_VER && _MSC_VER >= 1400
1047/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +02001048 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001049 * Normally, an invalid fd is likely to be a C program error and therefore
1050 * an assertion can be useful, but it does contradict the POSIX standard
1051 * which for write(2) states:
1052 * "Otherwise, -1 shall be returned and errno set to indicate the error."
1053 * "[EBADF] The fildes argument is not a valid file descriptor open for
1054 * writing."
1055 * Furthermore, python allows the user to enter any old integer
1056 * as a fd and should merely raise a python exception on error.
1057 * The Microsoft CRT doesn't provide an official way to check for the
1058 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +00001059 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001060 * internal structures involved.
1061 * The structures below must be updated for each version of visual studio
1062 * according to the file internal.h in the CRT source, until MS comes
1063 * up with a less hacky way to do this.
1064 * (all of this is to avoid globally modifying the CRT behaviour using
1065 * _set_invalid_parameter_handler() and _CrtSetReportMode())
1066 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001067/* The actual size of the structure is determined at runtime.
1068 * Only the first items must be present.
1069 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001070typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +00001071 intptr_t osfhnd;
1072 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001073} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001074
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001075extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001076#define IOINFO_L2E 5
1077#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
1078#define IOINFO_ARRAYS 64
1079#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
1080#define FOPEN 0x01
1081#define _NO_CONSOLE_FILENO (intptr_t)-2
1082
1083/* This function emulates what the windows CRT does to validate file handles */
1084int
1085_PyVerify_fd(int fd)
1086{
Victor Stinner8c62be82010-05-06 00:08:46 +00001087 const int i1 = fd >> IOINFO_L2E;
1088 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001089
Antoine Pitrou22e41552010-08-15 18:07:50 +00001090 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001091
Victor Stinner8c62be82010-05-06 00:08:46 +00001092 /* Determine the actual size of the ioinfo structure,
1093 * as used by the CRT loaded in memory
1094 */
1095 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
1096 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
1097 }
1098 if (sizeof_ioinfo == 0) {
1099 /* This should not happen... */
1100 goto fail;
1101 }
1102
1103 /* See that it isn't a special CLEAR fileno */
1104 if (fd != _NO_CONSOLE_FILENO) {
1105 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
1106 * we check pointer validity and other info
1107 */
1108 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
1109 /* finally, check that the file is open */
1110 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
1111 if (info->osfile & FOPEN) {
1112 return 1;
1113 }
1114 }
1115 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001116 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001117 errno = EBADF;
1118 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001119}
1120
1121/* the special case of checking dup2. The target fd must be in a sensible range */
1122static int
1123_PyVerify_fd_dup2(int fd1, int fd2)
1124{
Victor Stinner8c62be82010-05-06 00:08:46 +00001125 if (!_PyVerify_fd(fd1))
1126 return 0;
1127 if (fd2 == _NO_CONSOLE_FILENO)
1128 return 0;
1129 if ((unsigned)fd2 < _NHANDLE_)
1130 return 1;
1131 else
1132 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001133}
1134#else
1135/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1136#define _PyVerify_fd_dup2(A, B) (1)
1137#endif
1138
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001139#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001140/* The following structure was copied from
1141 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1142 include doesn't seem to be present in the Windows SDK (at least as included
1143 with Visual Studio Express). */
1144typedef struct _REPARSE_DATA_BUFFER {
1145 ULONG ReparseTag;
1146 USHORT ReparseDataLength;
1147 USHORT Reserved;
1148 union {
1149 struct {
1150 USHORT SubstituteNameOffset;
1151 USHORT SubstituteNameLength;
1152 USHORT PrintNameOffset;
1153 USHORT PrintNameLength;
1154 ULONG Flags;
1155 WCHAR PathBuffer[1];
1156 } SymbolicLinkReparseBuffer;
1157
1158 struct {
1159 USHORT SubstituteNameOffset;
1160 USHORT SubstituteNameLength;
1161 USHORT PrintNameOffset;
1162 USHORT PrintNameLength;
1163 WCHAR PathBuffer[1];
1164 } MountPointReparseBuffer;
1165
1166 struct {
1167 UCHAR DataBuffer[1];
1168 } GenericReparseBuffer;
1169 };
1170} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1171
1172#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1173 GenericReparseBuffer)
1174#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1175
1176static int
Brian Curtind25aef52011-06-13 15:16:04 -05001177win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001178{
1179 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1180 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1181 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001182
1183 if (0 == DeviceIoControl(
1184 reparse_point_handle,
1185 FSCTL_GET_REPARSE_POINT,
1186 NULL, 0, /* in buffer */
1187 target_buffer, sizeof(target_buffer),
1188 &n_bytes_returned,
1189 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001190 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001191
1192 if (reparse_tag)
1193 *reparse_tag = rdb->ReparseTag;
1194
Brian Curtind25aef52011-06-13 15:16:04 -05001195 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001196}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001197
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001198#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001199
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001200/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001201#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001202/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001203** environ directly, we must obtain it with _NSGetEnviron(). See also
1204** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001205*/
1206#include <crt_externs.h>
1207static char **environ;
1208#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001209extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001210#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211
Barry Warsaw53699e91996-12-10 23:23:01 +00001212static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001213convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001214{
Victor Stinner8c62be82010-05-06 00:08:46 +00001215 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001216#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001217 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001218#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001219 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001220#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001221
Victor Stinner8c62be82010-05-06 00:08:46 +00001222 d = PyDict_New();
1223 if (d == NULL)
1224 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001225#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001226 if (environ == NULL)
1227 environ = *_NSGetEnviron();
1228#endif
1229#ifdef MS_WINDOWS
1230 /* _wenviron must be initialized in this way if the program is started
1231 through main() instead of wmain(). */
1232 _wgetenv(L"");
1233 if (_wenviron == NULL)
1234 return d;
1235 /* This part ignores errors */
1236 for (e = _wenviron; *e != NULL; e++) {
1237 PyObject *k;
1238 PyObject *v;
1239 wchar_t *p = wcschr(*e, L'=');
1240 if (p == NULL)
1241 continue;
1242 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1243 if (k == NULL) {
1244 PyErr_Clear();
1245 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001246 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001247 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1248 if (v == NULL) {
1249 PyErr_Clear();
1250 Py_DECREF(k);
1251 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001252 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001253 if (PyDict_GetItem(d, k) == NULL) {
1254 if (PyDict_SetItem(d, k, v) != 0)
1255 PyErr_Clear();
1256 }
1257 Py_DECREF(k);
1258 Py_DECREF(v);
1259 }
1260#else
1261 if (environ == NULL)
1262 return d;
1263 /* This part ignores errors */
1264 for (e = environ; *e != NULL; e++) {
1265 PyObject *k;
1266 PyObject *v;
1267 char *p = strchr(*e, '=');
1268 if (p == NULL)
1269 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001270 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001271 if (k == NULL) {
1272 PyErr_Clear();
1273 continue;
1274 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001275 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001276 if (v == NULL) {
1277 PyErr_Clear();
1278 Py_DECREF(k);
1279 continue;
1280 }
1281 if (PyDict_GetItem(d, k) == NULL) {
1282 if (PyDict_SetItem(d, k, v) != 0)
1283 PyErr_Clear();
1284 }
1285 Py_DECREF(k);
1286 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001287 }
1288#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001289 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001290}
1291
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001292/* Set a POSIX-specific error from errno, and return NULL */
1293
Barry Warsawd58d7641998-07-23 16:14:40 +00001294static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001295posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001296{
Victor Stinner8c62be82010-05-06 00:08:46 +00001297 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001298}
Mark Hammondef8b6542001-05-13 08:04:26 +00001299
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001300#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001301static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001302win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001303{
Victor Stinner8c62be82010-05-06 00:08:46 +00001304 /* XXX We should pass the function name along in the future.
1305 (winreg.c also wants to pass the function name.)
1306 This would however require an additional param to the
1307 Windows error object, which is non-trivial.
1308 */
1309 errno = GetLastError();
1310 if (filename)
1311 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1312 else
1313 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001314}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001315
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001316static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001317win32_error_object(char* function, PyObject* filename)
1318{
1319 /* XXX - see win32_error for comments on 'function' */
1320 errno = GetLastError();
1321 if (filename)
1322 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001323 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001324 errno,
1325 filename);
1326 else
1327 return PyErr_SetFromWindowsErr(errno);
1328}
1329
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001330#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331
Larry Hastings9cf065c2012-06-22 16:30:09 -07001332static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001333path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001334{
1335#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001336 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1337 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001338#else
Victor Stinner292c8352012-10-30 02:17:38 +01001339 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001340#endif
1341}
1342
Larry Hastings31826802013-10-19 00:09:25 -07001343
Larry Hastingsb0827312014-02-09 22:05:19 -08001344static PyObject *
1345path_error2(path_t *path, path_t *path2)
1346{
1347#ifdef MS_WINDOWS
1348 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1349 0, path->object, path2->object);
1350#else
1351 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1352 path->object, path2->object);
1353#endif
1354}
1355
1356
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001357/* POSIX generic methods */
1358
Barry Warsaw53699e91996-12-10 23:23:01 +00001359static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001360posix_fildes(PyObject *fdobj, int (*func)(int))
1361{
Victor Stinner8c62be82010-05-06 00:08:46 +00001362 int fd;
1363 int res;
1364 fd = PyObject_AsFileDescriptor(fdobj);
1365 if (fd < 0)
1366 return NULL;
1367 if (!_PyVerify_fd(fd))
1368 return posix_error();
1369 Py_BEGIN_ALLOW_THREADS
1370 res = (*func)(fd);
1371 Py_END_ALLOW_THREADS
1372 if (res < 0)
1373 return posix_error();
1374 Py_INCREF(Py_None);
1375 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001376}
Guido van Rossum21142a01999-01-08 21:05:37 +00001377
1378static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001379posix_1str(const char *func_name, PyObject *args, char *format,
1380 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001381{
Victor Stinner292c8352012-10-30 02:17:38 +01001382 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001383 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001384 memset(&path, 0, sizeof(path));
1385 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001386 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001387 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001388 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001389 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001390 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001391 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001392 if (res < 0) {
1393 path_error(&path);
1394 path_cleanup(&path);
1395 return NULL;
1396 }
1397 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001398 Py_INCREF(Py_None);
1399 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001400}
1401
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001402
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001403#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001404/* This is a reimplementation of the C library's chdir function,
1405 but one that produces Win32 errors instead of DOS error codes.
1406 chdir is essentially a wrapper around SetCurrentDirectory; however,
1407 it also needs to set "magic" environment variables indicating
1408 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001409static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001410win32_chdir(LPCSTR path)
1411{
Victor Stinner75875072013-11-24 19:23:25 +01001412 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 int result;
1414 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001415
Victor Stinner8c62be82010-05-06 00:08:46 +00001416 if(!SetCurrentDirectoryA(path))
1417 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001418 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001419 if (!result)
1420 return FALSE;
1421 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001422 than MAX_PATH-1 (not including the final null character). */
1423 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001424 if (strncmp(new_path, "\\\\", 2) == 0 ||
1425 strncmp(new_path, "//", 2) == 0)
1426 /* UNC path, nothing to do. */
1427 return TRUE;
1428 env[1] = new_path[0];
1429 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001430}
1431
1432/* The Unicode version differs from the ANSI version
1433 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001434static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001435win32_wchdir(LPCWSTR path)
1436{
Victor Stinner75875072013-11-24 19:23:25 +01001437 wchar_t _new_path[MAX_PATH], *new_path = _new_path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001438 int result;
1439 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001440
Victor Stinner8c62be82010-05-06 00:08:46 +00001441 if(!SetCurrentDirectoryW(path))
1442 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001443 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001444 if (!result)
1445 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001446 if (result > Py_ARRAY_LENGTH(new_path)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001447 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001448 if (!new_path) {
1449 SetLastError(ERROR_OUTOFMEMORY);
1450 return FALSE;
1451 }
1452 result = GetCurrentDirectoryW(result, new_path);
1453 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001454 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001455 return FALSE;
1456 }
1457 }
1458 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1459 wcsncmp(new_path, L"//", 2) == 0)
1460 /* UNC path, nothing to do. */
1461 return TRUE;
1462 env[1] = new_path[0];
1463 result = SetEnvironmentVariableW(env, new_path);
1464 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001465 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001466 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001467}
1468#endif
1469
Martin v. Löwis14694662006-02-03 12:54:16 +00001470#ifdef MS_WINDOWS
1471/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1472 - time stamps are restricted to second resolution
1473 - file modification times suffer from forth-and-back conversions between
1474 UTC and local time
1475 Therefore, we implement our own stat, based on the Win32 API directly.
1476*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001477#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001478
1479struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001480 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001481 __int64 st_ino;
1482 unsigned short st_mode;
1483 int st_nlink;
1484 int st_uid;
1485 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001486 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001487 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001488 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001489 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001490 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001491 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001492 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001493 int st_ctime_nsec;
1494};
1495
1496static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1497
1498static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001499FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001500{
Victor Stinner8c62be82010-05-06 00:08:46 +00001501 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1502 /* Cannot simply cast and dereference in_ptr,
1503 since it might not be aligned properly */
1504 __int64 in;
1505 memcpy(&in, in_ptr, sizeof(in));
1506 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001507 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001508}
1509
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001511time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001512{
Victor Stinner8c62be82010-05-06 00:08:46 +00001513 /* XXX endianness */
1514 __int64 out;
1515 out = time_in + secs_between_epochs;
1516 out = out * 10000000 + nsec_in / 100;
1517 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001518}
1519
Martin v. Löwis14694662006-02-03 12:54:16 +00001520/* Below, we *know* that ugo+r is 0444 */
1521#if _S_IREAD != 0400
1522#error Unsupported C library
1523#endif
1524static int
1525attributes_to_mode(DWORD attr)
1526{
Victor Stinner8c62be82010-05-06 00:08:46 +00001527 int m = 0;
1528 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1529 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1530 else
1531 m |= _S_IFREG;
1532 if (attr & FILE_ATTRIBUTE_READONLY)
1533 m |= 0444;
1534 else
1535 m |= 0666;
1536 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001537}
1538
1539static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001540attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001541{
Victor Stinner8c62be82010-05-06 00:08:46 +00001542 memset(result, 0, sizeof(*result));
1543 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1544 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001545 result->st_dev = info->dwVolumeSerialNumber;
1546 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1548 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1549 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001550 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001551 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001552 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1553 /* first clear the S_IFMT bits */
Christian Heimes99d61352013-06-23 23:56:05 +02001554 result->st_mode ^= (result->st_mode & S_IFMT);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001555 /* now set the bits that make this a symlink */
Christian Heimes99d61352013-06-23 23:56:05 +02001556 result->st_mode |= S_IFLNK;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001557 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001558
Victor Stinner8c62be82010-05-06 00:08:46 +00001559 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001560}
1561
Guido van Rossumd8faa362007-04-27 19:54:29 +00001562static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001563attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001564{
Victor Stinner8c62be82010-05-06 00:08:46 +00001565 HANDLE hFindFile;
1566 WIN32_FIND_DATAA FileData;
1567 hFindFile = FindFirstFileA(pszFile, &FileData);
1568 if (hFindFile == INVALID_HANDLE_VALUE)
1569 return FALSE;
1570 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001571 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001572 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001573 info->dwFileAttributes = FileData.dwFileAttributes;
1574 info->ftCreationTime = FileData.ftCreationTime;
1575 info->ftLastAccessTime = FileData.ftLastAccessTime;
1576 info->ftLastWriteTime = FileData.ftLastWriteTime;
1577 info->nFileSizeHigh = FileData.nFileSizeHigh;
1578 info->nFileSizeLow = FileData.nFileSizeLow;
1579/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001580 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1581 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001582 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001583}
1584
1585static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001586attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001587{
Victor Stinner8c62be82010-05-06 00:08:46 +00001588 HANDLE hFindFile;
1589 WIN32_FIND_DATAW FileData;
1590 hFindFile = FindFirstFileW(pszFile, &FileData);
1591 if (hFindFile == INVALID_HANDLE_VALUE)
1592 return FALSE;
1593 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001594 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001595 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001596 info->dwFileAttributes = FileData.dwFileAttributes;
1597 info->ftCreationTime = FileData.ftCreationTime;
1598 info->ftLastAccessTime = FileData.ftLastAccessTime;
1599 info->ftLastWriteTime = FileData.ftLastWriteTime;
1600 info->nFileSizeHigh = FileData.nFileSizeHigh;
1601 info->nFileSizeLow = FileData.nFileSizeLow;
1602/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001603 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1604 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001605 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001606}
1607
Brian Curtind25aef52011-06-13 15:16:04 -05001608/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001609static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001610static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1611 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001612static int
Brian Curtind25aef52011-06-13 15:16:04 -05001613check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001614{
Brian Curtind25aef52011-06-13 15:16:04 -05001615 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001616 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1617 DWORD);
1618
Brian Curtind25aef52011-06-13 15:16:04 -05001619 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001620 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001621 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001622 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001623 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1624 "GetFinalPathNameByHandleA");
1625 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1626 "GetFinalPathNameByHandleW");
1627 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1628 Py_GetFinalPathNameByHandleW;
1629 }
1630 return has_GetFinalPathNameByHandle;
1631}
1632
1633static BOOL
1634get_target_path(HANDLE hdl, wchar_t **target_path)
1635{
1636 int buf_size, result_length;
1637 wchar_t *buf;
1638
1639 /* We have a good handle to the target, use it to determine
1640 the target path name (then we'll call lstat on it). */
1641 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1642 VOLUME_NAME_DOS);
1643 if(!buf_size)
1644 return FALSE;
1645
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02001646 buf = PyMem_New(wchar_t, buf_size+1);
Brian Curtinc8be8402011-06-14 09:52:50 -05001647 if (!buf) {
1648 SetLastError(ERROR_OUTOFMEMORY);
1649 return FALSE;
1650 }
1651
Brian Curtind25aef52011-06-13 15:16:04 -05001652 result_length = Py_GetFinalPathNameByHandleW(hdl,
1653 buf, buf_size, VOLUME_NAME_DOS);
1654
1655 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001656 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001657 return FALSE;
1658 }
1659
1660 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001661 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001662 return FALSE;
1663 }
1664
1665 buf[result_length] = 0;
1666
1667 *target_path = buf;
1668 return TRUE;
1669}
1670
1671static int
1672win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1673 BOOL traverse);
1674static int
1675win32_xstat_impl(const char *path, struct win32_stat *result,
1676 BOOL traverse)
1677{
Victor Stinner26de69d2011-06-17 15:15:38 +02001678 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001679 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001680 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001681 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001682 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001683 const char *dot;
1684
Brian Curtind25aef52011-06-13 15:16:04 -05001685 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001686 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1687 traverse reparse point. */
1688 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001689 }
1690
Brian Curtinf5e76d02010-11-24 13:14:05 +00001691 hFile = CreateFileA(
1692 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001693 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001694 0, /* share mode */
1695 NULL, /* security attributes */
1696 OPEN_EXISTING,
1697 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001698 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1699 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001700 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001701 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1702 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001703 NULL);
1704
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001705 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001706 /* Either the target doesn't exist, or we don't have access to
1707 get a handle to it. If the former, we need to return an error.
1708 If the latter, we can use attributes_from_dir. */
1709 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001710 return -1;
1711 /* Could not get attributes on open file. Fall back to
1712 reading the directory. */
1713 if (!attributes_from_dir(path, &info, &reparse_tag))
1714 /* Very strange. This should not fail now */
1715 return -1;
1716 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1717 if (traverse) {
1718 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001719 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001720 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001721 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001722 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001723 } else {
1724 if (!GetFileInformationByHandle(hFile, &info)) {
1725 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001726 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001727 }
1728 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001729 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1730 return -1;
1731
1732 /* Close the outer open file handle now that we're about to
1733 reopen it with different flags. */
1734 if (!CloseHandle(hFile))
1735 return -1;
1736
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001737 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001738 /* In order to call GetFinalPathNameByHandle we need to open
1739 the file without the reparse handling flag set. */
1740 hFile2 = CreateFileA(
1741 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1742 NULL, OPEN_EXISTING,
1743 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1744 NULL);
1745 if (hFile2 == INVALID_HANDLE_VALUE)
1746 return -1;
1747
1748 if (!get_target_path(hFile2, &target_path))
1749 return -1;
1750
1751 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001752 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001753 return code;
1754 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001755 } else
1756 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001757 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001758 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001759
1760 /* Set S_IEXEC if it is an .exe, .bat, ... */
1761 dot = strrchr(path, '.');
1762 if (dot) {
1763 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1764 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1765 result->st_mode |= 0111;
1766 }
1767 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001768}
1769
1770static int
Brian Curtind25aef52011-06-13 15:16:04 -05001771win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1772 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001773{
1774 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001775 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001776 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001777 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001778 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001779 const wchar_t *dot;
1780
Brian Curtind25aef52011-06-13 15:16:04 -05001781 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001782 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1783 traverse reparse point. */
1784 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001785 }
1786
Brian Curtinf5e76d02010-11-24 13:14:05 +00001787 hFile = CreateFileW(
1788 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001789 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001790 0, /* share mode */
1791 NULL, /* security attributes */
1792 OPEN_EXISTING,
1793 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001794 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1795 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001796 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001797 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001798 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001799 NULL);
1800
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001801 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001802 /* Either the target doesn't exist, or we don't have access to
1803 get a handle to it. If the former, we need to return an error.
1804 If the latter, we can use attributes_from_dir. */
1805 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001806 return -1;
1807 /* Could not get attributes on open file. Fall back to
1808 reading the directory. */
1809 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1810 /* Very strange. This should not fail now */
1811 return -1;
1812 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1813 if (traverse) {
1814 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001815 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001816 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001817 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001818 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001819 } else {
1820 if (!GetFileInformationByHandle(hFile, &info)) {
1821 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001822 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001823 }
1824 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001825 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1826 return -1;
1827
1828 /* Close the outer open file handle now that we're about to
1829 reopen it with different flags. */
1830 if (!CloseHandle(hFile))
1831 return -1;
1832
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001833 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001834 /* In order to call GetFinalPathNameByHandle we need to open
1835 the file without the reparse handling flag set. */
1836 hFile2 = CreateFileW(
1837 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1838 NULL, OPEN_EXISTING,
1839 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1840 NULL);
1841 if (hFile2 == INVALID_HANDLE_VALUE)
1842 return -1;
1843
1844 if (!get_target_path(hFile2, &target_path))
1845 return -1;
1846
1847 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001848 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001849 return code;
1850 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001851 } else
1852 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001853 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001854 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001855
1856 /* Set S_IEXEC if it is an .exe, .bat, ... */
1857 dot = wcsrchr(path, '.');
1858 if (dot) {
1859 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1860 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1861 result->st_mode |= 0111;
1862 }
1863 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001864}
1865
1866static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001867win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001868{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001869 /* Protocol violation: we explicitly clear errno, instead of
1870 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001871 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001872 errno = 0;
1873 return code;
1874}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001875
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001876static int
1877win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1878{
1879 /* Protocol violation: we explicitly clear errno, instead of
1880 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001881 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001882 errno = 0;
1883 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001884}
Brian Curtind25aef52011-06-13 15:16:04 -05001885/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001886
1887 In Posix, stat automatically traverses symlinks and returns the stat
1888 structure for the target. In Windows, the equivalent GetFileAttributes by
1889 default does not traverse symlinks and instead returns attributes for
1890 the symlink.
1891
1892 Therefore, win32_lstat will get the attributes traditionally, and
1893 win32_stat will first explicitly resolve the symlink target and then will
1894 call win32_lstat on that result.
1895
Ezio Melotti4969f702011-03-15 05:59:46 +02001896 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001897
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001898static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001899win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001900{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001901 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001902}
1903
Victor Stinner8c62be82010-05-06 00:08:46 +00001904static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001905win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001906{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001907 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001908}
1909
1910static int
1911win32_stat(const char* path, struct win32_stat *result)
1912{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001913 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001914}
1915
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001916static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001917win32_stat_w(const wchar_t* path, struct win32_stat *result)
1918{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001919 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001920}
1921
1922static int
1923win32_fstat(int file_number, struct win32_stat *result)
1924{
Victor Stinner8c62be82010-05-06 00:08:46 +00001925 BY_HANDLE_FILE_INFORMATION info;
1926 HANDLE h;
1927 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001928
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001929 if (!_PyVerify_fd(file_number))
1930 h = INVALID_HANDLE_VALUE;
1931 else
1932 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001933
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 /* Protocol violation: we explicitly clear errno, instead of
1935 setting it to a POSIX error. Callers should use GetLastError. */
1936 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001937
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 if (h == INVALID_HANDLE_VALUE) {
1939 /* This is really a C library error (invalid file handle).
1940 We set the Win32 error to the closes one matching. */
1941 SetLastError(ERROR_INVALID_HANDLE);
1942 return -1;
1943 }
1944 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001945
Victor Stinner8c62be82010-05-06 00:08:46 +00001946 type = GetFileType(h);
1947 if (type == FILE_TYPE_UNKNOWN) {
1948 DWORD error = GetLastError();
1949 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001950 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001951 }
1952 /* else: valid but unknown file */
1953 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001954
Victor Stinner8c62be82010-05-06 00:08:46 +00001955 if (type != FILE_TYPE_DISK) {
1956 if (type == FILE_TYPE_CHAR)
1957 result->st_mode = _S_IFCHR;
1958 else if (type == FILE_TYPE_PIPE)
1959 result->st_mode = _S_IFIFO;
1960 return 0;
1961 }
1962
1963 if (!GetFileInformationByHandle(h, &info)) {
1964 return -1;
1965 }
1966
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001967 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001968 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001969 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1970 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001971}
1972
1973#endif /* MS_WINDOWS */
1974
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001975PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001976"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001977This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001978 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001979or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1980\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001981Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1982or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001983\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001984See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001985
1986static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001987 {"st_mode", "protection bits"},
1988 {"st_ino", "inode"},
1989 {"st_dev", "device"},
1990 {"st_nlink", "number of hard links"},
1991 {"st_uid", "user ID of owner"},
1992 {"st_gid", "group ID of owner"},
1993 {"st_size", "total size, in bytes"},
1994 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1995 {NULL, "integer time of last access"},
1996 {NULL, "integer time of last modification"},
1997 {NULL, "integer time of last change"},
1998 {"st_atime", "time of last access"},
1999 {"st_mtime", "time of last modification"},
2000 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07002001 {"st_atime_ns", "time of last access in nanoseconds"},
2002 {"st_mtime_ns", "time of last modification in nanoseconds"},
2003 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002004#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002005 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002006#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002007#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002008 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002009#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002010#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002011 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002012#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002013#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002015#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002016#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002017 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002018#endif
2019#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002020 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002021#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002023};
2024
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002025#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002026#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002027#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002028#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002029#endif
2030
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002031#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002032#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2033#else
2034#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2035#endif
2036
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002037#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002038#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2039#else
2040#define ST_RDEV_IDX ST_BLOCKS_IDX
2041#endif
2042
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002043#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2044#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2045#else
2046#define ST_FLAGS_IDX ST_RDEV_IDX
2047#endif
2048
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002049#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002050#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002051#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002052#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002053#endif
2054
2055#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2056#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2057#else
2058#define ST_BIRTHTIME_IDX ST_GEN_IDX
2059#endif
2060
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002061static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002062 "stat_result", /* name */
2063 stat_result__doc__, /* doc */
2064 stat_result_fields,
2065 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002066};
2067
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002068PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002069"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2070This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002071 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002072or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002073\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002074See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002075
2076static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 {"f_bsize", },
2078 {"f_frsize", },
2079 {"f_blocks", },
2080 {"f_bfree", },
2081 {"f_bavail", },
2082 {"f_files", },
2083 {"f_ffree", },
2084 {"f_favail", },
2085 {"f_flag", },
2086 {"f_namemax",},
2087 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002088};
2089
2090static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002091 "statvfs_result", /* name */
2092 statvfs_result__doc__, /* doc */
2093 statvfs_result_fields,
2094 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002095};
2096
Ross Lagerwall7807c352011-03-17 20:20:30 +02002097#if defined(HAVE_WAITID) && !defined(__APPLE__)
2098PyDoc_STRVAR(waitid_result__doc__,
2099"waitid_result: Result from waitid.\n\n\
2100This object may be accessed either as a tuple of\n\
2101 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2102or via the attributes si_pid, si_uid, and so on.\n\
2103\n\
2104See os.waitid for more information.");
2105
2106static PyStructSequence_Field waitid_result_fields[] = {
2107 {"si_pid", },
2108 {"si_uid", },
2109 {"si_signo", },
2110 {"si_status", },
2111 {"si_code", },
2112 {0}
2113};
2114
2115static PyStructSequence_Desc waitid_result_desc = {
2116 "waitid_result", /* name */
2117 waitid_result__doc__, /* doc */
2118 waitid_result_fields,
2119 5
2120};
2121static PyTypeObject WaitidResultType;
2122#endif
2123
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002124static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002125static PyTypeObject StatResultType;
2126static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002127#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002128static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002129#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002130static newfunc structseq_new;
2131
2132static PyObject *
2133statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2134{
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 PyStructSequence *result;
2136 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002137
Victor Stinner8c62be82010-05-06 00:08:46 +00002138 result = (PyStructSequence*)structseq_new(type, args, kwds);
2139 if (!result)
2140 return NULL;
2141 /* If we have been initialized from a tuple,
2142 st_?time might be set to None. Initialize it
2143 from the int slots. */
2144 for (i = 7; i <= 9; i++) {
2145 if (result->ob_item[i+3] == Py_None) {
2146 Py_DECREF(Py_None);
2147 Py_INCREF(result->ob_item[i]);
2148 result->ob_item[i+3] = result->ob_item[i];
2149 }
2150 }
2151 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002152}
2153
2154
2155
2156/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002157static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002158
2159PyDoc_STRVAR(stat_float_times__doc__,
2160"stat_float_times([newval]) -> oldval\n\n\
2161Determine whether os.[lf]stat represents time stamps as float objects.\n\
2162If newval is True, future calls to stat() return floats, if it is False,\n\
2163future calls return ints. \n\
2164If newval is omitted, return the current setting.\n");
2165
2166static PyObject*
2167stat_float_times(PyObject* self, PyObject *args)
2168{
Victor Stinner8c62be82010-05-06 00:08:46 +00002169 int newval = -1;
2170 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2171 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002172 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2173 "stat_float_times() is deprecated",
2174 1))
2175 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002176 if (newval == -1)
2177 /* Return old value */
2178 return PyBool_FromLong(_stat_float_times);
2179 _stat_float_times = newval;
2180 Py_INCREF(Py_None);
2181 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002182}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002183
Larry Hastings6fe20b32012-04-19 15:07:49 -07002184static PyObject *billion = NULL;
2185
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002186static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002187fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002188{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002189 PyObject *s = _PyLong_FromTime_t(sec);
2190 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2191 PyObject *s_in_ns = NULL;
2192 PyObject *ns_total = NULL;
2193 PyObject *float_s = NULL;
2194
2195 if (!(s && ns_fractional))
2196 goto exit;
2197
2198 s_in_ns = PyNumber_Multiply(s, billion);
2199 if (!s_in_ns)
2200 goto exit;
2201
2202 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2203 if (!ns_total)
2204 goto exit;
2205
Victor Stinner4195b5c2012-02-08 23:03:19 +01002206 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002207 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2208 if (!float_s)
2209 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002210 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002211 else {
2212 float_s = s;
2213 Py_INCREF(float_s);
2214 }
2215
2216 PyStructSequence_SET_ITEM(v, index, s);
2217 PyStructSequence_SET_ITEM(v, index+3, float_s);
2218 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2219 s = NULL;
2220 float_s = NULL;
2221 ns_total = NULL;
2222exit:
2223 Py_XDECREF(s);
2224 Py_XDECREF(ns_fractional);
2225 Py_XDECREF(s_in_ns);
2226 Py_XDECREF(ns_total);
2227 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002228}
2229
Tim Peters5aa91602002-01-30 05:46:57 +00002230/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002231 (used by posix_stat() and posix_fstat()) */
2232static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002233_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002234{
Victor Stinner8c62be82010-05-06 00:08:46 +00002235 unsigned long ansec, mnsec, cnsec;
2236 PyObject *v = PyStructSequence_New(&StatResultType);
2237 if (v == NULL)
2238 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002239
Victor Stinner8c62be82010-05-06 00:08:46 +00002240 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002241#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002242 PyStructSequence_SET_ITEM(v, 1,
2243 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002244#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002245 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002246#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002247#ifdef MS_WINDOWS
2248 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002249#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002250 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002251#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002252 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002253#if defined(MS_WINDOWS)
2254 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2255 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2256#else
2257 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2258 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2259#endif
Fred Drake699f3522000-06-29 21:12:41 +00002260#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002261 PyStructSequence_SET_ITEM(v, 6,
2262 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002263#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002264 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002265#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002266
Martin v. Löwis14694662006-02-03 12:54:16 +00002267#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002268 ansec = st->st_atim.tv_nsec;
2269 mnsec = st->st_mtim.tv_nsec;
2270 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002271#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002272 ansec = st->st_atimespec.tv_nsec;
2273 mnsec = st->st_mtimespec.tv_nsec;
2274 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002275#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002276 ansec = st->st_atime_nsec;
2277 mnsec = st->st_mtime_nsec;
2278 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002279#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002280 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002281#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002282 fill_time(v, 7, st->st_atime, ansec);
2283 fill_time(v, 8, st->st_mtime, mnsec);
2284 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002285
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002286#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002287 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2288 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002289#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002290#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002291 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2292 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002293#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002294#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002295 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2296 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002297#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002298#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002299 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2300 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002301#endif
2302#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002303 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002304 PyObject *val;
2305 unsigned long bsec,bnsec;
2306 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002307#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002308 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002309#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002310 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002311#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002312 if (_stat_float_times) {
2313 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2314 } else {
2315 val = PyLong_FromLong((long)bsec);
2316 }
2317 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2318 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002319 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002320#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002321#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002322 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2323 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002324#endif
Fred Drake699f3522000-06-29 21:12:41 +00002325
Victor Stinner8c62be82010-05-06 00:08:46 +00002326 if (PyErr_Occurred()) {
2327 Py_DECREF(v);
2328 return NULL;
2329 }
Fred Drake699f3522000-06-29 21:12:41 +00002330
Victor Stinner8c62be82010-05-06 00:08:46 +00002331 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002332}
2333
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002334/* POSIX methods */
2335
Guido van Rossum94f6f721999-01-06 18:42:14 +00002336
2337static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002338posix_do_stat(char *function_name, path_t *path,
2339 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002340{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002341 STRUCT_STAT st;
2342 int result;
2343
2344#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2345 if (follow_symlinks_specified(function_name, follow_symlinks))
2346 return NULL;
2347#endif
2348
2349 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2350 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2351 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2352 return NULL;
2353
2354 Py_BEGIN_ALLOW_THREADS
2355 if (path->fd != -1)
2356 result = FSTAT(path->fd, &st);
2357 else
2358#ifdef MS_WINDOWS
2359 if (path->wide) {
2360 if (follow_symlinks)
2361 result = win32_stat_w(path->wide, &st);
2362 else
2363 result = win32_lstat_w(path->wide, &st);
2364 }
2365 else
2366#endif
2367#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2368 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2369 result = LSTAT(path->narrow, &st);
2370 else
2371#endif
2372#ifdef HAVE_FSTATAT
2373 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2374 result = fstatat(dir_fd, path->narrow, &st,
2375 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2376 else
2377#endif
2378 result = STAT(path->narrow, &st);
2379 Py_END_ALLOW_THREADS
2380
Victor Stinner292c8352012-10-30 02:17:38 +01002381 if (result != 0) {
2382 return path_error(path);
2383 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002384
2385 return _pystat_fromstructstat(&st);
2386}
2387
Larry Hastings31826802013-10-19 00:09:25 -07002388#ifdef HAVE_FSTATAT
2389 #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter
2390#else
2391 #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable
2392#endif
2393
2394
Larry Hastings61272b72014-01-07 12:41:53 -08002395/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002396
2397class path_t_converter(CConverter):
2398
2399 type = "path_t"
2400 impl_by_reference = True
2401 parse_by_reference = True
2402
2403 converter = 'path_converter'
2404
2405 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002406 # right now path_t doesn't support default values.
2407 # to support a default value, you'll need to override initialize().
Larry Hastings7726ac92014-01-31 22:03:12 -08002408 if self.default is not unspecified:
2409 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002410
Larry Hastings7726ac92014-01-31 22:03:12 -08002411 if self.c_default is not None:
2412 fail("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002413
2414 self.nullable = nullable
2415 self.allow_fd = allow_fd
2416
Larry Hastings7726ac92014-01-31 22:03:12 -08002417 def pre_render(self):
2418 def strify(value):
2419 return str(int(bool(value)))
2420
2421 # add self.py_name here when merging with posixmodule conversion
Larry Hastings31826802013-10-19 00:09:25 -07002422 self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format(
2423 self.function.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002424 strify(self.nullable),
2425 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002426 )
2427
2428 def cleanup(self):
2429 return "path_cleanup(&" + self.name + ");\n"
2430
2431
2432class dir_fd_converter(CConverter):
2433 type = 'int'
2434 converter = 'OS_STAT_DIR_FD_CONVERTER'
2435
2436 def converter_init(self):
2437 if self.default in (unspecified, None):
2438 self.c_default = 'DEFAULT_DIR_FD'
2439
2440
Larry Hastings61272b72014-01-07 12:41:53 -08002441[python start generated code]*/
Larry Hastings7726ac92014-01-31 22:03:12 -08002442/*[python end generated code: output=da39a3ee5e6b4b0d input=5c9f456f53244fc3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002443
Larry Hastings61272b72014-01-07 12:41:53 -08002444/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002445
Larry Hastings2a727912014-01-16 11:32:01 -08002446os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002447
2448 path : path_t(allow_fd=True)
2449 Path to be examined; can be string, bytes, or open-file-descriptor int.
2450
2451 *
2452
2453 dir_fd : dir_fd = None
2454 If not None, it should be a file descriptor open to a directory,
2455 and path should be a relative string; path will then be relative to
2456 that directory.
2457
2458 follow_symlinks: bool = True
2459 If False, and the last element of the path is a symbolic link,
2460 stat will examine the symbolic link itself instead of the file
2461 the link points to.
2462
2463Perform a stat system call on the given path.
2464
2465dir_fd and follow_symlinks may not be implemented
2466 on your platform. If they are unavailable, using them will raise a
2467 NotImplementedError.
2468
2469It's an error to use dir_fd or follow_symlinks when specifying path as
2470 an open file descriptor.
2471
Larry Hastings61272b72014-01-07 12:41:53 -08002472[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002473
2474PyDoc_STRVAR(os_stat__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002475"stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n"
2476"--\n"
2477"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002478"Perform a stat system call on the given path.\n"
2479"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002480" path\n"
2481" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
2482" dir_fd\n"
2483" If not None, it should be a file descriptor open to a directory,\n"
2484" and path should be a relative string; path will then be relative to\n"
2485" that directory.\n"
2486" follow_symlinks\n"
2487" If False, and the last element of the path is a symbolic link,\n"
2488" stat will examine the symbolic link itself instead of the file\n"
2489" the link points to.\n"
2490"\n"
2491"dir_fd and follow_symlinks may not be implemented\n"
2492" on your platform. If they are unavailable, using them will raise a\n"
2493" NotImplementedError.\n"
2494"\n"
2495"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n"
2496" an open file descriptor.");
2497
2498#define OS_STAT_METHODDEF \
2499 {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002500
2501static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002502os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002503
2504static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002505os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002506{
Larry Hastings31826802013-10-19 00:09:25 -07002507 PyObject *return_value = NULL;
2508 static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2509 path_t path = PATH_T_INITIALIZE("stat", 0, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002510 int dir_fd = DEFAULT_DIR_FD;
2511 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002512
Larry Hastings31826802013-10-19 00:09:25 -07002513 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2514 "O&|$O&p:stat", _keywords,
2515 path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
2516 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002517 return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002518
2519exit:
2520 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002521 path_cleanup(&path);
Larry Hastings31826802013-10-19 00:09:25 -07002522
Larry Hastings9cf065c2012-06-22 16:30:09 -07002523 return return_value;
2524}
2525
Larry Hastings31826802013-10-19 00:09:25 -07002526static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002527os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002528/*[clinic end generated code: output=f1dcaa5e24db9882 input=5ae155bd475fd20a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002529{
2530 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2531}
2532
Larry Hastings9cf065c2012-06-22 16:30:09 -07002533PyDoc_STRVAR(posix_lstat__doc__,
2534"lstat(path, *, dir_fd=None) -> stat result\n\n\
2535Like stat(), but do not follow symbolic links.\n\
2536Equivalent to stat(path, follow_symlinks=False).");
2537
2538static PyObject *
2539posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2540{
2541 static char *keywords[] = {"path", "dir_fd", NULL};
2542 path_t path;
2543 int dir_fd = DEFAULT_DIR_FD;
2544 int follow_symlinks = 0;
2545 PyObject *return_value;
2546
2547 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002548 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002549 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2550 path_converter, &path,
2551#ifdef HAVE_FSTATAT
2552 dir_fd_converter, &dir_fd
2553#else
2554 dir_fd_unavailable, &dir_fd
2555#endif
2556 ))
2557 return NULL;
Larry Hastings31826802013-10-19 00:09:25 -07002558 return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002559 path_cleanup(&path);
2560 return return_value;
2561}
2562
Larry Hastings31826802013-10-19 00:09:25 -07002563
2564#ifdef HAVE_FACCESSAT
2565 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter
2566#else
2567 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable
2568#endif
Larry Hastings61272b72014-01-07 12:41:53 -08002569/*[clinic input]
Larry Hastings2a727912014-01-16 11:32:01 -08002570os.access
Larry Hastings31826802013-10-19 00:09:25 -07002571
2572 path: path_t(allow_fd=True)
2573 Path to be tested; can be string, bytes, or open-file-descriptor int.
2574
2575 mode: int
2576 Operating-system mode bitfield. Can be F_OK to test existence,
2577 or the inclusive-OR of R_OK, W_OK, and X_OK.
2578
2579 *
2580
2581 dir_fd : dir_fd = None
2582 If not None, it should be a file descriptor open to a directory,
2583 and path should be relative; path will then be relative to that
2584 directory.
2585
2586 effective_ids: bool = False
2587 If True, access will use the effective uid/gid instead of
2588 the real uid/gid.
2589
2590 follow_symlinks: bool = True
2591 If False, and the last element of the path is a symbolic link,
2592 access will examine the symbolic link itself instead of the file
2593 the link points to.
2594
2595Use the real uid/gid to test for access to a path.
2596
2597{parameters}
2598dir_fd, effective_ids, and follow_symlinks may not be implemented
2599 on your platform. If they are unavailable, using them will raise a
2600 NotImplementedError.
2601
2602Note that most operations will use the effective uid/gid, therefore this
2603 routine can be used in a suid/sgid environment to test if the invoking user
2604 has the specified access to the path.
2605
Larry Hastings61272b72014-01-07 12:41:53 -08002606[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002607
2608PyDoc_STRVAR(os_access__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002609"access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n"
2610" follow_symlinks=True)\n"
2611"--\n"
2612"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002613"Use the real uid/gid to test for access to a path.\n"
2614"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002615" path\n"
2616" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
2617" mode\n"
2618" Operating-system mode bitfield. Can be F_OK to test existence,\n"
2619" or the inclusive-OR of R_OK, W_OK, and X_OK.\n"
2620" dir_fd\n"
2621" If not None, it should be a file descriptor open to a directory,\n"
2622" and path should be relative; path will then be relative to that\n"
2623" directory.\n"
2624" effective_ids\n"
2625" If True, access will use the effective uid/gid instead of\n"
2626" the real uid/gid.\n"
2627" follow_symlinks\n"
2628" If False, and the last element of the path is a symbolic link,\n"
2629" access will examine the symbolic link itself instead of the file\n"
2630" the link points to.\n"
2631"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002632"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
2633" on your platform. If they are unavailable, using them will raise a\n"
2634" NotImplementedError.\n"
2635"\n"
2636"Note that most operations will use the effective uid/gid, therefore this\n"
2637" routine can be used in a suid/sgid environment to test if the invoking user\n"
2638" has the specified access to the path.");
2639
2640#define OS_ACCESS_METHODDEF \
2641 {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002642
2643static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002644os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002645
2646static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002647os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002648{
Larry Hastings31826802013-10-19 00:09:25 -07002649 PyObject *return_value = NULL;
2650 static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL};
2651 path_t path = PATH_T_INITIALIZE("access", 0, 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00002652 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002653 int dir_fd = DEFAULT_DIR_FD;
2654 int effective_ids = 0;
2655 int follow_symlinks = 1;
Larry Hastings31826802013-10-19 00:09:25 -07002656
2657 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2658 "O&i|$O&pp:access", _keywords,
2659 path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks))
2660 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002661 return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002662
2663exit:
2664 /* Cleanup for path */
2665 path_cleanup(&path);
2666
2667 return return_value;
2668}
2669
2670static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002671os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002672/*[clinic end generated code: output=a6ed4f151be9df0f input=2e2e7594371f5b7e]*/
Larry Hastings31826802013-10-19 00:09:25 -07002673{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002674 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002675
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002676#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002677 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002678#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002679 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002680#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002681
Larry Hastings9cf065c2012-06-22 16:30:09 -07002682#ifndef HAVE_FACCESSAT
2683 if (follow_symlinks_specified("access", follow_symlinks))
2684 goto exit;
2685
2686 if (effective_ids) {
2687 argument_unavailable_error("access", "effective_ids");
2688 goto exit;
2689 }
2690#endif
2691
2692#ifdef MS_WINDOWS
2693 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002694 if (path->wide != NULL)
2695 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002696 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002697 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002698 Py_END_ALLOW_THREADS
2699
2700 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002701 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002702 * * we didn't get a -1, and
2703 * * write access wasn't requested,
2704 * * or the file isn't read-only,
2705 * * or it's a directory.
2706 * (Directories cannot be read-only on Windows.)
2707 */
2708 return_value = PyBool_FromLong(
Tim Golden23005082013-10-25 11:22:37 +01002709 (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002710 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002711 !(attr & FILE_ATTRIBUTE_READONLY) ||
2712 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2713#else
2714
2715 Py_BEGIN_ALLOW_THREADS
2716#ifdef HAVE_FACCESSAT
2717 if ((dir_fd != DEFAULT_DIR_FD) ||
2718 effective_ids ||
2719 !follow_symlinks) {
2720 int flags = 0;
2721 if (!follow_symlinks)
2722 flags |= AT_SYMLINK_NOFOLLOW;
2723 if (effective_ids)
2724 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002725 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002726 }
2727 else
2728#endif
Larry Hastings31826802013-10-19 00:09:25 -07002729 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002730 Py_END_ALLOW_THREADS
2731 return_value = PyBool_FromLong(!result);
2732#endif
2733
2734#ifndef HAVE_FACCESSAT
2735exit:
2736#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002737 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002738}
2739
Guido van Rossumd371ff11999-01-25 16:12:23 +00002740#ifndef F_OK
2741#define F_OK 0
2742#endif
2743#ifndef R_OK
2744#define R_OK 4
2745#endif
2746#ifndef W_OK
2747#define W_OK 2
2748#endif
2749#ifndef X_OK
2750#define X_OK 1
2751#endif
2752
Larry Hastings31826802013-10-19 00:09:25 -07002753
Guido van Rossumd371ff11999-01-25 16:12:23 +00002754#ifdef HAVE_TTYNAME
Larry Hastings31826802013-10-19 00:09:25 -07002755
Larry Hastings61272b72014-01-07 12:41:53 -08002756/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002757os.ttyname -> DecodeFSDefault
2758
2759 fd: int
2760 Integer file descriptor handle.
2761
2762 /
2763
2764Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002765[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002766
2767PyDoc_STRVAR(os_ttyname__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002768"ttyname($module, fd, /)\n"
2769"--\n"
2770"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002771"Return the name of the terminal device connected to \'fd\'.\n"
2772"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002773" fd\n"
2774" Integer file descriptor handle.");
2775
2776#define OS_TTYNAME_METHODDEF \
2777 {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__},
2778
2779static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002780os_ttyname_impl(PyModuleDef *module, int fd);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002781
2782static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002783os_ttyname(PyModuleDef *module, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002784{
Larry Hastings31826802013-10-19 00:09:25 -07002785 PyObject *return_value = NULL;
2786 int fd;
2787 char *_return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002788
Larry Hastings31826802013-10-19 00:09:25 -07002789 if (!PyArg_ParseTuple(args,
2790 "i:ttyname",
2791 &fd))
2792 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002793 _return_value = os_ttyname_impl(module, fd);
Larry Hastings31826802013-10-19 00:09:25 -07002794 if (_return_value == NULL)
2795 goto exit;
2796 return_value = PyUnicode_DecodeFSDefault(_return_value);
2797
2798exit:
2799 return return_value;
2800}
2801
2802static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002803os_ttyname_impl(PyModuleDef *module, int fd)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002804/*[clinic end generated code: output=cee7bc4cffec01a2 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002805{
2806 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002807
Larry Hastings31826802013-10-19 00:09:25 -07002808 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002809 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002810 posix_error();
2811 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002812}
Larry Hastings31826802013-10-19 00:09:25 -07002813#else
2814#define OS_TTYNAME_METHODDEF
Guido van Rossumd371ff11999-01-25 16:12:23 +00002815#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002816
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002817#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002818PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002819"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002820Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002821
2822static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002823posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002824{
Victor Stinner8c62be82010-05-06 00:08:46 +00002825 char *ret;
2826 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002827
Greg Wardb48bc172000-03-01 21:51:56 +00002828#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002829 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002830#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002831 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002832#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002833 if (ret == NULL)
2834 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002835 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002836}
2837#endif
2838
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002839PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002840"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002841Change the current working directory to the specified path.\n\
2842\n\
2843path may always be specified as a string.\n\
2844On some platforms, path may also be specified as an open file descriptor.\n\
2845 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002846
Barry Warsaw53699e91996-12-10 23:23:01 +00002847static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002848posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002849{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002850 path_t path;
2851 int result;
2852 PyObject *return_value = NULL;
2853 static char *keywords[] = {"path", NULL};
2854
2855 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002856 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002857#ifdef HAVE_FCHDIR
2858 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002859#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002860 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2861 path_converter, &path
2862 ))
2863 return NULL;
2864
2865 Py_BEGIN_ALLOW_THREADS
2866#ifdef MS_WINDOWS
2867 if (path.wide)
2868 result = win32_wchdir(path.wide);
2869 else
2870 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002871 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002872#else
2873#ifdef HAVE_FCHDIR
2874 if (path.fd != -1)
2875 result = fchdir(path.fd);
2876 else
2877#endif
2878 result = chdir(path.narrow);
2879#endif
2880 Py_END_ALLOW_THREADS
2881
2882 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002883 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002884 goto exit;
2885 }
2886
2887 return_value = Py_None;
2888 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002889
Larry Hastings9cf065c2012-06-22 16:30:09 -07002890exit:
2891 path_cleanup(&path);
2892 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002893}
2894
Fred Drake4d1e64b2002-04-15 19:40:07 +00002895#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002896PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002897"fchdir(fd)\n\n\
2898Change to the directory of the given file descriptor. fd must be\n\
2899opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002900
2901static PyObject *
2902posix_fchdir(PyObject *self, PyObject *fdobj)
2903{
Victor Stinner8c62be82010-05-06 00:08:46 +00002904 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002905}
2906#endif /* HAVE_FCHDIR */
2907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002908
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002909PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002910"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2911Change the access permissions of a file.\n\
2912\n\
2913path may always be specified as a string.\n\
2914On some platforms, path may also be specified as an open file descriptor.\n\
2915 If this functionality is unavailable, using it raises an exception.\n\
2916If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2917 and path should be relative; path will then be relative to that directory.\n\
2918If follow_symlinks is False, and the last element of the path is a symbolic\n\
2919 link, chmod will modify the symbolic link itself instead of the file the\n\
2920 link points to.\n\
2921It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2922 an open file descriptor.\n\
2923dir_fd and follow_symlinks may not be implemented on your platform.\n\
2924 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002925
Barry Warsaw53699e91996-12-10 23:23:01 +00002926static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002927posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002928{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002929 path_t path;
2930 int mode;
2931 int dir_fd = DEFAULT_DIR_FD;
2932 int follow_symlinks = 1;
2933 int result;
2934 PyObject *return_value = NULL;
2935 static char *keywords[] = {"path", "mode", "dir_fd",
2936 "follow_symlinks", NULL};
2937
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002938#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002939 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002940#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002941
Larry Hastings9cf065c2012-06-22 16:30:09 -07002942#ifdef HAVE_FCHMODAT
2943 int fchmodat_nofollow_unsupported = 0;
2944#endif
2945
2946 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002947 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002948#ifdef HAVE_FCHMOD
2949 path.allow_fd = 1;
2950#endif
2951 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2952 path_converter, &path,
2953 &mode,
2954#ifdef HAVE_FCHMODAT
2955 dir_fd_converter, &dir_fd,
2956#else
2957 dir_fd_unavailable, &dir_fd,
2958#endif
2959 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002960 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002961
2962#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2963 if (follow_symlinks_specified("chmod", follow_symlinks))
2964 goto exit;
2965#endif
2966
2967#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002968 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002969 if (path.wide)
2970 attr = GetFileAttributesW(path.wide);
2971 else
2972 attr = GetFileAttributesA(path.narrow);
Tim Golden23005082013-10-25 11:22:37 +01002973 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002974 result = 0;
2975 else {
2976 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002977 attr &= ~FILE_ATTRIBUTE_READONLY;
2978 else
2979 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002980 if (path.wide)
2981 result = SetFileAttributesW(path.wide, attr);
2982 else
2983 result = SetFileAttributesA(path.narrow, attr);
2984 }
2985 Py_END_ALLOW_THREADS
2986
2987 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002988 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002989 goto exit;
2990 }
2991#else /* MS_WINDOWS */
2992 Py_BEGIN_ALLOW_THREADS
2993#ifdef HAVE_FCHMOD
2994 if (path.fd != -1)
2995 result = fchmod(path.fd, mode);
2996 else
2997#endif
2998#ifdef HAVE_LCHMOD
2999 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3000 result = lchmod(path.narrow, mode);
3001 else
3002#endif
3003#ifdef HAVE_FCHMODAT
3004 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
3005 /*
3006 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3007 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003008 * and then says it isn't implemented yet.
3009 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003010 *
3011 * Once it is supported, os.chmod will automatically
3012 * support dir_fd and follow_symlinks=False. (Hopefully.)
3013 * Until then, we need to be careful what exception we raise.
3014 */
3015 result = fchmodat(dir_fd, path.narrow, mode,
3016 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3017 /*
3018 * But wait! We can't throw the exception without allowing threads,
3019 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3020 */
3021 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003022 result &&
3023 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3024 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00003025 }
3026 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00003027#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003028 result = chmod(path.narrow, mode);
3029 Py_END_ALLOW_THREADS
3030
3031 if (result) {
3032#ifdef HAVE_FCHMODAT
3033 if (fchmodat_nofollow_unsupported) {
3034 if (dir_fd != DEFAULT_DIR_FD)
3035 dir_fd_and_follow_symlinks_invalid("chmod",
3036 dir_fd, follow_symlinks);
3037 else
3038 follow_symlinks_specified("chmod", follow_symlinks);
3039 }
3040 else
3041#endif
Victor Stinner292c8352012-10-30 02:17:38 +01003042 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003043 goto exit;
3044 }
3045#endif
3046
3047 Py_INCREF(Py_None);
3048 return_value = Py_None;
3049exit:
3050 path_cleanup(&path);
3051 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003052}
3053
Larry Hastings9cf065c2012-06-22 16:30:09 -07003054
Christian Heimes4e30a842007-11-30 22:12:06 +00003055#ifdef HAVE_FCHMOD
3056PyDoc_STRVAR(posix_fchmod__doc__,
3057"fchmod(fd, mode)\n\n\
3058Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003059descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003060
3061static PyObject *
3062posix_fchmod(PyObject *self, PyObject *args)
3063{
Victor Stinner8c62be82010-05-06 00:08:46 +00003064 int fd, mode, res;
3065 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
3066 return NULL;
3067 Py_BEGIN_ALLOW_THREADS
3068 res = fchmod(fd, mode);
3069 Py_END_ALLOW_THREADS
3070 if (res < 0)
3071 return posix_error();
3072 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003073}
3074#endif /* HAVE_FCHMOD */
3075
3076#ifdef HAVE_LCHMOD
3077PyDoc_STRVAR(posix_lchmod__doc__,
3078"lchmod(path, mode)\n\n\
3079Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003080affects the link itself rather than the target.\n\
3081Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003082
3083static PyObject *
3084posix_lchmod(PyObject *self, PyObject *args)
3085{
Victor Stinner292c8352012-10-30 02:17:38 +01003086 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003087 int i;
3088 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003089 memset(&path, 0, sizeof(path));
3090 path.function_name = "lchmod";
3091 if (!PyArg_ParseTuple(args, "O&i:lchmod",
3092 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00003093 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003094 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003095 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00003096 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003097 if (res < 0) {
3098 path_error(&path);
3099 path_cleanup(&path);
3100 return NULL;
3101 }
3102 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003103 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003104}
3105#endif /* HAVE_LCHMOD */
3106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003107
Thomas Wouterscf297e42007-02-23 15:07:44 +00003108#ifdef HAVE_CHFLAGS
3109PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110"chflags(path, flags, *, follow_symlinks=True)\n\n\
3111Set file flags.\n\
3112\n\
3113If follow_symlinks is False, and the last element of the path is a symbolic\n\
3114 link, chflags will change flags on the symbolic link itself instead of the\n\
3115 file the link points to.\n\
3116follow_symlinks may not be implemented on your platform. If it is\n\
3117unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003118
3119static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003120posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003121{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003122 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003123 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003124 int follow_symlinks = 1;
3125 int result;
Victor Stinner45e90392013-07-18 23:57:35 +02003126 PyObject *return_value = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003127 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
3128
3129 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003130 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003131 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
3132 path_converter, &path,
3133 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003134 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003135
3136#ifndef HAVE_LCHFLAGS
3137 if (follow_symlinks_specified("chflags", follow_symlinks))
3138 goto exit;
3139#endif
3140
Victor Stinner8c62be82010-05-06 00:08:46 +00003141 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003142#ifdef HAVE_LCHFLAGS
3143 if (!follow_symlinks)
3144 result = lchflags(path.narrow, flags);
3145 else
3146#endif
3147 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003148 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003149
3150 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003151 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003152 goto exit;
3153 }
3154
3155 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003156 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157
3158exit:
3159 path_cleanup(&path);
3160 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003161}
3162#endif /* HAVE_CHFLAGS */
3163
3164#ifdef HAVE_LCHFLAGS
3165PyDoc_STRVAR(posix_lchflags__doc__,
3166"lchflags(path, flags)\n\n\
3167Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003168This function will not follow symbolic links.\n\
3169Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003170
3171static PyObject *
3172posix_lchflags(PyObject *self, PyObject *args)
3173{
Victor Stinner292c8352012-10-30 02:17:38 +01003174 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003175 unsigned long flags;
3176 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003177 memset(&path, 0, sizeof(path));
3178 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00003179 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01003180 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00003181 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003182 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003183 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003184 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003185 if (res < 0) {
3186 path_error(&path);
3187 path_cleanup(&path);
3188 return NULL;
3189 }
3190 path_cleanup(&path);
3191 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003192}
3193#endif /* HAVE_LCHFLAGS */
3194
Martin v. Löwis244edc82001-10-04 22:44:26 +00003195#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003196PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003197"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003198Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00003199
3200static PyObject *
3201posix_chroot(PyObject *self, PyObject *args)
3202{
Victor Stinner292c8352012-10-30 02:17:38 +01003203 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00003204}
3205#endif
3206
Guido van Rossum21142a01999-01-08 21:05:37 +00003207#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003208PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003209"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003210force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003211
3212static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003213posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003214{
Stefan Krah0e803b32010-11-26 16:16:47 +00003215 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003216}
3217#endif /* HAVE_FSYNC */
3218
Ross Lagerwall7807c352011-03-17 20:20:30 +02003219#ifdef HAVE_SYNC
3220PyDoc_STRVAR(posix_sync__doc__,
3221"sync()\n\n\
3222Force write of everything to disk.");
3223
3224static PyObject *
3225posix_sync(PyObject *self, PyObject *noargs)
3226{
3227 Py_BEGIN_ALLOW_THREADS
3228 sync();
3229 Py_END_ALLOW_THREADS
3230 Py_RETURN_NONE;
3231}
3232#endif
3233
Guido van Rossum21142a01999-01-08 21:05:37 +00003234#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00003235
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003236#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003237extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3238#endif
3239
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003240PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003241"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003242force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003243 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003244
3245static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003246posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003247{
Stefan Krah0e803b32010-11-26 16:16:47 +00003248 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003249}
3250#endif /* HAVE_FDATASYNC */
3251
3252
Fredrik Lundh10723342000-07-10 16:38:09 +00003253#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003254PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003255"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3256Change the owner and group id of path to the numeric uid and gid.\n\
3257\n\
3258path may always be specified as a string.\n\
3259On some platforms, path may also be specified as an open file descriptor.\n\
3260 If this functionality is unavailable, using it raises an exception.\n\
3261If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3262 and path should be relative; path will then be relative to that directory.\n\
3263If follow_symlinks is False, and the last element of the path is a symbolic\n\
3264 link, chown will modify the symbolic link itself instead of the file the\n\
3265 link points to.\n\
3266It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3267 an open file descriptor.\n\
3268dir_fd and follow_symlinks may not be implemented on your platform.\n\
3269 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003270
Barry Warsaw53699e91996-12-10 23:23:01 +00003271static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003272posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003273{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003274 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003275 uid_t uid;
3276 gid_t gid;
3277 int dir_fd = DEFAULT_DIR_FD;
3278 int follow_symlinks = 1;
3279 int result;
3280 PyObject *return_value = NULL;
3281 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3282 "follow_symlinks", NULL};
3283
3284 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003285 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003286#ifdef HAVE_FCHOWN
3287 path.allow_fd = 1;
3288#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003289 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003290 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003291 _Py_Uid_Converter, &uid,
3292 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003293#ifdef HAVE_FCHOWNAT
3294 dir_fd_converter, &dir_fd,
3295#else
3296 dir_fd_unavailable, &dir_fd,
3297#endif
3298 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003299 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003300
3301#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3302 if (follow_symlinks_specified("chown", follow_symlinks))
3303 goto exit;
3304#endif
3305 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3306 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3307 goto exit;
3308
3309#ifdef __APPLE__
3310 /*
3311 * This is for Mac OS X 10.3, which doesn't have lchown.
3312 * (But we still have an lchown symbol because of weak-linking.)
3313 * It doesn't have fchownat either. So there's no possibility
3314 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003315 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003316 if ((!follow_symlinks) && (lchown == NULL)) {
3317 follow_symlinks_specified("chown", follow_symlinks);
3318 goto exit;
3319 }
3320#endif
3321
Victor Stinner8c62be82010-05-06 00:08:46 +00003322 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003323#ifdef HAVE_FCHOWN
3324 if (path.fd != -1)
3325 result = fchown(path.fd, uid, gid);
3326 else
3327#endif
3328#ifdef HAVE_LCHOWN
3329 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3330 result = lchown(path.narrow, uid, gid);
3331 else
3332#endif
3333#ifdef HAVE_FCHOWNAT
3334 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3335 result = fchownat(dir_fd, path.narrow, uid, gid,
3336 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3337 else
3338#endif
3339 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003341
3342 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003343 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003344 goto exit;
3345 }
3346
3347 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003348 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003349
3350exit:
3351 path_cleanup(&path);
3352 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003353}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003354#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003355
Christian Heimes4e30a842007-11-30 22:12:06 +00003356#ifdef HAVE_FCHOWN
3357PyDoc_STRVAR(posix_fchown__doc__,
3358"fchown(fd, uid, gid)\n\n\
3359Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003360fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003361
3362static PyObject *
3363posix_fchown(PyObject *self, PyObject *args)
3364{
Victor Stinner8c62be82010-05-06 00:08:46 +00003365 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003366 uid_t uid;
3367 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003369 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3370 _Py_Uid_Converter, &uid,
3371 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 return NULL;
3373 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003374 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003375 Py_END_ALLOW_THREADS
3376 if (res < 0)
3377 return posix_error();
3378 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003379}
3380#endif /* HAVE_FCHOWN */
3381
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003382#ifdef HAVE_LCHOWN
3383PyDoc_STRVAR(posix_lchown__doc__,
3384"lchown(path, uid, gid)\n\n\
3385Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386This function will not follow symbolic links.\n\
3387Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003388
3389static PyObject *
3390posix_lchown(PyObject *self, PyObject *args)
3391{
Victor Stinner292c8352012-10-30 02:17:38 +01003392 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003393 uid_t uid;
3394 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003395 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003396 memset(&path, 0, sizeof(path));
3397 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003398 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003399 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003400 _Py_Uid_Converter, &uid,
3401 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003402 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003403 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003404 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003406 if (res < 0) {
3407 path_error(&path);
3408 path_cleanup(&path);
3409 return NULL;
3410 }
3411 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 Py_INCREF(Py_None);
3413 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003414}
3415#endif /* HAVE_LCHOWN */
3416
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003417
Barry Warsaw53699e91996-12-10 23:23:01 +00003418static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003419posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003420{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003421 char *buf, *tmpbuf;
3422 char *cwd;
3423 const size_t chunk = 1024;
3424 size_t buflen = 0;
3425 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003426
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003427#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003429 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 wchar_t *wbuf2 = wbuf;
3431 PyObject *resobj;
3432 DWORD len;
3433 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003434 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003435 /* If the buffer is large enough, len does not include the
3436 terminating \0. If the buffer is too small, len includes
3437 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003438 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003439 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003440 if (wbuf2)
3441 len = GetCurrentDirectoryW(len, wbuf2);
3442 }
3443 Py_END_ALLOW_THREADS
3444 if (!wbuf2) {
3445 PyErr_NoMemory();
3446 return NULL;
3447 }
3448 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003449 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003450 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003451 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003452 }
3453 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003454 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003455 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 return resobj;
3457 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003458
3459 if (win32_warn_bytes_api())
3460 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003461#endif
3462
Victor Stinner4403d7d2015-04-25 00:16:10 +02003463 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003464 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003465 do {
3466 buflen += chunk;
3467 tmpbuf = PyMem_RawRealloc(buf, buflen);
3468 if (tmpbuf == NULL)
3469 break;
3470
3471 buf = tmpbuf;
3472 cwd = getcwd(buf, buflen);
3473 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003474 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003475
3476 if (cwd == NULL) {
3477 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003478 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003479 }
3480
Victor Stinner8c62be82010-05-06 00:08:46 +00003481 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003482 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3483 else
3484 obj = PyUnicode_DecodeFSDefault(buf);
3485 PyMem_RawFree(buf);
3486
3487 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003488}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003489
3490PyDoc_STRVAR(posix_getcwd__doc__,
3491"getcwd() -> path\n\n\
3492Return a unicode string representing the current working directory.");
3493
3494static PyObject *
3495posix_getcwd_unicode(PyObject *self)
3496{
3497 return posix_getcwd(0);
3498}
3499
3500PyDoc_STRVAR(posix_getcwdb__doc__,
3501"getcwdb() -> path\n\n\
3502Return a bytes string representing the current working directory.");
3503
3504static PyObject *
3505posix_getcwd_bytes(PyObject *self)
3506{
3507 return posix_getcwd(1);
3508}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003509
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3511#define HAVE_LINK 1
3512#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003513
Guido van Rossumb6775db1994-08-01 11:34:53 +00003514#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003515PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003516"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3517Create a hard link to a file.\n\
3518\n\
3519If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3520 descriptor open to a directory, and the respective path string (src or dst)\n\
3521 should be relative; the path will then be relative to that directory.\n\
3522If follow_symlinks is False, and the last element of src is a symbolic\n\
3523 link, link will create a link to the symbolic link itself instead of the\n\
3524 file the link points to.\n\
3525src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3526 platform. If they are unavailable, using them will raise a\n\
3527 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003528
Barry Warsaw53699e91996-12-10 23:23:01 +00003529static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003531{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 path_t src, dst;
3533 int src_dir_fd = DEFAULT_DIR_FD;
3534 int dst_dir_fd = DEFAULT_DIR_FD;
3535 int follow_symlinks = 1;
3536 PyObject *return_value = NULL;
3537 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3538 "follow_symlinks", NULL};
3539#ifdef MS_WINDOWS
3540 BOOL result;
3541#else
3542 int result;
3543#endif
3544
3545 memset(&src, 0, sizeof(src));
3546 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003547 src.function_name = "link";
3548 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3550 path_converter, &src,
3551 path_converter, &dst,
3552 dir_fd_converter, &src_dir_fd,
3553 dir_fd_converter, &dst_dir_fd,
3554 &follow_symlinks))
3555 return NULL;
3556
3557#ifndef HAVE_LINKAT
3558 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3559 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3560 goto exit;
3561 }
3562#endif
3563
3564 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3565 PyErr_SetString(PyExc_NotImplementedError,
3566 "link: src and dst must be the same type");
3567 goto exit;
3568 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003569
Brian Curtin1b9df392010-11-24 20:24:31 +00003570#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003571 Py_BEGIN_ALLOW_THREADS
3572 if (src.wide)
3573 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3574 else
3575 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3576 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003577
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08003579 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003581 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003582#else
3583 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003584#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003585 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3586 (dst_dir_fd != DEFAULT_DIR_FD) ||
3587 (!follow_symlinks))
3588 result = linkat(src_dir_fd, src.narrow,
3589 dst_dir_fd, dst.narrow,
3590 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3591 else
3592#endif
3593 result = link(src.narrow, dst.narrow);
3594 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003595
Larry Hastings9cf065c2012-06-22 16:30:09 -07003596 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08003597 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003599 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003600#endif
3601
3602 return_value = Py_None;
3603 Py_INCREF(Py_None);
3604
3605exit:
3606 path_cleanup(&src);
3607 path_cleanup(&dst);
3608 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003609}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003610#endif
3611
Brian Curtin1b9df392010-11-24 20:24:31 +00003612
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003613
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003614PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003615"listdir(path='.') -> list_of_filenames\n\n\
3616Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003617The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003618entries '.' and '..' even if they are present in the directory.\n\
3619\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003620path can be specified as either str or bytes. If path is bytes,\n\
3621 the filenames returned will also be bytes; in all other circumstances\n\
3622 the filenames returned will be str.\n\
3623On some platforms, path may also be specified as an open file descriptor;\n\
3624 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003626
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003627#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003628static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003629_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003630{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003631 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632 PyObject *v;
3633 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3634 BOOL result;
3635 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003636 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003637 char *bufptr = namebuf;
3638 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003639 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003640 PyObject *po = NULL;
3641 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003642
Gregory P. Smith40a21602013-03-20 20:52:50 -07003643 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003644 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003645 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003646
Gregory P. Smith40a21602013-03-20 20:52:50 -07003647 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003648 po_wchars = L".";
3649 len = 1;
3650 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003651 po_wchars = path->wide;
3652 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003653 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003654 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003655 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003656 if (!wnamebuf) {
3657 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003658 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003659 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003660 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003662 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003663 if (wch != SEP && wch != ALTSEP && wch != L':')
3664 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003665 wcscpy(wnamebuf + len, L"*.*");
3666 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003667 if ((list = PyList_New(0)) == NULL) {
3668 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003669 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003670 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003672 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003673 if (hFindFile == INVALID_HANDLE_VALUE) {
3674 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003675 if (error == ERROR_FILE_NOT_FOUND)
3676 goto exit;
3677 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003678 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003679 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003680 }
3681 do {
3682 /* Skip over . and .. */
3683 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3684 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003685 v = PyUnicode_FromWideChar(wFileData.cFileName,
3686 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003687 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003688 Py_DECREF(list);
3689 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003690 break;
3691 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003692 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003693 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003694 Py_DECREF(list);
3695 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 break;
3697 }
3698 Py_DECREF(v);
3699 }
3700 Py_BEGIN_ALLOW_THREADS
3701 result = FindNextFileW(hFindFile, &wFileData);
3702 Py_END_ALLOW_THREADS
3703 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3704 it got to the end of the directory. */
3705 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003706 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003707 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003708 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 }
3710 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003711
Larry Hastings9cf065c2012-06-22 16:30:09 -07003712 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003713 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003714 strcpy(namebuf, path->narrow);
3715 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003716 if (len > 0) {
3717 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003718 if (ch != '\\' && ch != '/' && ch != ':')
3719 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003720 strcpy(namebuf + len, "*.*");
3721 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003722
Larry Hastings9cf065c2012-06-22 16:30:09 -07003723 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003724 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003725
Antoine Pitroub73caab2010-08-09 23:39:31 +00003726 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003727 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003728 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003729 if (hFindFile == INVALID_HANDLE_VALUE) {
3730 int error = GetLastError();
3731 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003732 goto exit;
3733 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003734 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003735 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003736 }
3737 do {
3738 /* Skip over . and .. */
3739 if (strcmp(FileData.cFileName, ".") != 0 &&
3740 strcmp(FileData.cFileName, "..") != 0) {
3741 v = PyBytes_FromString(FileData.cFileName);
3742 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003743 Py_DECREF(list);
3744 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003745 break;
3746 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003747 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003748 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003749 Py_DECREF(list);
3750 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003751 break;
3752 }
3753 Py_DECREF(v);
3754 }
3755 Py_BEGIN_ALLOW_THREADS
3756 result = FindNextFile(hFindFile, &FileData);
3757 Py_END_ALLOW_THREADS
3758 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3759 it got to the end of the directory. */
3760 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003761 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003762 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003763 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003764 }
3765 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003766
Larry Hastings9cf065c2012-06-22 16:30:09 -07003767exit:
3768 if (hFindFile != INVALID_HANDLE_VALUE) {
3769 if (FindClose(hFindFile) == FALSE) {
3770 if (list != NULL) {
3771 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003772 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003773 }
3774 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003775 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003776 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003777
Larry Hastings9cf065c2012-06-22 16:30:09 -07003778 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003779} /* end of _listdir_windows_no_opendir */
3780
3781#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3782
3783static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003784_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003785{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003786 PyObject *v;
3787 DIR *dirp = NULL;
3788 struct dirent *ep;
3789 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003790#ifdef HAVE_FDOPENDIR
3791 int fd = -1;
3792#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003793
Victor Stinner8c62be82010-05-06 00:08:46 +00003794 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003795#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003796 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003797 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003798 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003799 if (fd == -1)
3800 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003801
Larry Hastingsfdaea062012-06-25 04:42:23 -07003802 return_str = 1;
3803
Larry Hastings9cf065c2012-06-22 16:30:09 -07003804 Py_BEGIN_ALLOW_THREADS
3805 dirp = fdopendir(fd);
3806 Py_END_ALLOW_THREADS
3807 }
3808 else
3809#endif
3810 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003811 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003812 if (path->narrow) {
3813 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003814 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003815 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003816 }
3817 else {
3818 name = ".";
3819 return_str = 1;
3820 }
3821
Larry Hastings9cf065c2012-06-22 16:30:09 -07003822 Py_BEGIN_ALLOW_THREADS
3823 dirp = opendir(name);
3824 Py_END_ALLOW_THREADS
3825 }
3826
3827 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003828 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003829#ifdef HAVE_FDOPENDIR
3830 if (fd != -1) {
3831 Py_BEGIN_ALLOW_THREADS
3832 close(fd);
3833 Py_END_ALLOW_THREADS
3834 }
3835#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003836 goto exit;
3837 }
3838 if ((list = PyList_New(0)) == NULL) {
3839 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003840 }
3841 for (;;) {
3842 errno = 0;
3843 Py_BEGIN_ALLOW_THREADS
3844 ep = readdir(dirp);
3845 Py_END_ALLOW_THREADS
3846 if (ep == NULL) {
3847 if (errno == 0) {
3848 break;
3849 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003850 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003851 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003852 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003853 }
3854 }
3855 if (ep->d_name[0] == '.' &&
3856 (NAMLEN(ep) == 1 ||
3857 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3858 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003859 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003860 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3861 else
3862 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003863 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003864 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003865 break;
3866 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003867 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003868 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003869 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003870 break;
3871 }
3872 Py_DECREF(v);
3873 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003874
Larry Hastings9cf065c2012-06-22 16:30:09 -07003875exit:
3876 if (dirp != NULL) {
3877 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003878#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003879 if (fd > -1)
3880 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003881#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003882 closedir(dirp);
3883 Py_END_ALLOW_THREADS
3884 }
3885
Larry Hastings9cf065c2012-06-22 16:30:09 -07003886 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003887} /* end of _posix_listdir */
3888#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003889
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003890static PyObject *
3891posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3892{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003893 path_t path;
3894 PyObject *list = NULL;
3895 static char *keywords[] = {"path", NULL};
3896 PyObject *return_value;
3897
3898 memset(&path, 0, sizeof(path));
3899 path.function_name = "listdir";
3900 path.nullable = 1;
3901#ifdef HAVE_FDOPENDIR
3902 path.allow_fd = 1;
3903 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003904#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003905
3906 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3907 path_converter, &path)) {
3908 return NULL;
3909 }
3910
3911#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3912 return_value = _listdir_windows_no_opendir(&path, list);
3913#else
3914 return_value = _posix_listdir(&path, list);
3915#endif
3916 path_cleanup(&path);
3917 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003918}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003919
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003920#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003921/* A helper function for abspath on win32 */
3922static PyObject *
3923posix__getfullpathname(PyObject *self, PyObject *args)
3924{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003925 const char *path;
Victor Stinner75875072013-11-24 19:23:25 +01003926 char outbuf[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00003927 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003928 PyObject *po;
3929
3930 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3931 {
3932 wchar_t *wpath;
Victor Stinner75875072013-11-24 19:23:25 +01003933 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003934 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003935 DWORD result;
3936 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003937
3938 wpath = PyUnicode_AsUnicode(po);
3939 if (wpath == NULL)
3940 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003941 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003942 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003943 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003944 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003945 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003946 if (!woutbufp)
3947 return PyErr_NoMemory();
3948 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3949 }
3950 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003951 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003953 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003954 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003955 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003956 return v;
3957 }
3958 /* Drop the argument parsing error as narrow strings
3959 are also valid. */
3960 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003961
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003962 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3963 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003964 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003965 if (win32_warn_bytes_api())
3966 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003967 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003968 outbuf, &temp)) {
3969 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003970 return NULL;
3971 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003972 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3973 return PyUnicode_Decode(outbuf, strlen(outbuf),
3974 Py_FileSystemDefaultEncoding, NULL);
3975 }
3976 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003977} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003978
Brian Curtind25aef52011-06-13 15:16:04 -05003979
Brian Curtinf5e76d02010-11-24 13:14:05 +00003980
Brian Curtind40e6f72010-07-08 21:39:08 +00003981/* A helper function for samepath on windows */
3982static PyObject *
3983posix__getfinalpathname(PyObject *self, PyObject *args)
3984{
3985 HANDLE hFile;
3986 int buf_size;
3987 wchar_t *target_path;
3988 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003989 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003990 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003991
Victor Stinnereb5657a2011-09-30 01:44:27 +02003992 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003993 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003994 path = PyUnicode_AsUnicode(po);
3995 if (path == NULL)
3996 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003997
3998 if(!check_GetFinalPathNameByHandle()) {
3999 /* If the OS doesn't have GetFinalPathNameByHandle, return a
4000 NotImplementedError. */
4001 return PyErr_Format(PyExc_NotImplementedError,
4002 "GetFinalPathNameByHandle not available on this platform");
4003 }
4004
4005 hFile = CreateFileW(
4006 path,
4007 0, /* desired access */
4008 0, /* share mode */
4009 NULL, /* security attributes */
4010 OPEN_EXISTING,
4011 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4012 FILE_FLAG_BACKUP_SEMANTICS,
4013 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004014
Victor Stinnereb5657a2011-09-30 01:44:27 +02004015 if(hFile == INVALID_HANDLE_VALUE)
4016 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00004017
4018 /* We have a good handle to the target, use it to determine the
4019 target path name. */
4020 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
4021
4022 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02004023 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00004024
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004025 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00004026 if(!target_path)
4027 return PyErr_NoMemory();
4028
4029 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
4030 buf_size, VOLUME_NAME_DOS);
4031 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02004032 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00004033
4034 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02004035 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00004036
4037 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004038 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02004039 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004040 return result;
4041
4042} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00004043
Brian Curtin95d028f2011-06-09 09:10:38 -05004044PyDoc_STRVAR(posix__isdir__doc__,
4045"Return true if the pathname refers to an existing directory.");
4046
Brian Curtin9c669cc2011-06-08 18:17:18 -05004047static PyObject *
4048posix__isdir(PyObject *self, PyObject *args)
4049{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004050 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004051 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004052 DWORD attributes;
4053
4054 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02004055 wchar_t *wpath = PyUnicode_AsUnicode(po);
4056 if (wpath == NULL)
4057 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004058
4059 attributes = GetFileAttributesW(wpath);
4060 if (attributes == INVALID_FILE_ATTRIBUTES)
4061 Py_RETURN_FALSE;
4062 goto check;
4063 }
4064 /* Drop the argument parsing error as narrow strings
4065 are also valid. */
4066 PyErr_Clear();
4067
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004068 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05004069 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004070 if (win32_warn_bytes_api())
4071 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004072 attributes = GetFileAttributesA(path);
4073 if (attributes == INVALID_FILE_ATTRIBUTES)
4074 Py_RETURN_FALSE;
4075
4076check:
4077 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4078 Py_RETURN_TRUE;
4079 else
4080 Py_RETURN_FALSE;
4081}
Tim Golden6b528062013-08-01 12:44:00 +01004082
4083PyDoc_STRVAR(posix__getvolumepathname__doc__,
4084"Return volume mount point of the specified path.");
4085
4086/* A helper function for ismount on windows */
4087static PyObject *
4088posix__getvolumepathname(PyObject *self, PyObject *args)
4089{
4090 PyObject *po, *result;
4091 wchar_t *path, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004092 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004093 BOOL ret;
4094
4095 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
4096 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004097 path = PyUnicode_AsUnicodeAndSize(po, &buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004098 if (path == NULL)
4099 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004100 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01004101
4102 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01004103 buflen = Py_MAX(buflen, MAX_PATH);
4104
4105 if (buflen > DWORD_MAX) {
4106 PyErr_SetString(PyExc_OverflowError, "path too long");
4107 return NULL;
4108 }
4109
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004110 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004111 if (mountpath == NULL)
4112 return PyErr_NoMemory();
4113
4114 Py_BEGIN_ALLOW_THREADS
Christian Heimes85ba92a2013-11-18 10:30:42 +01004115 ret = GetVolumePathNameW(path, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004116 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004117 Py_END_ALLOW_THREADS
4118
4119 if (!ret) {
4120 result = win32_error_object("_getvolumepathname", po);
4121 goto exit;
4122 }
4123 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4124
4125exit:
4126 PyMem_Free(mountpath);
4127 return result;
4128}
4129/* end of posix__getvolumepathname */
4130
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004131#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004132
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004133PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4135Create a directory.\n\
4136\n\
4137If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4138 and path should be relative; path will then be relative to that directory.\n\
4139dir_fd may not be implemented on your platform.\n\
4140 If it is unavailable, using it will raise a NotImplementedError.\n\
4141\n\
4142The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004143
Barry Warsaw53699e91996-12-10 23:23:01 +00004144static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004145posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004146{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004147 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004148 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004149 int dir_fd = DEFAULT_DIR_FD;
4150 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
4151 PyObject *return_value = NULL;
4152 int result;
4153
4154 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004155 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004156 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4157 path_converter, &path, &mode,
4158#ifdef HAVE_MKDIRAT
4159 dir_fd_converter, &dir_fd
4160#else
4161 dir_fd_unavailable, &dir_fd
4162#endif
4163 ))
4164 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004165
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004166#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004167 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004168 if (path.wide)
4169 result = CreateDirectoryW(path.wide, NULL);
4170 else
4171 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004172 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004173
Larry Hastings9cf065c2012-06-22 16:30:09 -07004174 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004175 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004176 goto exit;
4177 }
4178#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004179 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004180#if HAVE_MKDIRAT
4181 if (dir_fd != DEFAULT_DIR_FD)
4182 result = mkdirat(dir_fd, path.narrow, mode);
4183 else
4184#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004185#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004186 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004187#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004188 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004189#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004190 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004191 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01004192 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004193 goto exit;
4194 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004195#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004196 return_value = Py_None;
4197 Py_INCREF(Py_None);
4198exit:
4199 path_cleanup(&path);
4200 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004201}
4202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004203
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004204/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4205#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004206#include <sys/resource.h>
4207#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004208
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004209
4210#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004211PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004212"nice(inc) -> new_priority\n\n\
4213Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004214
Barry Warsaw53699e91996-12-10 23:23:01 +00004215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004216posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004217{
Victor Stinner8c62be82010-05-06 00:08:46 +00004218 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004219
Victor Stinner8c62be82010-05-06 00:08:46 +00004220 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4221 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004222
Victor Stinner8c62be82010-05-06 00:08:46 +00004223 /* There are two flavours of 'nice': one that returns the new
4224 priority (as required by almost all standards out there) and the
4225 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4226 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004227
Victor Stinner8c62be82010-05-06 00:08:46 +00004228 If we are of the nice family that returns the new priority, we
4229 need to clear errno before the call, and check if errno is filled
4230 before calling posix_error() on a returnvalue of -1, because the
4231 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004232
Victor Stinner8c62be82010-05-06 00:08:46 +00004233 errno = 0;
4234 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004235#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004236 if (value == 0)
4237 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004238#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004239 if (value == -1 && errno != 0)
4240 /* either nice() or getpriority() returned an error */
4241 return posix_error();
4242 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004243}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004244#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004245
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004246
4247#ifdef HAVE_GETPRIORITY
4248PyDoc_STRVAR(posix_getpriority__doc__,
4249"getpriority(which, who) -> current_priority\n\n\
4250Get program scheduling priority.");
4251
4252static PyObject *
4253posix_getpriority(PyObject *self, PyObject *args)
4254{
4255 int which, who, retval;
4256
4257 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4258 return NULL;
4259 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004260 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004261 if (errno != 0)
4262 return posix_error();
4263 return PyLong_FromLong((long)retval);
4264}
4265#endif /* HAVE_GETPRIORITY */
4266
4267
4268#ifdef HAVE_SETPRIORITY
4269PyDoc_STRVAR(posix_setpriority__doc__,
4270"setpriority(which, who, prio) -> None\n\n\
4271Set program scheduling priority.");
4272
4273static PyObject *
4274posix_setpriority(PyObject *self, PyObject *args)
4275{
4276 int which, who, prio, retval;
4277
4278 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4279 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004280 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004281 if (retval == -1)
4282 return posix_error();
4283 Py_RETURN_NONE;
4284}
4285#endif /* HAVE_SETPRIORITY */
4286
4287
Barry Warsaw53699e91996-12-10 23:23:01 +00004288static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004289internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004290{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004291 char *function_name = is_replace ? "replace" : "rename";
4292 path_t src;
4293 path_t dst;
4294 int src_dir_fd = DEFAULT_DIR_FD;
4295 int dst_dir_fd = DEFAULT_DIR_FD;
4296 int dir_fd_specified;
4297 PyObject *return_value = NULL;
4298 char format[24];
4299 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4300
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004301#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004302 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004303 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004304#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004305 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004306#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004307
4308 memset(&src, 0, sizeof(src));
4309 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01004310 src.function_name = function_name;
4311 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004312 strcpy(format, "O&O&|$O&O&:");
4313 strcat(format, function_name);
4314 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4315 path_converter, &src,
4316 path_converter, &dst,
4317 dir_fd_converter, &src_dir_fd,
4318 dir_fd_converter, &dst_dir_fd))
4319 return NULL;
4320
4321 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4322 (dst_dir_fd != DEFAULT_DIR_FD);
4323#ifndef HAVE_RENAMEAT
4324 if (dir_fd_specified) {
4325 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4326 goto exit;
4327 }
4328#endif
4329
4330 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4331 PyErr_Format(PyExc_ValueError,
4332 "%s: src and dst must be the same type", function_name);
4333 goto exit;
4334 }
4335
4336#ifdef MS_WINDOWS
4337 Py_BEGIN_ALLOW_THREADS
4338 if (src.wide)
4339 result = MoveFileExW(src.wide, dst.wide, flags);
4340 else
4341 result = MoveFileExA(src.narrow, dst.narrow, flags);
4342 Py_END_ALLOW_THREADS
4343
4344 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08004345 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004346 goto exit;
4347 }
4348
4349#else
4350 Py_BEGIN_ALLOW_THREADS
4351#ifdef HAVE_RENAMEAT
4352 if (dir_fd_specified)
4353 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4354 else
4355#endif
4356 result = rename(src.narrow, dst.narrow);
4357 Py_END_ALLOW_THREADS
4358
4359 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08004360 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004361 goto exit;
4362 }
4363#endif
4364
4365 Py_INCREF(Py_None);
4366 return_value = Py_None;
4367exit:
4368 path_cleanup(&src);
4369 path_cleanup(&dst);
4370 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004371}
4372
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004373PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004374"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4375Rename a file or directory.\n\
4376\n\
4377If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4378 descriptor open to a directory, and the respective path string (src or dst)\n\
4379 should be relative; the path will then be relative to that directory.\n\
4380src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4381 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004382
4383static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004384posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004385{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004386 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004387}
4388
4389PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004390"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4391Rename a file or directory, overwriting the destination.\n\
4392\n\
4393If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4394 descriptor open to a directory, and the respective path string (src or dst)\n\
4395 should be relative; the path will then be relative to that directory.\n\
4396src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4397 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004398
4399static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004400posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004401{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004402 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004403}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004404
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004405PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004406"rmdir(path, *, dir_fd=None)\n\n\
4407Remove a directory.\n\
4408\n\
4409If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4410 and path should be relative; path will then be relative to that directory.\n\
4411dir_fd may not be implemented on your platform.\n\
4412 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004413
Barry Warsaw53699e91996-12-10 23:23:01 +00004414static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004415posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004416{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004417 path_t path;
4418 int dir_fd = DEFAULT_DIR_FD;
4419 static char *keywords[] = {"path", "dir_fd", NULL};
4420 int result;
4421 PyObject *return_value = NULL;
4422
4423 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004424 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004425 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4426 path_converter, &path,
4427#ifdef HAVE_UNLINKAT
4428 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004429#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004430 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004431#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004432 ))
4433 return NULL;
4434
4435 Py_BEGIN_ALLOW_THREADS
4436#ifdef MS_WINDOWS
4437 if (path.wide)
4438 result = RemoveDirectoryW(path.wide);
4439 else
4440 result = RemoveDirectoryA(path.narrow);
4441 result = !result; /* Windows, success=1, UNIX, success=0 */
4442#else
4443#ifdef HAVE_UNLINKAT
4444 if (dir_fd != DEFAULT_DIR_FD)
4445 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4446 else
4447#endif
4448 result = rmdir(path.narrow);
4449#endif
4450 Py_END_ALLOW_THREADS
4451
4452 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004453 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004454 goto exit;
4455 }
4456
4457 return_value = Py_None;
4458 Py_INCREF(Py_None);
4459
4460exit:
4461 path_cleanup(&path);
4462 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004463}
4464
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004465
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004466#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004467PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004468"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004469Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004470
Barry Warsaw53699e91996-12-10 23:23:01 +00004471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004472posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004473{
Victor Stinner8c62be82010-05-06 00:08:46 +00004474 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004475#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004476 wchar_t *command;
4477 if (!PyArg_ParseTuple(args, "u:system", &command))
4478 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004479
Victor Stinner8c62be82010-05-06 00:08:46 +00004480 Py_BEGIN_ALLOW_THREADS
4481 sts = _wsystem(command);
4482 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004483#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004484 PyObject *command_obj;
4485 char *command;
4486 if (!PyArg_ParseTuple(args, "O&:system",
4487 PyUnicode_FSConverter, &command_obj))
4488 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004489
Victor Stinner8c62be82010-05-06 00:08:46 +00004490 command = PyBytes_AsString(command_obj);
4491 Py_BEGIN_ALLOW_THREADS
4492 sts = system(command);
4493 Py_END_ALLOW_THREADS
4494 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004495#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004496 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004497}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004498#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004499
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004500
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004501PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004502"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004503Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004504
Barry Warsaw53699e91996-12-10 23:23:01 +00004505static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004506posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004507{
Victor Stinner8c62be82010-05-06 00:08:46 +00004508 int i;
4509 if (!PyArg_ParseTuple(args, "i:umask", &i))
4510 return NULL;
4511 i = (int)umask(i);
4512 if (i < 0)
4513 return posix_error();
4514 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004515}
4516
Brian Curtind40e6f72010-07-08 21:39:08 +00004517#ifdef MS_WINDOWS
4518
4519/* override the default DeleteFileW behavior so that directory
4520symlinks can be removed with this function, the same as with
4521Unix symlinks */
4522BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4523{
4524 WIN32_FILE_ATTRIBUTE_DATA info;
4525 WIN32_FIND_DATAW find_data;
4526 HANDLE find_data_handle;
4527 int is_directory = 0;
4528 int is_link = 0;
4529
4530 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4531 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004532
Brian Curtind40e6f72010-07-08 21:39:08 +00004533 /* Get WIN32_FIND_DATA structure for the path to determine if
4534 it is a symlink */
4535 if(is_directory &&
4536 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4537 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4538
4539 if(find_data_handle != INVALID_HANDLE_VALUE) {
4540 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4541 FindClose(find_data_handle);
4542 }
4543 }
4544 }
4545
4546 if (is_directory && is_link)
4547 return RemoveDirectoryW(lpFileName);
4548
4549 return DeleteFileW(lpFileName);
4550}
4551#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004552
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004553PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004554"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004555Remove a file (same as remove()).\n\
4556\n\
4557If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4558 and path should be relative; path will then be relative to that directory.\n\
4559dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004560 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004561
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004562PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004563"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004564Remove a file (same as unlink()).\n\
4565\n\
4566If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4567 and path should be relative; path will then be relative to that directory.\n\
4568dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004569 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004570
Barry Warsaw53699e91996-12-10 23:23:01 +00004571static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004573{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574 path_t path;
4575 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004576 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004577 int result;
4578 PyObject *return_value = NULL;
4579
4580 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004581 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004582 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004583 path_converter, &path,
4584#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004585 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004586#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004587 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004588#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004589 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590 return NULL;
4591
4592 Py_BEGIN_ALLOW_THREADS
4593#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004594 if (path.wide)
4595 result = Py_DeleteFileW(path.wide);
4596 else
4597 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598 result = !result; /* Windows, success=1, UNIX, success=0 */
4599#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004600#ifdef HAVE_UNLINKAT
4601 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004602 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004603 else
4604#endif /* HAVE_UNLINKAT */
4605 result = unlink(path.narrow);
4606#endif
4607 Py_END_ALLOW_THREADS
4608
4609 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004610 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004611 goto exit;
4612 }
4613
4614 return_value = Py_None;
4615 Py_INCREF(Py_None);
4616
4617exit:
4618 path_cleanup(&path);
4619 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004620}
4621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004623PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004624"uname() -> uname_result\n\n\
4625Return an object identifying the current operating system.\n\
4626The object behaves like a named tuple with the following fields:\n\
4627 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004628
Larry Hastings605a62d2012-06-24 04:33:36 -07004629static PyStructSequence_Field uname_result_fields[] = {
4630 {"sysname", "operating system name"},
4631 {"nodename", "name of machine on network (implementation-defined)"},
4632 {"release", "operating system release"},
4633 {"version", "operating system version"},
4634 {"machine", "hardware identifier"},
4635 {NULL}
4636};
4637
4638PyDoc_STRVAR(uname_result__doc__,
4639"uname_result: Result from os.uname().\n\n\
4640This object may be accessed either as a tuple of\n\
4641 (sysname, nodename, release, version, machine),\n\
4642or via the attributes sysname, nodename, release, version, and machine.\n\
4643\n\
4644See os.uname for more information.");
4645
4646static PyStructSequence_Desc uname_result_desc = {
4647 "uname_result", /* name */
4648 uname_result__doc__, /* doc */
4649 uname_result_fields,
4650 5
4651};
4652
4653static PyTypeObject UnameResultType;
4654
4655
4656#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004657static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004658posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004659{
Victor Stinner8c62be82010-05-06 00:08:46 +00004660 struct utsname u;
4661 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004662 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004663
Victor Stinner8c62be82010-05-06 00:08:46 +00004664 Py_BEGIN_ALLOW_THREADS
4665 res = uname(&u);
4666 Py_END_ALLOW_THREADS
4667 if (res < 0)
4668 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004669
4670 value = PyStructSequence_New(&UnameResultType);
4671 if (value == NULL)
4672 return NULL;
4673
4674#define SET(i, field) \
4675 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004676 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004677 if (!o) { \
4678 Py_DECREF(value); \
4679 return NULL; \
4680 } \
4681 PyStructSequence_SET_ITEM(value, i, o); \
4682 } \
4683
4684 SET(0, u.sysname);
4685 SET(1, u.nodename);
4686 SET(2, u.release);
4687 SET(3, u.version);
4688 SET(4, u.machine);
4689
4690#undef SET
4691
4692 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004693}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004694#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004695
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004696
Larry Hastings9cf065c2012-06-22 16:30:09 -07004697PyDoc_STRVAR(posix_utime__doc__,
4698"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4699Set the access and modified time of path.\n\
4700\n\
4701path may always be specified as a string.\n\
4702On some platforms, path may also be specified as an open file descriptor.\n\
4703 If this functionality is unavailable, using it raises an exception.\n\
4704\n\
4705If times is not None, it must be a tuple (atime, mtime);\n\
4706 atime and mtime should be expressed as float seconds since the epoch.\n\
4707If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4708 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4709 since the epoch.\n\
4710If both times and ns are None, utime uses the current time.\n\
4711Specifying tuples for both times and ns is an error.\n\
4712\n\
4713If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4714 and path should be relative; path will then be relative to that directory.\n\
4715If follow_symlinks is False, and the last element of the path is a symbolic\n\
4716 link, utime will modify the symbolic link itself instead of the file the\n\
4717 link points to.\n\
4718It is an error to use dir_fd or follow_symlinks when specifying path\n\
4719 as an open file descriptor.\n\
4720dir_fd and follow_symlinks may not be available on your platform.\n\
4721 If they are unavailable, using them will raise a NotImplementedError.");
4722
4723typedef struct {
4724 int now;
4725 time_t atime_s;
4726 long atime_ns;
4727 time_t mtime_s;
4728 long mtime_ns;
4729} utime_t;
4730
4731/*
Victor Stinner484df002014-10-09 13:52:31 +02004732 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004733 * they also intentionally leak the declaration of a pointer named "time"
4734 */
4735#define UTIME_TO_TIMESPEC \
4736 struct timespec ts[2]; \
4737 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004738 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004739 time = NULL; \
4740 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004741 ts[0].tv_sec = ut->atime_s; \
4742 ts[0].tv_nsec = ut->atime_ns; \
4743 ts[1].tv_sec = ut->mtime_s; \
4744 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 time = ts; \
4746 } \
4747
4748#define UTIME_TO_TIMEVAL \
4749 struct timeval tv[2]; \
4750 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004751 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004752 time = NULL; \
4753 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004754 tv[0].tv_sec = ut->atime_s; \
4755 tv[0].tv_usec = ut->atime_ns / 1000; \
4756 tv[1].tv_sec = ut->mtime_s; \
4757 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 time = tv; \
4759 } \
4760
4761#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004762 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004764 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 time = NULL; \
4766 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004767 u.actime = ut->atime_s; \
4768 u.modtime = ut->mtime_s; \
4769 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770 }
4771
4772#define UTIME_TO_TIME_T \
4773 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004774 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004775 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004776 time = NULL; \
4777 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004778 timet[0] = ut->atime_s; \
4779 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004780 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004781 } \
4782
4783
4784#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4785
4786#if UTIME_HAVE_DIR_FD
4787
4788static int
Victor Stinner484df002014-10-09 13:52:31 +02004789utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004790{
4791#ifdef HAVE_UTIMENSAT
4792 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4793 UTIME_TO_TIMESPEC;
4794 return utimensat(dir_fd, path, time, flags);
4795#elif defined(HAVE_FUTIMESAT)
4796 UTIME_TO_TIMEVAL;
4797 /*
4798 * follow_symlinks will never be false here;
4799 * we only allow !follow_symlinks and dir_fd together
4800 * if we have utimensat()
4801 */
4802 assert(follow_symlinks);
4803 return futimesat(dir_fd, path, time);
4804#endif
4805}
4806
4807#endif
4808
4809#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4810
4811#if UTIME_HAVE_FD
4812
4813static int
Victor Stinner484df002014-10-09 13:52:31 +02004814utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004815{
4816#ifdef HAVE_FUTIMENS
4817 UTIME_TO_TIMESPEC;
4818 return futimens(fd, time);
4819#else
4820 UTIME_TO_TIMEVAL;
4821 return futimes(fd, time);
4822#endif
4823}
4824
4825#endif
4826
4827
4828#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4829 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4830
4831#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4832
4833static int
Victor Stinner484df002014-10-09 13:52:31 +02004834utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004835{
4836#ifdef HAVE_UTIMENSAT
4837 UTIME_TO_TIMESPEC;
4838 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4839#else
4840 UTIME_TO_TIMEVAL;
4841 return lutimes(path, time);
4842#endif
4843}
4844
4845#endif
4846
4847#ifndef MS_WINDOWS
4848
4849static int
Victor Stinner484df002014-10-09 13:52:31 +02004850utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004851{
4852#ifdef HAVE_UTIMENSAT
4853 UTIME_TO_TIMESPEC;
4854 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4855#elif defined(HAVE_UTIMES)
4856 UTIME_TO_TIMEVAL;
4857 return utimes(path, time);
4858#elif defined(HAVE_UTIME_H)
4859 UTIME_TO_UTIMBUF;
4860 return utime(path, time);
4861#else
4862 UTIME_TO_TIME_T;
4863 return utime(path, time);
4864#endif
4865}
4866
4867#endif
4868
Larry Hastings76ad59b2012-05-03 00:30:07 -07004869static int
4870split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4871{
4872 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004873 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004874 divmod = PyNumber_Divmod(py_long, billion);
4875 if (!divmod)
4876 goto exit;
4877 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4878 if ((*s == -1) && PyErr_Occurred())
4879 goto exit;
4880 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004881 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004882 goto exit;
4883
4884 result = 1;
4885exit:
4886 Py_XDECREF(divmod);
4887 return result;
4888}
4889
Larry Hastings9cf065c2012-06-22 16:30:09 -07004890static PyObject *
4891posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004892{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004893 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004894 PyObject *times = NULL;
4895 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004896 int dir_fd = DEFAULT_DIR_FD;
4897 int follow_symlinks = 1;
4898 char *keywords[] = {"path", "times", "ns", "dir_fd",
4899 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004900
Larry Hastings9cf065c2012-06-22 16:30:09 -07004901 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004902
Larry Hastings9cf065c2012-06-22 16:30:09 -07004903#ifdef MS_WINDOWS
4904 HANDLE hFile;
4905 FILETIME atime, mtime;
4906#else
4907 int result;
4908#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004909
Larry Hastings9cf065c2012-06-22 16:30:09 -07004910 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004911
Larry Hastings9cf065c2012-06-22 16:30:09 -07004912 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004913 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004914 memset(&utime, 0, sizeof(utime_t));
Larry Hastings9cf065c2012-06-22 16:30:09 -07004915#if UTIME_HAVE_FD
4916 path.allow_fd = 1;
4917#endif
4918 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4919 "O&|O$OO&p:utime", keywords,
4920 path_converter, &path,
4921 &times, &ns,
4922#if UTIME_HAVE_DIR_FD
4923 dir_fd_converter, &dir_fd,
4924#else
4925 dir_fd_unavailable, &dir_fd,
4926#endif
4927 &follow_symlinks
4928 ))
4929 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004930
Larry Hastings9cf065c2012-06-22 16:30:09 -07004931 if (times && (times != Py_None) && ns) {
4932 PyErr_SetString(PyExc_ValueError,
4933 "utime: you may specify either 'times'"
4934 " or 'ns' but not both");
4935 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004936 }
4937
4938 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004939 time_t a_sec, m_sec;
4940 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004941 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004942 PyErr_SetString(PyExc_TypeError,
4943 "utime: 'times' must be either"
4944 " a tuple of two ints or None");
4945 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004946 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004947 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004948 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004949 &a_sec, &a_nsec, _PyTime_ROUND_DOWN) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004950 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004951 &m_sec, &m_nsec, _PyTime_ROUND_DOWN) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004952 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004953 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004954 utime.atime_s = a_sec;
4955 utime.atime_ns = a_nsec;
4956 utime.mtime_s = m_sec;
4957 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004958 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004959 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004960 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004961 PyErr_SetString(PyExc_TypeError,
4962 "utime: 'ns' must be a tuple of two ints");
4963 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004964 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004965 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004966 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004967 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004968 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004969 &utime.mtime_s, &utime.mtime_ns)) {
4970 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004971 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004972 }
4973 else {
4974 /* times and ns are both None/unspecified. use "now". */
4975 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004976 }
4977
Larry Hastings9cf065c2012-06-22 16:30:09 -07004978#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4979 if (follow_symlinks_specified("utime", follow_symlinks))
4980 goto exit;
4981#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004982
Larry Hastings9cf065c2012-06-22 16:30:09 -07004983 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4984 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4985 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4986 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004987
Larry Hastings9cf065c2012-06-22 16:30:09 -07004988#if !defined(HAVE_UTIMENSAT)
4989 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004990 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004991 "utime: cannot use dir_fd and follow_symlinks "
4992 "together on this platform");
4993 goto exit;
4994 }
4995#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004996
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004997#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004998 Py_BEGIN_ALLOW_THREADS
4999 if (path.wide)
5000 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00005001 NULL, OPEN_EXISTING,
5002 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005003 else
5004 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00005005 NULL, OPEN_EXISTING,
5006 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005007 Py_END_ALLOW_THREADS
5008 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01005009 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005010 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07005011 }
5012
Larry Hastings9cf065c2012-06-22 16:30:09 -07005013 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005014 GetSystemTimeAsFileTime(&mtime);
5015 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005016 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005017 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005018 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5019 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005020 }
5021 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5022 /* Avoid putting the file name into the error here,
5023 as that may confuse the user into believing that
5024 something is wrong with the file, when it also
5025 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005026 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005027 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005028 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005029#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005030 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005031
Larry Hastings9cf065c2012-06-22 16:30:09 -07005032#if UTIME_HAVE_NOFOLLOW_SYMLINKS
5033 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
5034 result = utime_nofollow_symlinks(&utime, path.narrow);
5035 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005036#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005037
5038#if UTIME_HAVE_DIR_FD
5039 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
5040 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
5041 else
5042#endif
5043
5044#if UTIME_HAVE_FD
5045 if (path.fd != -1)
5046 result = utime_fd(&utime, path.fd);
5047 else
5048#endif
5049
5050 result = utime_default(&utime, path.narrow);
5051
5052 Py_END_ALLOW_THREADS
5053
5054 if (result < 0) {
5055 /* see previous comment about not putting filename in error here */
5056 return_value = posix_error();
5057 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005058 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005059
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005060#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005061
5062 Py_INCREF(Py_None);
5063 return_value = Py_None;
5064
5065exit:
5066 path_cleanup(&path);
5067#ifdef MS_WINDOWS
5068 if (hFile != INVALID_HANDLE_VALUE)
5069 CloseHandle(hFile);
5070#endif
5071 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005072}
5073
Guido van Rossum3b066191991-06-04 19:40:25 +00005074/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005075
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005076PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005077"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005078Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005079
Barry Warsaw53699e91996-12-10 23:23:01 +00005080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005081posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005082{
Victor Stinner8c62be82010-05-06 00:08:46 +00005083 int sts;
5084 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5085 return NULL;
5086 _exit(sts);
5087 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005088}
5089
Martin v. Löwis114619e2002-10-07 06:44:21 +00005090#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5091static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00005092free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005093{
Victor Stinner8c62be82010-05-06 00:08:46 +00005094 Py_ssize_t i;
5095 for (i = 0; i < count; i++)
5096 PyMem_Free(array[i]);
5097 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005098}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005099
Antoine Pitrou69f71142009-05-24 21:25:49 +00005100static
Martin v. Löwis011e8422009-05-05 04:43:17 +00005101int fsconvert_strdup(PyObject *o, char**out)
5102{
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 PyObject *bytes;
5104 Py_ssize_t size;
5105 if (!PyUnicode_FSConverter(o, &bytes))
5106 return 0;
5107 size = PyBytes_GET_SIZE(bytes);
5108 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01005109 if (!*out) {
5110 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01005112 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005113 memcpy(*out, PyBytes_AsString(bytes), size+1);
5114 Py_DECREF(bytes);
5115 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005116}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005117#endif
5118
Ross Lagerwall7807c352011-03-17 20:20:30 +02005119#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005120static char**
5121parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5122{
Victor Stinner8c62be82010-05-06 00:08:46 +00005123 char **envlist;
5124 Py_ssize_t i, pos, envc;
5125 PyObject *keys=NULL, *vals=NULL;
5126 PyObject *key, *val, *key2, *val2;
5127 char *p, *k, *v;
5128 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005129
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 i = PyMapping_Size(env);
5131 if (i < 0)
5132 return NULL;
5133 envlist = PyMem_NEW(char *, i + 1);
5134 if (envlist == NULL) {
5135 PyErr_NoMemory();
5136 return NULL;
5137 }
5138 envc = 0;
5139 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005140 if (!keys)
5141 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005142 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005143 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 goto error;
5145 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5146 PyErr_Format(PyExc_TypeError,
5147 "env.keys() or env.values() is not a list");
5148 goto error;
5149 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005150
Victor Stinner8c62be82010-05-06 00:08:46 +00005151 for (pos = 0; pos < i; pos++) {
5152 key = PyList_GetItem(keys, pos);
5153 val = PyList_GetItem(vals, pos);
5154 if (!key || !val)
5155 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005156
Victor Stinner8c62be82010-05-06 00:08:46 +00005157 if (PyUnicode_FSConverter(key, &key2) == 0)
5158 goto error;
5159 if (PyUnicode_FSConverter(val, &val2) == 0) {
5160 Py_DECREF(key2);
5161 goto error;
5162 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005163
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 k = PyBytes_AsString(key2);
5165 v = PyBytes_AsString(val2);
5166 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005167
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 p = PyMem_NEW(char, len);
5169 if (p == NULL) {
5170 PyErr_NoMemory();
5171 Py_DECREF(key2);
5172 Py_DECREF(val2);
5173 goto error;
5174 }
5175 PyOS_snprintf(p, len, "%s=%s", k, v);
5176 envlist[envc++] = p;
5177 Py_DECREF(key2);
5178 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005179 }
5180 Py_DECREF(vals);
5181 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005182
Victor Stinner8c62be82010-05-06 00:08:46 +00005183 envlist[envc] = 0;
5184 *envc_ptr = envc;
5185 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005186
5187error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005188 Py_XDECREF(keys);
5189 Py_XDECREF(vals);
5190 while (--envc >= 0)
5191 PyMem_DEL(envlist[envc]);
5192 PyMem_DEL(envlist);
5193 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005194}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005195
Ross Lagerwall7807c352011-03-17 20:20:30 +02005196static char**
5197parse_arglist(PyObject* argv, Py_ssize_t *argc)
5198{
5199 int i;
5200 char **argvlist = PyMem_NEW(char *, *argc+1);
5201 if (argvlist == NULL) {
5202 PyErr_NoMemory();
5203 return NULL;
5204 }
5205 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005206 PyObject* item = PySequence_ITEM(argv, i);
5207 if (item == NULL)
5208 goto fail;
5209 if (!fsconvert_strdup(item, &argvlist[i])) {
5210 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005211 goto fail;
5212 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005213 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005214 }
5215 argvlist[*argc] = NULL;
5216 return argvlist;
5217fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005218 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005219 free_string_array(argvlist, *argc);
5220 return NULL;
5221}
5222#endif
5223
5224#ifdef HAVE_EXECV
5225PyDoc_STRVAR(posix_execv__doc__,
5226"execv(path, args)\n\n\
5227Execute an executable path with arguments, replacing current process.\n\
5228\n\
5229 path: path of executable file\n\
5230 args: tuple or list of strings");
5231
5232static PyObject *
5233posix_execv(PyObject *self, PyObject *args)
5234{
5235 PyObject *opath;
5236 char *path;
5237 PyObject *argv;
5238 char **argvlist;
5239 Py_ssize_t argc;
5240
5241 /* execv has two arguments: (path, argv), where
5242 argv is a list or tuple of strings. */
5243
5244 if (!PyArg_ParseTuple(args, "O&O:execv",
5245 PyUnicode_FSConverter,
5246 &opath, &argv))
5247 return NULL;
5248 path = PyBytes_AsString(opath);
5249 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5250 PyErr_SetString(PyExc_TypeError,
5251 "execv() arg 2 must be a tuple or list");
5252 Py_DECREF(opath);
5253 return NULL;
5254 }
5255 argc = PySequence_Size(argv);
5256 if (argc < 1) {
5257 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5258 Py_DECREF(opath);
5259 return NULL;
5260 }
5261
5262 argvlist = parse_arglist(argv, &argc);
5263 if (argvlist == NULL) {
5264 Py_DECREF(opath);
5265 return NULL;
5266 }
5267
5268 execv(path, argvlist);
5269
5270 /* If we get here it's definitely an error */
5271
5272 free_string_array(argvlist, argc);
5273 Py_DECREF(opath);
5274 return posix_error();
5275}
5276
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005277PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005278"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005279Execute a path with arguments and environment, replacing current process.\n\
5280\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005281 path: path of executable file\n\
5282 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005283 env: dictionary of strings mapping to strings\n\
5284\n\
5285On some platforms, you may specify an open file descriptor for path;\n\
5286 execve will execute the program the file descriptor is open to.\n\
5287 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005288
Barry Warsaw53699e91996-12-10 23:23:01 +00005289static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005290posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005291{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005292 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005293 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005294 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005295 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005296 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005297 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005298
Victor Stinner8c62be82010-05-06 00:08:46 +00005299 /* execve has three arguments: (path, argv, env), where
5300 argv is a list or tuple of strings and env is a dictionary
5301 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005302
Larry Hastings9cf065c2012-06-22 16:30:09 -07005303 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005304 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005305#ifdef HAVE_FEXECVE
5306 path.allow_fd = 1;
5307#endif
5308 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5309 path_converter, &path,
5310 &argv, &env
5311 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005312 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005313
Ross Lagerwall7807c352011-03-17 20:20:30 +02005314 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005316 "execve: argv must be a tuple or list");
5317 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005318 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005319 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005320 if (!PyMapping_Check(env)) {
5321 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005322 "execve: environment must be a mapping object");
5323 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005324 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005325
Ross Lagerwall7807c352011-03-17 20:20:30 +02005326 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005327 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005328 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005329 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005330
Victor Stinner8c62be82010-05-06 00:08:46 +00005331 envlist = parse_envlist(env, &envc);
5332 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005333 goto fail;
5334
Larry Hastings9cf065c2012-06-22 16:30:09 -07005335#ifdef HAVE_FEXECVE
5336 if (path.fd > -1)
5337 fexecve(path.fd, argvlist, envlist);
5338 else
5339#endif
5340 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005341
5342 /* If we get here it's definitely an error */
5343
Victor Stinner292c8352012-10-30 02:17:38 +01005344 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005345
5346 while (--envc >= 0)
5347 PyMem_DEL(envlist[envc]);
5348 PyMem_DEL(envlist);
5349 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005350 if (argvlist)
5351 free_string_array(argvlist, argc);
5352 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005353 return NULL;
5354}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005355#endif /* HAVE_EXECV */
5356
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005357
Guido van Rossuma1065681999-01-25 23:20:23 +00005358#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005359PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005360"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005361Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005362\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005363 mode: mode of process creation\n\
5364 path: path of executable file\n\
5365 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005366
5367static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005368posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005369{
Victor Stinner8c62be82010-05-06 00:08:46 +00005370 PyObject *opath;
5371 char *path;
5372 PyObject *argv;
5373 char **argvlist;
5374 int mode, i;
5375 Py_ssize_t argc;
5376 Py_intptr_t spawnval;
5377 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005378
Victor Stinner8c62be82010-05-06 00:08:46 +00005379 /* spawnv has three arguments: (mode, path, argv), where
5380 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005381
Victor Stinner8c62be82010-05-06 00:08:46 +00005382 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5383 PyUnicode_FSConverter,
5384 &opath, &argv))
5385 return NULL;
5386 path = PyBytes_AsString(opath);
5387 if (PyList_Check(argv)) {
5388 argc = PyList_Size(argv);
5389 getitem = PyList_GetItem;
5390 }
5391 else if (PyTuple_Check(argv)) {
5392 argc = PyTuple_Size(argv);
5393 getitem = PyTuple_GetItem;
5394 }
5395 else {
5396 PyErr_SetString(PyExc_TypeError,
5397 "spawnv() arg 2 must be a tuple or list");
5398 Py_DECREF(opath);
5399 return NULL;
5400 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005401
Victor Stinner8c62be82010-05-06 00:08:46 +00005402 argvlist = PyMem_NEW(char *, argc+1);
5403 if (argvlist == NULL) {
5404 Py_DECREF(opath);
5405 return PyErr_NoMemory();
5406 }
5407 for (i = 0; i < argc; i++) {
5408 if (!fsconvert_strdup((*getitem)(argv, i),
5409 &argvlist[i])) {
5410 free_string_array(argvlist, i);
5411 PyErr_SetString(
5412 PyExc_TypeError,
5413 "spawnv() arg 2 must contain only strings");
5414 Py_DECREF(opath);
5415 return NULL;
5416 }
5417 }
5418 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005419
Victor Stinner8c62be82010-05-06 00:08:46 +00005420 if (mode == _OLD_P_OVERLAY)
5421 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005422
Victor Stinner8c62be82010-05-06 00:08:46 +00005423 Py_BEGIN_ALLOW_THREADS
5424 spawnval = _spawnv(mode, path, argvlist);
5425 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005426
Victor Stinner8c62be82010-05-06 00:08:46 +00005427 free_string_array(argvlist, argc);
5428 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005429
Victor Stinner8c62be82010-05-06 00:08:46 +00005430 if (spawnval == -1)
5431 return posix_error();
5432 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005433 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005434}
5435
5436
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005437PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005438"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005439Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005440\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005441 mode: mode of process creation\n\
5442 path: path of executable file\n\
5443 args: tuple or list of arguments\n\
5444 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005445
5446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005447posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005448{
Victor Stinner8c62be82010-05-06 00:08:46 +00005449 PyObject *opath;
5450 char *path;
5451 PyObject *argv, *env;
5452 char **argvlist;
5453 char **envlist;
5454 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005455 int mode;
5456 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005457 Py_intptr_t spawnval;
5458 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5459 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005460
Victor Stinner8c62be82010-05-06 00:08:46 +00005461 /* spawnve has four arguments: (mode, path, argv, env), where
5462 argv is a list or tuple of strings and env is a dictionary
5463 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005464
Victor Stinner8c62be82010-05-06 00:08:46 +00005465 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5466 PyUnicode_FSConverter,
5467 &opath, &argv, &env))
5468 return NULL;
5469 path = PyBytes_AsString(opath);
5470 if (PyList_Check(argv)) {
5471 argc = PyList_Size(argv);
5472 getitem = PyList_GetItem;
5473 }
5474 else if (PyTuple_Check(argv)) {
5475 argc = PyTuple_Size(argv);
5476 getitem = PyTuple_GetItem;
5477 }
5478 else {
5479 PyErr_SetString(PyExc_TypeError,
5480 "spawnve() arg 2 must be a tuple or list");
5481 goto fail_0;
5482 }
5483 if (!PyMapping_Check(env)) {
5484 PyErr_SetString(PyExc_TypeError,
5485 "spawnve() arg 3 must be a mapping object");
5486 goto fail_0;
5487 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005488
Victor Stinner8c62be82010-05-06 00:08:46 +00005489 argvlist = PyMem_NEW(char *, argc+1);
5490 if (argvlist == NULL) {
5491 PyErr_NoMemory();
5492 goto fail_0;
5493 }
5494 for (i = 0; i < argc; i++) {
5495 if (!fsconvert_strdup((*getitem)(argv, i),
5496 &argvlist[i]))
5497 {
5498 lastarg = i;
5499 goto fail_1;
5500 }
5501 }
5502 lastarg = argc;
5503 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005504
Victor Stinner8c62be82010-05-06 00:08:46 +00005505 envlist = parse_envlist(env, &envc);
5506 if (envlist == NULL)
5507 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005508
Victor Stinner8c62be82010-05-06 00:08:46 +00005509 if (mode == _OLD_P_OVERLAY)
5510 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005511
Victor Stinner8c62be82010-05-06 00:08:46 +00005512 Py_BEGIN_ALLOW_THREADS
5513 spawnval = _spawnve(mode, path, argvlist, envlist);
5514 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005515
Victor Stinner8c62be82010-05-06 00:08:46 +00005516 if (spawnval == -1)
5517 (void) posix_error();
5518 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005519 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005520
Victor Stinner8c62be82010-05-06 00:08:46 +00005521 while (--envc >= 0)
5522 PyMem_DEL(envlist[envc]);
5523 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005524 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005525 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005526 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005527 Py_DECREF(opath);
5528 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005529}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005530
Guido van Rossuma1065681999-01-25 23:20:23 +00005531#endif /* HAVE_SPAWNV */
5532
5533
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005534#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005535PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005536"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005537Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5538\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005539Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005540
5541static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005542posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005543{
Victor Stinner8c62be82010-05-06 00:08:46 +00005544 pid_t pid;
5545 int result = 0;
5546 _PyImport_AcquireLock();
5547 pid = fork1();
5548 if (pid == 0) {
5549 /* child: this clobbers and resets the import lock. */
5550 PyOS_AfterFork();
5551 } else {
5552 /* parent: release the import lock. */
5553 result = _PyImport_ReleaseLock();
5554 }
5555 if (pid == -1)
5556 return posix_error();
5557 if (result < 0) {
5558 /* Don't clobber the OSError if the fork failed. */
5559 PyErr_SetString(PyExc_RuntimeError,
5560 "not holding the import lock");
5561 return NULL;
5562 }
5563 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005564}
5565#endif
5566
5567
Guido van Rossumad0ee831995-03-01 10:34:45 +00005568#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005569PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005570"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005571Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005572Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005573
Barry Warsaw53699e91996-12-10 23:23:01 +00005574static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005575posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005576{
Victor Stinner8c62be82010-05-06 00:08:46 +00005577 pid_t pid;
5578 int result = 0;
5579 _PyImport_AcquireLock();
5580 pid = fork();
5581 if (pid == 0) {
5582 /* child: this clobbers and resets the import lock. */
5583 PyOS_AfterFork();
5584 } else {
5585 /* parent: release the import lock. */
5586 result = _PyImport_ReleaseLock();
5587 }
5588 if (pid == -1)
5589 return posix_error();
5590 if (result < 0) {
5591 /* Don't clobber the OSError if the fork failed. */
5592 PyErr_SetString(PyExc_RuntimeError,
5593 "not holding the import lock");
5594 return NULL;
5595 }
5596 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005597}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005598#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005599
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005600#ifdef HAVE_SCHED_H
5601
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005602#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5603
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005604PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5605"sched_get_priority_max(policy)\n\n\
5606Get the maximum scheduling priority for *policy*.");
5607
5608static PyObject *
5609posix_sched_get_priority_max(PyObject *self, PyObject *args)
5610{
5611 int policy, max;
5612
5613 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5614 return NULL;
5615 max = sched_get_priority_max(policy);
5616 if (max < 0)
5617 return posix_error();
5618 return PyLong_FromLong(max);
5619}
5620
5621PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5622"sched_get_priority_min(policy)\n\n\
5623Get the minimum scheduling priority for *policy*.");
5624
5625static PyObject *
5626posix_sched_get_priority_min(PyObject *self, PyObject *args)
5627{
5628 int policy, min;
5629
5630 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5631 return NULL;
5632 min = sched_get_priority_min(policy);
5633 if (min < 0)
5634 return posix_error();
5635 return PyLong_FromLong(min);
5636}
5637
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005638#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5639
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005640#ifdef HAVE_SCHED_SETSCHEDULER
5641
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005642PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5643"sched_getscheduler(pid)\n\n\
5644Get the scheduling policy for the process with a PID of *pid*.\n\
5645Passing a PID of 0 returns the scheduling policy for the calling process.");
5646
5647static PyObject *
5648posix_sched_getscheduler(PyObject *self, PyObject *args)
5649{
5650 pid_t pid;
5651 int policy;
5652
5653 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5654 return NULL;
5655 policy = sched_getscheduler(pid);
5656 if (policy < 0)
5657 return posix_error();
5658 return PyLong_FromLong(policy);
5659}
5660
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005661#endif
5662
5663#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5664
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005665static PyObject *
5666sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5667{
5668 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005669 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005670
5671 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5672 return NULL;
5673 res = PyStructSequence_New(type);
5674 if (!res)
5675 return NULL;
5676 Py_INCREF(priority);
5677 PyStructSequence_SET_ITEM(res, 0, priority);
5678 return res;
5679}
5680
5681PyDoc_STRVAR(sched_param__doc__,
5682"sched_param(sched_priority): A scheduling parameter.\n\n\
5683Current has only one field: sched_priority");
5684
5685static PyStructSequence_Field sched_param_fields[] = {
5686 {"sched_priority", "the scheduling priority"},
5687 {0}
5688};
5689
5690static PyStructSequence_Desc sched_param_desc = {
5691 "sched_param", /* name */
5692 sched_param__doc__, /* doc */
5693 sched_param_fields,
5694 1
5695};
5696
5697static int
5698convert_sched_param(PyObject *param, struct sched_param *res)
5699{
5700 long priority;
5701
5702 if (Py_TYPE(param) != &SchedParamType) {
5703 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5704 return 0;
5705 }
5706 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5707 if (priority == -1 && PyErr_Occurred())
5708 return 0;
5709 if (priority > INT_MAX || priority < INT_MIN) {
5710 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5711 return 0;
5712 }
5713 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5714 return 1;
5715}
5716
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005717#endif
5718
5719#ifdef HAVE_SCHED_SETSCHEDULER
5720
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005721PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5722"sched_setscheduler(pid, policy, param)\n\n\
5723Set the scheduling policy, *policy*, for *pid*.\n\
5724If *pid* is 0, the calling process is changed.\n\
5725*param* is an instance of sched_param.");
5726
5727static PyObject *
5728posix_sched_setscheduler(PyObject *self, PyObject *args)
5729{
5730 pid_t pid;
5731 int policy;
5732 struct sched_param param;
5733
5734 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5735 &pid, &policy, &convert_sched_param, &param))
5736 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005737
5738 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005739 ** sched_setscheduler() returns 0 in Linux, but the previous
5740 ** scheduling policy under Solaris/Illumos, and others.
5741 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005742 */
5743 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005744 return posix_error();
5745 Py_RETURN_NONE;
5746}
5747
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005748#endif
5749
5750#ifdef HAVE_SCHED_SETPARAM
5751
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005752PyDoc_STRVAR(posix_sched_getparam__doc__,
5753"sched_getparam(pid) -> sched_param\n\n\
5754Returns scheduling parameters for the process with *pid* as an instance of the\n\
5755sched_param class. A PID of 0 means the calling process.");
5756
5757static PyObject *
5758posix_sched_getparam(PyObject *self, PyObject *args)
5759{
5760 pid_t pid;
5761 struct sched_param param;
5762 PyObject *res, *priority;
5763
5764 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5765 return NULL;
5766 if (sched_getparam(pid, &param))
5767 return posix_error();
5768 res = PyStructSequence_New(&SchedParamType);
5769 if (!res)
5770 return NULL;
5771 priority = PyLong_FromLong(param.sched_priority);
5772 if (!priority) {
5773 Py_DECREF(res);
5774 return NULL;
5775 }
5776 PyStructSequence_SET_ITEM(res, 0, priority);
5777 return res;
5778}
5779
5780PyDoc_STRVAR(posix_sched_setparam__doc__,
5781"sched_setparam(pid, param)\n\n\
5782Set scheduling parameters for a process with PID *pid*.\n\
5783A PID of 0 means the calling process.");
5784
5785static PyObject *
5786posix_sched_setparam(PyObject *self, PyObject *args)
5787{
5788 pid_t pid;
5789 struct sched_param param;
5790
5791 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5792 &pid, &convert_sched_param, &param))
5793 return NULL;
5794 if (sched_setparam(pid, &param))
5795 return posix_error();
5796 Py_RETURN_NONE;
5797}
5798
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005799#endif
5800
5801#ifdef HAVE_SCHED_RR_GET_INTERVAL
5802
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005803PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5804"sched_rr_get_interval(pid) -> float\n\n\
5805Return the round-robin quantum for the process with PID *pid* in seconds.");
5806
5807static PyObject *
5808posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5809{
5810 pid_t pid;
5811 struct timespec interval;
5812
5813 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5814 return NULL;
5815 if (sched_rr_get_interval(pid, &interval))
5816 return posix_error();
5817 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5818}
5819
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005820#endif
5821
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005822PyDoc_STRVAR(posix_sched_yield__doc__,
5823"sched_yield()\n\n\
5824Voluntarily relinquish the CPU.");
5825
5826static PyObject *
5827posix_sched_yield(PyObject *self, PyObject *noargs)
5828{
5829 if (sched_yield())
5830 return posix_error();
5831 Py_RETURN_NONE;
5832}
5833
Benjamin Peterson2740af82011-08-02 17:41:34 -05005834#ifdef HAVE_SCHED_SETAFFINITY
5835
Antoine Pitrou84869872012-08-04 16:16:35 +02005836/* The minimum number of CPUs allocated in a cpu_set_t */
5837static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005838
5839PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5840"sched_setaffinity(pid, cpu_set)\n\n\
5841Set the affinity of the process with PID *pid* to *cpu_set*.");
5842
5843static PyObject *
5844posix_sched_setaffinity(PyObject *self, PyObject *args)
5845{
5846 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005847 int ncpus;
5848 size_t setsize;
5849 cpu_set_t *mask = NULL;
5850 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005851
Antoine Pitrou84869872012-08-04 16:16:35 +02005852 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5853 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005854 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005855
5856 iterator = PyObject_GetIter(iterable);
5857 if (iterator == NULL)
5858 return NULL;
5859
5860 ncpus = NCPUS_START;
5861 setsize = CPU_ALLOC_SIZE(ncpus);
5862 mask = CPU_ALLOC(ncpus);
5863 if (mask == NULL) {
5864 PyErr_NoMemory();
5865 goto error;
5866 }
5867 CPU_ZERO_S(setsize, mask);
5868
5869 while ((item = PyIter_Next(iterator))) {
5870 long cpu;
5871 if (!PyLong_Check(item)) {
5872 PyErr_Format(PyExc_TypeError,
5873 "expected an iterator of ints, "
5874 "but iterator yielded %R",
5875 Py_TYPE(item));
5876 Py_DECREF(item);
5877 goto error;
5878 }
5879 cpu = PyLong_AsLong(item);
5880 Py_DECREF(item);
5881 if (cpu < 0) {
5882 if (!PyErr_Occurred())
5883 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5884 goto error;
5885 }
5886 if (cpu > INT_MAX - 1) {
5887 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5888 goto error;
5889 }
5890 if (cpu >= ncpus) {
5891 /* Grow CPU mask to fit the CPU number */
5892 int newncpus = ncpus;
5893 cpu_set_t *newmask;
5894 size_t newsetsize;
5895 while (newncpus <= cpu) {
5896 if (newncpus > INT_MAX / 2)
5897 newncpus = cpu + 1;
5898 else
5899 newncpus = newncpus * 2;
5900 }
5901 newmask = CPU_ALLOC(newncpus);
5902 if (newmask == NULL) {
5903 PyErr_NoMemory();
5904 goto error;
5905 }
5906 newsetsize = CPU_ALLOC_SIZE(newncpus);
5907 CPU_ZERO_S(newsetsize, newmask);
5908 memcpy(newmask, mask, setsize);
5909 CPU_FREE(mask);
5910 setsize = newsetsize;
5911 mask = newmask;
5912 ncpus = newncpus;
5913 }
5914 CPU_SET_S(cpu, setsize, mask);
5915 }
5916 Py_CLEAR(iterator);
5917
5918 if (sched_setaffinity(pid, setsize, mask)) {
5919 posix_error();
5920 goto error;
5921 }
5922 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005923 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005924
5925error:
5926 if (mask)
5927 CPU_FREE(mask);
5928 Py_XDECREF(iterator);
5929 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005930}
5931
5932PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5933"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5934Return the affinity of the process with PID *pid*.\n\
5935The returned cpu_set will be of size *ncpus*.");
5936
5937static PyObject *
5938posix_sched_getaffinity(PyObject *self, PyObject *args)
5939{
5940 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005941 int cpu, ncpus, count;
5942 size_t setsize;
5943 cpu_set_t *mask = NULL;
5944 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005945
Antoine Pitrou84869872012-08-04 16:16:35 +02005946 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5947 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005948 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005949
5950 ncpus = NCPUS_START;
5951 while (1) {
5952 setsize = CPU_ALLOC_SIZE(ncpus);
5953 mask = CPU_ALLOC(ncpus);
5954 if (mask == NULL)
5955 return PyErr_NoMemory();
5956 if (sched_getaffinity(pid, setsize, mask) == 0)
5957 break;
5958 CPU_FREE(mask);
5959 if (errno != EINVAL)
5960 return posix_error();
5961 if (ncpus > INT_MAX / 2) {
5962 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5963 "a large enough CPU set");
5964 return NULL;
5965 }
5966 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005967 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005968
5969 res = PySet_New(NULL);
5970 if (res == NULL)
5971 goto error;
5972 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5973 if (CPU_ISSET_S(cpu, setsize, mask)) {
5974 PyObject *cpu_num = PyLong_FromLong(cpu);
5975 --count;
5976 if (cpu_num == NULL)
5977 goto error;
5978 if (PySet_Add(res, cpu_num)) {
5979 Py_DECREF(cpu_num);
5980 goto error;
5981 }
5982 Py_DECREF(cpu_num);
5983 }
5984 }
5985 CPU_FREE(mask);
5986 return res;
5987
5988error:
5989 if (mask)
5990 CPU_FREE(mask);
5991 Py_XDECREF(res);
5992 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005993}
5994
Benjamin Peterson2740af82011-08-02 17:41:34 -05005995#endif /* HAVE_SCHED_SETAFFINITY */
5996
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005997#endif /* HAVE_SCHED_H */
5998
Neal Norwitzb59798b2003-03-21 01:43:31 +00005999/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006000/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6001#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006002#define DEV_PTY_FILE "/dev/ptc"
6003#define HAVE_DEV_PTMX
6004#else
6005#define DEV_PTY_FILE "/dev/ptmx"
6006#endif
6007
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006008#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006009#ifdef HAVE_PTY_H
6010#include <pty.h>
6011#else
6012#ifdef HAVE_LIBUTIL_H
6013#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006014#else
6015#ifdef HAVE_UTIL_H
6016#include <util.h>
6017#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006018#endif /* HAVE_LIBUTIL_H */
6019#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006020#ifdef HAVE_STROPTS_H
6021#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006022#endif
6023#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006024
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006025#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006026PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006027"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006028Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006029
6030static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006031posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006032{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006033 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006034#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006035 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006036#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006037#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006038 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006039#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006040 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006041#endif
6042#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006043
Thomas Wouters70c21a12000-07-14 14:28:33 +00006044#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006045 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006046 goto posix_error;
6047
6048 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6049 goto error;
6050 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6051 goto error;
6052
Neal Norwitzb59798b2003-03-21 01:43:31 +00006053#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006054 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6055 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006056 goto posix_error;
6057 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6058 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006059
Victor Stinnerdaf45552013-08-28 00:53:59 +02006060 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006061 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006062 goto posix_error;
6063
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006064#else
Victor Stinner000de532013-11-25 23:19:58 +01006065 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006066 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006067 goto posix_error;
6068
Victor Stinner8c62be82010-05-06 00:08:46 +00006069 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006070
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 /* change permission of slave */
6072 if (grantpt(master_fd) < 0) {
6073 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006074 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006075 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006076
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 /* unlock slave */
6078 if (unlockpt(master_fd) < 0) {
6079 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006080 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006081 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006082
Victor Stinner8c62be82010-05-06 00:08:46 +00006083 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006084
Victor Stinner8c62be82010-05-06 00:08:46 +00006085 slave_name = ptsname(master_fd); /* get name of slave */
6086 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006087 goto posix_error;
6088
6089 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00006090 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006091 goto posix_error;
Victor Stinner000de532013-11-25 23:19:58 +01006092
6093 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6094 goto posix_error;
6095
Neal Norwitzb59798b2003-03-21 01:43:31 +00006096#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006097 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6098 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006099#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006100 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006101#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006102#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006103#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006104
Victor Stinner8c62be82010-05-06 00:08:46 +00006105 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006106
Victor Stinnerdaf45552013-08-28 00:53:59 +02006107posix_error:
6108 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006109#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006110error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006111#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02006112 if (master_fd != -1)
6113 close(master_fd);
6114 if (slave_fd != -1)
6115 close(slave_fd);
6116 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006117}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006118#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006119
6120#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006121PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006122"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006123Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6124Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006125To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006126
6127static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006128posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006129{
Victor Stinner8c62be82010-05-06 00:08:46 +00006130 int master_fd = -1, result = 0;
6131 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006132
Victor Stinner8c62be82010-05-06 00:08:46 +00006133 _PyImport_AcquireLock();
6134 pid = forkpty(&master_fd, NULL, NULL, NULL);
6135 if (pid == 0) {
6136 /* child: this clobbers and resets the import lock. */
6137 PyOS_AfterFork();
6138 } else {
6139 /* parent: release the import lock. */
6140 result = _PyImport_ReleaseLock();
6141 }
6142 if (pid == -1)
6143 return posix_error();
6144 if (result < 0) {
6145 /* Don't clobber the OSError if the fork failed. */
6146 PyErr_SetString(PyExc_RuntimeError,
6147 "not holding the import lock");
6148 return NULL;
6149 }
6150 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006151}
6152#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006153
Ross Lagerwall7807c352011-03-17 20:20:30 +02006154
Guido van Rossumad0ee831995-03-01 10:34:45 +00006155#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006156PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006157"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006158Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006159
Barry Warsaw53699e91996-12-10 23:23:01 +00006160static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006161posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006162{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006163 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006164}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006165#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006166
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006167
Guido van Rossumad0ee831995-03-01 10:34:45 +00006168#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006169PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006170"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006171Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006172
Barry Warsaw53699e91996-12-10 23:23:01 +00006173static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006174posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006175{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006176 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006177}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006178#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006179
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006180
Guido van Rossumad0ee831995-03-01 10:34:45 +00006181#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006182PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006183"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006184Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006185
Barry Warsaw53699e91996-12-10 23:23:01 +00006186static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006187posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006188{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006189 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006190}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006191#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006192
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006193
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006194PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006195"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006196Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006197
Barry Warsaw53699e91996-12-10 23:23:01 +00006198static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006199posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006200{
Victor Stinner8c62be82010-05-06 00:08:46 +00006201 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006202}
6203
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006204#ifdef HAVE_GETGROUPLIST
6205PyDoc_STRVAR(posix_getgrouplist__doc__,
6206"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6207Returns a list of groups to which a user belongs.\n\n\
6208 user: username to lookup\n\
6209 group: base group id of the user");
6210
6211static PyObject *
6212posix_getgrouplist(PyObject *self, PyObject *args)
6213{
6214#ifdef NGROUPS_MAX
6215#define MAX_GROUPS NGROUPS_MAX
6216#else
6217 /* defined to be 16 on Solaris7, so this should be a small number */
6218#define MAX_GROUPS 64
6219#endif
6220
6221 const char *user;
6222 int i, ngroups;
6223 PyObject *list;
6224#ifdef __APPLE__
6225 int *groups, basegid;
6226#else
6227 gid_t *groups, basegid;
6228#endif
6229 ngroups = MAX_GROUPS;
6230
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006231#ifdef __APPLE__
6232 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006233 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006234#else
6235 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6236 _Py_Gid_Converter, &basegid))
6237 return NULL;
6238#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006239
6240#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006241 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006242#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006243 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006244#endif
6245 if (groups == NULL)
6246 return PyErr_NoMemory();
6247
6248 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6249 PyMem_Del(groups);
6250 return posix_error();
6251 }
6252
6253 list = PyList_New(ngroups);
6254 if (list == NULL) {
6255 PyMem_Del(groups);
6256 return NULL;
6257 }
6258
6259 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006260#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006261 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006262#else
6263 PyObject *o = _PyLong_FromGid(groups[i]);
6264#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006265 if (o == NULL) {
6266 Py_DECREF(list);
6267 PyMem_Del(groups);
6268 return NULL;
6269 }
6270 PyList_SET_ITEM(list, i, o);
6271 }
6272
6273 PyMem_Del(groups);
6274
6275 return list;
6276}
6277#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006278
Fred Drakec9680921999-12-13 16:37:25 +00006279#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006280PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006281"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006282Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006283
6284static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006285posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006286{
6287 PyObject *result = NULL;
6288
Fred Drakec9680921999-12-13 16:37:25 +00006289#ifdef NGROUPS_MAX
6290#define MAX_GROUPS NGROUPS_MAX
6291#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006292 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006293#define MAX_GROUPS 64
6294#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006295 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006296
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006297 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006298 * This is a helper variable to store the intermediate result when
6299 * that happens.
6300 *
6301 * To keep the code readable the OSX behaviour is unconditional,
6302 * according to the POSIX spec this should be safe on all unix-y
6303 * systems.
6304 */
6305 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006306 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006307
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006308#ifdef __APPLE__
6309 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6310 * there are more groups than can fit in grouplist. Therefore, on OS X
6311 * always first call getgroups with length 0 to get the actual number
6312 * of groups.
6313 */
6314 n = getgroups(0, NULL);
6315 if (n < 0) {
6316 return posix_error();
6317 } else if (n <= MAX_GROUPS) {
6318 /* groups will fit in existing array */
6319 alt_grouplist = grouplist;
6320 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006321 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006322 if (alt_grouplist == NULL) {
6323 errno = EINVAL;
6324 return posix_error();
6325 }
6326 }
6327
6328 n = getgroups(n, alt_grouplist);
6329 if (n == -1) {
6330 if (alt_grouplist != grouplist) {
6331 PyMem_Free(alt_grouplist);
6332 }
6333 return posix_error();
6334 }
6335#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006336 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006337 if (n < 0) {
6338 if (errno == EINVAL) {
6339 n = getgroups(0, NULL);
6340 if (n == -1) {
6341 return posix_error();
6342 }
6343 if (n == 0) {
6344 /* Avoid malloc(0) */
6345 alt_grouplist = grouplist;
6346 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006347 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006348 if (alt_grouplist == NULL) {
6349 errno = EINVAL;
6350 return posix_error();
6351 }
6352 n = getgroups(n, alt_grouplist);
6353 if (n == -1) {
6354 PyMem_Free(alt_grouplist);
6355 return posix_error();
6356 }
6357 }
6358 } else {
6359 return posix_error();
6360 }
6361 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006362#endif
6363
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006364 result = PyList_New(n);
6365 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006366 int i;
6367 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006368 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006369 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006370 Py_DECREF(result);
6371 result = NULL;
6372 break;
Fred Drakec9680921999-12-13 16:37:25 +00006373 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006374 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006375 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006376 }
6377
6378 if (alt_grouplist != grouplist) {
6379 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006380 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006381
Fred Drakec9680921999-12-13 16:37:25 +00006382 return result;
6383}
6384#endif
6385
Antoine Pitroub7572f02009-12-02 20:46:48 +00006386#ifdef HAVE_INITGROUPS
6387PyDoc_STRVAR(posix_initgroups__doc__,
6388"initgroups(username, gid) -> None\n\n\
6389Call the system initgroups() to initialize the group access list with all of\n\
6390the groups of which the specified username is a member, plus the specified\n\
6391group id.");
6392
6393static PyObject *
6394posix_initgroups(PyObject *self, PyObject *args)
6395{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006396 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006398 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006399#ifdef __APPLE__
6400 int gid;
6401#else
6402 gid_t gid;
6403#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006404
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006405#ifdef __APPLE__
6406 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6407 PyUnicode_FSConverter, &oname,
6408 &gid))
6409#else
6410 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6411 PyUnicode_FSConverter, &oname,
6412 _Py_Gid_Converter, &gid))
6413#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006414 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006415 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006416
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006417 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006418 Py_DECREF(oname);
6419 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006420 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006421
Victor Stinner8c62be82010-05-06 00:08:46 +00006422 Py_INCREF(Py_None);
6423 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006424}
6425#endif
6426
Martin v. Löwis606edc12002-06-13 21:09:11 +00006427#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006428PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006429"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006430Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006431
6432static PyObject *
6433posix_getpgid(PyObject *self, PyObject *args)
6434{
Victor Stinner8c62be82010-05-06 00:08:46 +00006435 pid_t pid, pgid;
6436 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6437 return NULL;
6438 pgid = getpgid(pid);
6439 if (pgid < 0)
6440 return posix_error();
6441 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006442}
6443#endif /* HAVE_GETPGID */
6444
6445
Guido van Rossumb6775db1994-08-01 11:34:53 +00006446#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006447PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006448"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006449Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006450
Barry Warsaw53699e91996-12-10 23:23:01 +00006451static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006452posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006453{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006454#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006455 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006456#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006457 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006458#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006459}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006460#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006461
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006462
Guido van Rossumb6775db1994-08-01 11:34:53 +00006463#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006464PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006465"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006466Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006467
Barry Warsaw53699e91996-12-10 23:23:01 +00006468static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006469posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006470{
Guido van Rossum64933891994-10-20 21:56:42 +00006471#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006472 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006473#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006474 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006475#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006476 return posix_error();
6477 Py_INCREF(Py_None);
6478 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006479}
6480
Guido van Rossumb6775db1994-08-01 11:34:53 +00006481#endif /* HAVE_SETPGRP */
6482
Guido van Rossumad0ee831995-03-01 10:34:45 +00006483#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006484
6485#ifdef MS_WINDOWS
6486#include <tlhelp32.h>
6487
6488static PyObject*
6489win32_getppid()
6490{
6491 HANDLE snapshot;
6492 pid_t mypid;
6493 PyObject* result = NULL;
6494 BOOL have_record;
6495 PROCESSENTRY32 pe;
6496
6497 mypid = getpid(); /* This function never fails */
6498
6499 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6500 if (snapshot == INVALID_HANDLE_VALUE)
6501 return PyErr_SetFromWindowsErr(GetLastError());
6502
6503 pe.dwSize = sizeof(pe);
6504 have_record = Process32First(snapshot, &pe);
6505 while (have_record) {
6506 if (mypid == (pid_t)pe.th32ProcessID) {
6507 /* We could cache the ulong value in a static variable. */
6508 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6509 break;
6510 }
6511
6512 have_record = Process32Next(snapshot, &pe);
6513 }
6514
6515 /* If our loop exits and our pid was not found (result will be NULL)
6516 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6517 * error anyway, so let's raise it. */
6518 if (!result)
6519 result = PyErr_SetFromWindowsErr(GetLastError());
6520
6521 CloseHandle(snapshot);
6522
6523 return result;
6524}
6525#endif /*MS_WINDOWS*/
6526
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006527PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006528"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006529Return the parent's process id. If the parent process has already exited,\n\
6530Windows machines will still return its id; others systems will return the id\n\
6531of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006532
Barry Warsaw53699e91996-12-10 23:23:01 +00006533static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006534posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006535{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006536#ifdef MS_WINDOWS
6537 return win32_getppid();
6538#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006540#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006541}
6542#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006543
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006544
Fred Drake12c6e2d1999-12-14 21:25:03 +00006545#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006546PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006547"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006548Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006549
6550static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006551posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006552{
Victor Stinner8c62be82010-05-06 00:08:46 +00006553 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006554#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006555 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006556 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006557
6558 if (GetUserNameW(user_name, &num_chars)) {
6559 /* num_chars is the number of unicode chars plus null terminator */
6560 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006561 }
6562 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006563 result = PyErr_SetFromWindowsErr(GetLastError());
6564#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 char *name;
6566 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006567
Victor Stinner8c62be82010-05-06 00:08:46 +00006568 errno = 0;
6569 name = getlogin();
6570 if (name == NULL) {
6571 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006572 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006573 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006574 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 }
6576 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006577 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006579#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006580 return result;
6581}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006582#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006583
Guido van Rossumad0ee831995-03-01 10:34:45 +00006584#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006585PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006586"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006587Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006588
Barry Warsaw53699e91996-12-10 23:23:01 +00006589static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006590posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006591{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006592 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006593}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006594#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006595
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006596
Guido van Rossumad0ee831995-03-01 10:34:45 +00006597#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006598PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006599"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006600Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006601
Barry Warsaw53699e91996-12-10 23:23:01 +00006602static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006603posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006604{
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 pid_t pid;
6606 int sig;
6607 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6608 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006609 if (kill(pid, sig) == -1)
6610 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006611 Py_INCREF(Py_None);
6612 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006613}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006614#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006615
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006616#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006617PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006618"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006619Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006620
6621static PyObject *
6622posix_killpg(PyObject *self, PyObject *args)
6623{
Victor Stinner8c62be82010-05-06 00:08:46 +00006624 int sig;
6625 pid_t pgid;
6626 /* XXX some man pages make the `pgid` parameter an int, others
6627 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6628 take the same type. Moreover, pid_t is always at least as wide as
6629 int (else compilation of this module fails), which is safe. */
6630 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6631 return NULL;
6632 if (killpg(pgid, sig) == -1)
6633 return posix_error();
6634 Py_INCREF(Py_None);
6635 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006636}
6637#endif
6638
Brian Curtineb24d742010-04-12 17:16:38 +00006639#ifdef MS_WINDOWS
6640PyDoc_STRVAR(win32_kill__doc__,
6641"kill(pid, sig)\n\n\
6642Kill a process with a signal.");
6643
6644static PyObject *
6645win32_kill(PyObject *self, PyObject *args)
6646{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006647 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006648 pid_t pid;
6649 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006650 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006651
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006652 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006653 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006654
Victor Stinner8c62be82010-05-06 00:08:46 +00006655 /* Console processes which share a common console can be sent CTRL+C or
6656 CTRL+BREAK events, provided they handle said events. */
6657 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006658 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 err = GetLastError();
6660 PyErr_SetFromWindowsErr(err);
6661 }
6662 else
6663 Py_RETURN_NONE;
6664 }
Brian Curtineb24d742010-04-12 17:16:38 +00006665
Victor Stinner8c62be82010-05-06 00:08:46 +00006666 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6667 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006668 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006669 if (handle == NULL) {
6670 err = GetLastError();
6671 return PyErr_SetFromWindowsErr(err);
6672 }
Brian Curtineb24d742010-04-12 17:16:38 +00006673
Victor Stinner8c62be82010-05-06 00:08:46 +00006674 if (TerminateProcess(handle, sig) == 0) {
6675 err = GetLastError();
6676 result = PyErr_SetFromWindowsErr(err);
6677 } else {
6678 Py_INCREF(Py_None);
6679 result = Py_None;
6680 }
Brian Curtineb24d742010-04-12 17:16:38 +00006681
Victor Stinner8c62be82010-05-06 00:08:46 +00006682 CloseHandle(handle);
6683 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006684}
6685#endif /* MS_WINDOWS */
6686
Guido van Rossumc0125471996-06-28 18:55:32 +00006687#ifdef HAVE_PLOCK
6688
6689#ifdef HAVE_SYS_LOCK_H
6690#include <sys/lock.h>
6691#endif
6692
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006693PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006694"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006695Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006696
Barry Warsaw53699e91996-12-10 23:23:01 +00006697static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006698posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006699{
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 int op;
6701 if (!PyArg_ParseTuple(args, "i:plock", &op))
6702 return NULL;
6703 if (plock(op) == -1)
6704 return posix_error();
6705 Py_INCREF(Py_None);
6706 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006707}
6708#endif
6709
Guido van Rossumb6775db1994-08-01 11:34:53 +00006710#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006711PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006712"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006713Set the current process's user id.");
6714
Barry Warsaw53699e91996-12-10 23:23:01 +00006715static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006716posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006717{
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006719 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006720 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006721 if (setuid(uid) < 0)
6722 return posix_error();
6723 Py_INCREF(Py_None);
6724 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006725}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006726#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006727
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006728
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006729#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006730PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006731"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006732Set the current process's effective user id.");
6733
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006734static PyObject *
6735posix_seteuid (PyObject *self, PyObject *args)
6736{
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006738 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006739 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 if (seteuid(euid) < 0) {
6741 return posix_error();
6742 } else {
6743 Py_INCREF(Py_None);
6744 return Py_None;
6745 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006746}
6747#endif /* HAVE_SETEUID */
6748
6749#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006750PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006751"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006752Set the current process's effective group id.");
6753
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006754static PyObject *
6755posix_setegid (PyObject *self, PyObject *args)
6756{
Victor Stinner8c62be82010-05-06 00:08:46 +00006757 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006758 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006759 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 if (setegid(egid) < 0) {
6761 return posix_error();
6762 } else {
6763 Py_INCREF(Py_None);
6764 return Py_None;
6765 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006766}
6767#endif /* HAVE_SETEGID */
6768
6769#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006770PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006771"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006772Set the current process's real and effective user ids.");
6773
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006774static PyObject *
6775posix_setreuid (PyObject *self, PyObject *args)
6776{
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006778 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6779 _Py_Uid_Converter, &ruid,
6780 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 if (setreuid(ruid, euid) < 0) {
6783 return posix_error();
6784 } else {
6785 Py_INCREF(Py_None);
6786 return Py_None;
6787 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006788}
6789#endif /* HAVE_SETREUID */
6790
6791#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006792PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006793"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006794Set the current process's real and effective group ids.");
6795
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006796static PyObject *
6797posix_setregid (PyObject *self, PyObject *args)
6798{
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006800 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6801 _Py_Gid_Converter, &rgid,
6802 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 if (setregid(rgid, egid) < 0) {
6805 return posix_error();
6806 } else {
6807 Py_INCREF(Py_None);
6808 return Py_None;
6809 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006810}
6811#endif /* HAVE_SETREGID */
6812
Guido van Rossumb6775db1994-08-01 11:34:53 +00006813#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006814PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006815"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006816Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006817
Barry Warsaw53699e91996-12-10 23:23:01 +00006818static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006819posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006820{
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006822 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 if (setgid(gid) < 0)
6825 return posix_error();
6826 Py_INCREF(Py_None);
6827 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006828}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006829#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006830
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006831#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006832PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006833"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006834Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006835
6836static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006837posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006838{
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 int i, len;
6840 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006841
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 if (!PySequence_Check(groups)) {
6843 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6844 return NULL;
6845 }
6846 len = PySequence_Size(groups);
6847 if (len > MAX_GROUPS) {
6848 PyErr_SetString(PyExc_ValueError, "too many groups");
6849 return NULL;
6850 }
6851 for(i = 0; i < len; i++) {
6852 PyObject *elem;
6853 elem = PySequence_GetItem(groups, i);
6854 if (!elem)
6855 return NULL;
6856 if (!PyLong_Check(elem)) {
6857 PyErr_SetString(PyExc_TypeError,
6858 "groups must be integers");
6859 Py_DECREF(elem);
6860 return NULL;
6861 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006862 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 Py_DECREF(elem);
6864 return NULL;
6865 }
6866 }
6867 Py_DECREF(elem);
6868 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006869
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 if (setgroups(len, grouplist) < 0)
6871 return posix_error();
6872 Py_INCREF(Py_None);
6873 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006874}
6875#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006876
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006877#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6878static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006879wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006880{
Victor Stinner8c62be82010-05-06 00:08:46 +00006881 PyObject *result;
6882 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006883 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006884
Victor Stinner8c62be82010-05-06 00:08:46 +00006885 if (pid == -1)
6886 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006887
Victor Stinner8c62be82010-05-06 00:08:46 +00006888 if (struct_rusage == NULL) {
6889 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6890 if (m == NULL)
6891 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006892 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 Py_DECREF(m);
6894 if (struct_rusage == NULL)
6895 return NULL;
6896 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006897
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6899 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6900 if (!result)
6901 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006902
6903#ifndef doubletime
6904#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6905#endif
6906
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006908 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006909 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006910 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006911#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006912 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6913 SET_INT(result, 2, ru->ru_maxrss);
6914 SET_INT(result, 3, ru->ru_ixrss);
6915 SET_INT(result, 4, ru->ru_idrss);
6916 SET_INT(result, 5, ru->ru_isrss);
6917 SET_INT(result, 6, ru->ru_minflt);
6918 SET_INT(result, 7, ru->ru_majflt);
6919 SET_INT(result, 8, ru->ru_nswap);
6920 SET_INT(result, 9, ru->ru_inblock);
6921 SET_INT(result, 10, ru->ru_oublock);
6922 SET_INT(result, 11, ru->ru_msgsnd);
6923 SET_INT(result, 12, ru->ru_msgrcv);
6924 SET_INT(result, 13, ru->ru_nsignals);
6925 SET_INT(result, 14, ru->ru_nvcsw);
6926 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006927#undef SET_INT
6928
Victor Stinner8c62be82010-05-06 00:08:46 +00006929 if (PyErr_Occurred()) {
6930 Py_DECREF(result);
6931 return NULL;
6932 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006933
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006935}
6936#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6937
6938#ifdef HAVE_WAIT3
6939PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006940"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006941Wait for completion of a child process.");
6942
6943static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006944posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006945{
Victor Stinner8c62be82010-05-06 00:08:46 +00006946 pid_t pid;
6947 int options;
6948 struct rusage ru;
6949 WAIT_TYPE status;
6950 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006951
Victor Stinner4195b5c2012-02-08 23:03:19 +01006952 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006954
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 Py_BEGIN_ALLOW_THREADS
6956 pid = wait3(&status, options, &ru);
6957 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006958
Victor Stinner4195b5c2012-02-08 23:03:19 +01006959 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006960}
6961#endif /* HAVE_WAIT3 */
6962
6963#ifdef HAVE_WAIT4
6964PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006965"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006966Wait for completion of a given child process.");
6967
6968static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006969posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006970{
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 pid_t pid;
6972 int options;
6973 struct rusage ru;
6974 WAIT_TYPE status;
6975 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006976
Victor Stinner4195b5c2012-02-08 23:03:19 +01006977 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006978 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006979
Victor Stinner8c62be82010-05-06 00:08:46 +00006980 Py_BEGIN_ALLOW_THREADS
6981 pid = wait4(pid, &status, options, &ru);
6982 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006983
Victor Stinner4195b5c2012-02-08 23:03:19 +01006984 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006985}
6986#endif /* HAVE_WAIT4 */
6987
Ross Lagerwall7807c352011-03-17 20:20:30 +02006988#if defined(HAVE_WAITID) && !defined(__APPLE__)
6989PyDoc_STRVAR(posix_waitid__doc__,
6990"waitid(idtype, id, options) -> waitid_result\n\n\
6991Wait for the completion of one or more child processes.\n\n\
6992idtype can be P_PID, P_PGID or P_ALL.\n\
6993id specifies the pid to wait on.\n\
6994options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6995or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6996Returns either waitid_result or None if WNOHANG is specified and there are\n\
6997no children in a waitable state.");
6998
6999static PyObject *
7000posix_waitid(PyObject *self, PyObject *args)
7001{
7002 PyObject *result;
7003 idtype_t idtype;
7004 id_t id;
7005 int options, res;
7006 siginfo_t si;
7007 si.si_pid = 0;
7008 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
7009 return NULL;
7010 Py_BEGIN_ALLOW_THREADS
7011 res = waitid(idtype, id, &si, options);
7012 Py_END_ALLOW_THREADS
7013 if (res == -1)
7014 return posix_error();
7015
7016 if (si.si_pid == 0)
7017 Py_RETURN_NONE;
7018
7019 result = PyStructSequence_New(&WaitidResultType);
7020 if (!result)
7021 return NULL;
7022
7023 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007024 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007025 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7026 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7027 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7028 if (PyErr_Occurred()) {
7029 Py_DECREF(result);
7030 return NULL;
7031 }
7032
7033 return result;
7034}
7035#endif
7036
Guido van Rossumb6775db1994-08-01 11:34:53 +00007037#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007038PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007039"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007040Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007041
Barry Warsaw53699e91996-12-10 23:23:01 +00007042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007043posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007044{
Victor Stinner8c62be82010-05-06 00:08:46 +00007045 pid_t pid;
7046 int options;
7047 WAIT_TYPE status;
7048 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007049
Victor Stinner8c62be82010-05-06 00:08:46 +00007050 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7051 return NULL;
7052 Py_BEGIN_ALLOW_THREADS
7053 pid = waitpid(pid, &status, options);
7054 Py_END_ALLOW_THREADS
7055 if (pid == -1)
7056 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007057
Victor Stinner8c62be82010-05-06 00:08:46 +00007058 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007059}
7060
Tim Petersab034fa2002-02-01 11:27:43 +00007061#elif defined(HAVE_CWAIT)
7062
7063/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007064PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007065"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007066"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007067
7068static PyObject *
7069posix_waitpid(PyObject *self, PyObject *args)
7070{
Victor Stinner8c62be82010-05-06 00:08:46 +00007071 Py_intptr_t pid;
7072 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007073
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007074 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 return NULL;
7076 Py_BEGIN_ALLOW_THREADS
7077 pid = _cwait(&status, pid, options);
7078 Py_END_ALLOW_THREADS
7079 if (pid == -1)
7080 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007081
Victor Stinner8c62be82010-05-06 00:08:46 +00007082 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007083 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007084}
7085#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007086
Guido van Rossumad0ee831995-03-01 10:34:45 +00007087#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007088PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007089"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007090Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007091
Barry Warsaw53699e91996-12-10 23:23:01 +00007092static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007093posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007094{
Victor Stinner8c62be82010-05-06 00:08:46 +00007095 pid_t pid;
7096 WAIT_TYPE status;
7097 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007098
Victor Stinner8c62be82010-05-06 00:08:46 +00007099 Py_BEGIN_ALLOW_THREADS
7100 pid = wait(&status);
7101 Py_END_ALLOW_THREADS
7102 if (pid == -1)
7103 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007104
Victor Stinner8c62be82010-05-06 00:08:46 +00007105 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007106}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007107#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007108
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007109
Larry Hastings9cf065c2012-06-22 16:30:09 -07007110#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7111PyDoc_STRVAR(readlink__doc__,
7112"readlink(path, *, dir_fd=None) -> path\n\n\
7113Return a string representing the path to which the symbolic link points.\n\
7114\n\
7115If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7116 and path should be relative; path will then be relative to that directory.\n\
7117dir_fd may not be implemented on your platform.\n\
7118 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007119#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007120
Guido van Rossumb6775db1994-08-01 11:34:53 +00007121#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007122
Barry Warsaw53699e91996-12-10 23:23:01 +00007123static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007124posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007125{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126 path_t path;
7127 int dir_fd = DEFAULT_DIR_FD;
7128 char buffer[MAXPATHLEN];
7129 ssize_t length;
7130 PyObject *return_value = NULL;
7131 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007132
Larry Hastings9cf065c2012-06-22 16:30:09 -07007133 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007134 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007135 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7136 path_converter, &path,
7137#ifdef HAVE_READLINKAT
7138 dir_fd_converter, &dir_fd
7139#else
7140 dir_fd_unavailable, &dir_fd
7141#endif
7142 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007143 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007144
Victor Stinner8c62be82010-05-06 00:08:46 +00007145 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007146#ifdef HAVE_READLINKAT
7147 if (dir_fd != DEFAULT_DIR_FD)
7148 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007149 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007150#endif
7151 length = readlink(path.narrow, buffer, sizeof(buffer));
7152 Py_END_ALLOW_THREADS
7153
7154 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007155 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007156 goto exit;
7157 }
7158
7159 if (PyUnicode_Check(path.object))
7160 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7161 else
7162 return_value = PyBytes_FromStringAndSize(buffer, length);
7163exit:
7164 path_cleanup(&path);
7165 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007166}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007167
7168
Guido van Rossumb6775db1994-08-01 11:34:53 +00007169#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007170
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007171
Larry Hastings9cf065c2012-06-22 16:30:09 -07007172#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007173PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007174"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7175Create a symbolic link pointing to src named dst.\n\n\
7176target_is_directory is required on Windows if the target is to be\n\
7177 interpreted as a directory. (On Windows, symlink requires\n\
7178 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7179 target_is_directory is ignored on non-Windows platforms.\n\
7180\n\
7181If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7182 and path should be relative; path will then be relative to that directory.\n\
7183dir_fd may not be implemented on your platform.\n\
7184 If it is unavailable, using it will raise a NotImplementedError.");
7185
7186#if defined(MS_WINDOWS)
7187
7188/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7189static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7190static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007191
Larry Hastings9cf065c2012-06-22 16:30:09 -07007192static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007193check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007194{
7195 HINSTANCE hKernel32;
7196 /* only recheck */
7197 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7198 return 1;
7199 hKernel32 = GetModuleHandleW(L"KERNEL32");
7200 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7201 "CreateSymbolicLinkW");
7202 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7203 "CreateSymbolicLinkA");
7204 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7205}
7206
Victor Stinner31b3b922013-06-05 01:49:17 +02007207/* Remove the last portion of the path */
7208static void
7209_dirnameW(WCHAR *path)
7210{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007211 WCHAR *ptr;
7212
7213 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007214 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007215 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007216 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007217 }
7218 *ptr = 0;
7219}
7220
Victor Stinner31b3b922013-06-05 01:49:17 +02007221/* Remove the last portion of the path */
7222static void
7223_dirnameA(char *path)
7224{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007225 char *ptr;
7226
7227 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007228 for(ptr = path + strlen(path); ptr != path; ptr--) {
7229 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007230 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007231 }
7232 *ptr = 0;
7233}
7234
Victor Stinner31b3b922013-06-05 01:49:17 +02007235/* Is this path absolute? */
7236static int
7237_is_absW(const WCHAR *path)
7238{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007239 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7240
7241}
7242
Victor Stinner31b3b922013-06-05 01:49:17 +02007243/* Is this path absolute? */
7244static int
7245_is_absA(const char *path)
7246{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007247 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7248
7249}
7250
Victor Stinner31b3b922013-06-05 01:49:17 +02007251/* join root and rest with a backslash */
7252static void
7253_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7254{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007255 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007256
Victor Stinner31b3b922013-06-05 01:49:17 +02007257 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007258 wcscpy(dest_path, rest);
7259 return;
7260 }
7261
7262 root_len = wcslen(root);
7263
7264 wcscpy(dest_path, root);
7265 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007266 dest_path[root_len] = L'\\';
7267 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007268 }
7269 wcscpy(dest_path+root_len, rest);
7270}
7271
Victor Stinner31b3b922013-06-05 01:49:17 +02007272/* join root and rest with a backslash */
7273static void
7274_joinA(char *dest_path, const char *root, const char *rest)
7275{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007276 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007277
Victor Stinner31b3b922013-06-05 01:49:17 +02007278 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007279 strcpy(dest_path, rest);
7280 return;
7281 }
7282
7283 root_len = strlen(root);
7284
7285 strcpy(dest_path, root);
7286 if(root_len) {
7287 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007288 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007289 }
7290 strcpy(dest_path+root_len, rest);
7291}
7292
Victor Stinner31b3b922013-06-05 01:49:17 +02007293/* Return True if the path at src relative to dest is a directory */
7294static int
7295_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007296{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007297 WIN32_FILE_ATTRIBUTE_DATA src_info;
7298 WCHAR dest_parent[MAX_PATH];
7299 WCHAR src_resolved[MAX_PATH] = L"";
7300
7301 /* dest_parent = os.path.dirname(dest) */
7302 wcscpy(dest_parent, dest);
7303 _dirnameW(dest_parent);
7304 /* src_resolved = os.path.join(dest_parent, src) */
7305 _joinW(src_resolved, dest_parent, src);
7306 return (
7307 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7308 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7309 );
7310}
7311
Victor Stinner31b3b922013-06-05 01:49:17 +02007312/* Return True if the path at src relative to dest is a directory */
7313static int
7314_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007315{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007316 WIN32_FILE_ATTRIBUTE_DATA src_info;
7317 char dest_parent[MAX_PATH];
7318 char src_resolved[MAX_PATH] = "";
7319
7320 /* dest_parent = os.path.dirname(dest) */
7321 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007322 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007323 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007324 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007325 return (
7326 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7327 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7328 );
7329}
7330
Larry Hastings9cf065c2012-06-22 16:30:09 -07007331#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007332
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007333static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007334posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007335{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007336 path_t src;
7337 path_t dst;
7338 int dir_fd = DEFAULT_DIR_FD;
7339 int target_is_directory = 0;
7340 static char *keywords[] = {"src", "dst", "target_is_directory",
7341 "dir_fd", NULL};
7342 PyObject *return_value;
7343#ifdef MS_WINDOWS
7344 DWORD result;
7345#else
7346 int result;
7347#endif
7348
7349 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007350 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007351 src.argument_name = "src";
7352 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007353 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007354 dst.argument_name = "dst";
7355
7356#ifdef MS_WINDOWS
7357 if (!check_CreateSymbolicLink()) {
7358 PyErr_SetString(PyExc_NotImplementedError,
7359 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007360 return NULL;
7361 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007362 if (!win32_can_symlink) {
7363 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007364 return NULL;
7365 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007366#endif
7367
7368 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7369 keywords,
7370 path_converter, &src,
7371 path_converter, &dst,
7372 &target_is_directory,
7373#ifdef HAVE_SYMLINKAT
7374 dir_fd_converter, &dir_fd
7375#else
7376 dir_fd_unavailable, &dir_fd
7377#endif
7378 ))
7379 return NULL;
7380
7381 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7382 PyErr_SetString(PyExc_ValueError,
7383 "symlink: src and dst must be the same type");
7384 return_value = NULL;
7385 goto exit;
7386 }
7387
7388#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007389
Larry Hastings9cf065c2012-06-22 16:30:09 -07007390 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007391 if (dst.wide) {
7392 /* if src is a directory, ensure target_is_directory==1 */
7393 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007394 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7395 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007396 }
7397 else {
7398 /* if src is a directory, ensure target_is_directory==1 */
7399 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007400 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7401 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007402 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007403 Py_END_ALLOW_THREADS
7404
7405 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08007406 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007407 goto exit;
7408 }
7409
7410#else
7411
7412 Py_BEGIN_ALLOW_THREADS
7413#if HAVE_SYMLINKAT
7414 if (dir_fd != DEFAULT_DIR_FD)
7415 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7416 else
7417#endif
7418 result = symlink(src.narrow, dst.narrow);
7419 Py_END_ALLOW_THREADS
7420
7421 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08007422 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007423 goto exit;
7424 }
7425#endif
7426
7427 return_value = Py_None;
7428 Py_INCREF(Py_None);
7429 goto exit; /* silence "unused label" warning */
7430exit:
7431 path_cleanup(&src);
7432 path_cleanup(&dst);
7433 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007434}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007435
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007436#endif /* HAVE_SYMLINK */
7437
Larry Hastings9cf065c2012-06-22 16:30:09 -07007438
Brian Curtind40e6f72010-07-08 21:39:08 +00007439#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7440
Brian Curtind40e6f72010-07-08 21:39:08 +00007441static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007442win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007443{
7444 wchar_t *path;
7445 DWORD n_bytes_returned;
7446 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007447 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007448 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007449 HANDLE reparse_point_handle;
7450
7451 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7452 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7453 wchar_t *print_name;
7454
Larry Hastings9cf065c2012-06-22 16:30:09 -07007455 static char *keywords[] = {"path", "dir_fd", NULL};
7456
7457 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7458 &po,
7459 dir_fd_unavailable, &dir_fd
7460 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007461 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007462
Victor Stinnereb5657a2011-09-30 01:44:27 +02007463 path = PyUnicode_AsUnicode(po);
7464 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007465 return NULL;
7466
7467 /* First get a handle to the reparse point */
7468 Py_BEGIN_ALLOW_THREADS
7469 reparse_point_handle = CreateFileW(
7470 path,
7471 0,
7472 0,
7473 0,
7474 OPEN_EXISTING,
7475 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7476 0);
7477 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007478
Brian Curtind40e6f72010-07-08 21:39:08 +00007479 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007480 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007481
Brian Curtind40e6f72010-07-08 21:39:08 +00007482 Py_BEGIN_ALLOW_THREADS
7483 /* New call DeviceIoControl to read the reparse point */
7484 io_result = DeviceIoControl(
7485 reparse_point_handle,
7486 FSCTL_GET_REPARSE_POINT,
7487 0, 0, /* in buffer */
7488 target_buffer, sizeof(target_buffer),
7489 &n_bytes_returned,
7490 0 /* we're not using OVERLAPPED_IO */
7491 );
7492 CloseHandle(reparse_point_handle);
7493 Py_END_ALLOW_THREADS
7494
7495 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007496 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007497
7498 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7499 {
7500 PyErr_SetString(PyExc_ValueError,
7501 "not a symbolic link");
7502 return NULL;
7503 }
Brian Curtin74e45612010-07-09 15:58:59 +00007504 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7505 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7506
7507 result = PyUnicode_FromWideChar(print_name,
7508 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007509 return result;
7510}
7511
7512#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7513
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007514
Larry Hastings605a62d2012-06-24 04:33:36 -07007515static PyStructSequence_Field times_result_fields[] = {
7516 {"user", "user time"},
7517 {"system", "system time"},
7518 {"children_user", "user time of children"},
7519 {"children_system", "system time of children"},
7520 {"elapsed", "elapsed time since an arbitrary point in the past"},
7521 {NULL}
7522};
7523
7524PyDoc_STRVAR(times_result__doc__,
7525"times_result: Result from os.times().\n\n\
7526This object may be accessed either as a tuple of\n\
7527 (user, system, children_user, children_system, elapsed),\n\
7528or via the attributes user, system, children_user, children_system,\n\
7529and elapsed.\n\
7530\n\
7531See os.times for more information.");
7532
7533static PyStructSequence_Desc times_result_desc = {
7534 "times_result", /* name */
7535 times_result__doc__, /* doc */
7536 times_result_fields,
7537 5
7538};
7539
7540static PyTypeObject TimesResultType;
7541
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007542#ifdef MS_WINDOWS
7543#define HAVE_TIMES /* mandatory, for the method table */
7544#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007545
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007546#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007547
7548static PyObject *
7549build_times_result(double user, double system,
7550 double children_user, double children_system,
7551 double elapsed)
7552{
7553 PyObject *value = PyStructSequence_New(&TimesResultType);
7554 if (value == NULL)
7555 return NULL;
7556
7557#define SET(i, field) \
7558 { \
7559 PyObject *o = PyFloat_FromDouble(field); \
7560 if (!o) { \
7561 Py_DECREF(value); \
7562 return NULL; \
7563 } \
7564 PyStructSequence_SET_ITEM(value, i, o); \
7565 } \
7566
7567 SET(0, user);
7568 SET(1, system);
7569 SET(2, children_user);
7570 SET(3, children_system);
7571 SET(4, elapsed);
7572
7573#undef SET
7574
7575 return value;
7576}
7577
7578PyDoc_STRVAR(posix_times__doc__,
7579"times() -> times_result\n\n\
7580Return an object containing floating point numbers indicating process\n\
7581times. The object behaves like a named tuple with these fields:\n\
7582 (utime, stime, cutime, cstime, elapsed_time)");
7583
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007584#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007585static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007586posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007587{
Victor Stinner8c62be82010-05-06 00:08:46 +00007588 FILETIME create, exit, kernel, user;
7589 HANDLE hProc;
7590 hProc = GetCurrentProcess();
7591 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7592 /* The fields of a FILETIME structure are the hi and lo part
7593 of a 64-bit value expressed in 100 nanosecond units.
7594 1e7 is one second in such units; 1e-7 the inverse.
7595 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7596 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007597 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007598 (double)(user.dwHighDateTime*429.4967296 +
7599 user.dwLowDateTime*1e-7),
7600 (double)(kernel.dwHighDateTime*429.4967296 +
7601 kernel.dwLowDateTime*1e-7),
7602 (double)0,
7603 (double)0,
7604 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007605}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007606#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007607#define NEED_TICKS_PER_SECOND
7608static long ticks_per_second = -1;
7609static PyObject *
7610posix_times(PyObject *self, PyObject *noargs)
7611{
7612 struct tms t;
7613 clock_t c;
7614 errno = 0;
7615 c = times(&t);
7616 if (c == (clock_t) -1)
7617 return posix_error();
7618 return build_times_result(
7619 (double)t.tms_utime / ticks_per_second,
7620 (double)t.tms_stime / ticks_per_second,
7621 (double)t.tms_cutime / ticks_per_second,
7622 (double)t.tms_cstime / ticks_per_second,
7623 (double)c / ticks_per_second);
7624}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007625#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007626
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007627#endif /* HAVE_TIMES */
7628
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007629
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007630#ifdef HAVE_GETSID
7631PyDoc_STRVAR(posix_getsid__doc__,
7632"getsid(pid) -> sid\n\n\
7633Call the system call getsid().");
7634
7635static PyObject *
7636posix_getsid(PyObject *self, PyObject *args)
7637{
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 pid_t pid;
7639 int sid;
7640 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7641 return NULL;
7642 sid = getsid(pid);
7643 if (sid < 0)
7644 return posix_error();
7645 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007646}
7647#endif /* HAVE_GETSID */
7648
7649
Guido van Rossumb6775db1994-08-01 11:34:53 +00007650#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007651PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007652"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007653Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007654
Barry Warsaw53699e91996-12-10 23:23:01 +00007655static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007656posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007657{
Victor Stinner8c62be82010-05-06 00:08:46 +00007658 if (setsid() < 0)
7659 return posix_error();
7660 Py_INCREF(Py_None);
7661 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007662}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007663#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007664
Guido van Rossumb6775db1994-08-01 11:34:53 +00007665#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007666PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007667"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007668Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007669
Barry Warsaw53699e91996-12-10 23:23:01 +00007670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007671posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007672{
Victor Stinner8c62be82010-05-06 00:08:46 +00007673 pid_t pid;
7674 int pgrp;
7675 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7676 return NULL;
7677 if (setpgid(pid, pgrp) < 0)
7678 return posix_error();
7679 Py_INCREF(Py_None);
7680 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007681}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007682#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007683
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007684
Guido van Rossumb6775db1994-08-01 11:34:53 +00007685#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007686PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007687"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007688Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007689
Barry Warsaw53699e91996-12-10 23:23:01 +00007690static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007691posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007692{
Victor Stinner8c62be82010-05-06 00:08:46 +00007693 int fd;
7694 pid_t pgid;
7695 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7696 return NULL;
7697 pgid = tcgetpgrp(fd);
7698 if (pgid < 0)
7699 return posix_error();
7700 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007701}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007702#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007703
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007704
Guido van Rossumb6775db1994-08-01 11:34:53 +00007705#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007706PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007707"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007708Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007709
Barry Warsaw53699e91996-12-10 23:23:01 +00007710static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007711posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007712{
Victor Stinner8c62be82010-05-06 00:08:46 +00007713 int fd;
7714 pid_t pgid;
7715 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7716 return NULL;
7717 if (tcsetpgrp(fd, pgid) < 0)
7718 return posix_error();
7719 Py_INCREF(Py_None);
7720 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007721}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007722#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007723
Guido van Rossum687dd131993-05-17 08:34:16 +00007724/* Functions acting on file descriptors */
7725
Victor Stinnerdaf45552013-08-28 00:53:59 +02007726#ifdef O_CLOEXEC
7727extern int _Py_open_cloexec_works;
7728#endif
7729
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007730PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007731"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7732Open a file for low level IO. Returns a file handle (integer).\n\
7733\n\
7734If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7735 and path should be relative; path will then be relative to that directory.\n\
7736dir_fd may not be implemented on your platform.\n\
7737 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007738
Barry Warsaw53699e91996-12-10 23:23:01 +00007739static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007740posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007741{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007742 path_t path;
7743 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007744 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007745 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007746 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007747 PyObject *return_value = NULL;
7748 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Victor Stinnerdaf45552013-08-28 00:53:59 +02007749#ifdef O_CLOEXEC
7750 int *atomic_flag_works = &_Py_open_cloexec_works;
7751#elif !defined(MS_WINDOWS)
7752 int *atomic_flag_works = NULL;
7753#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007754
Larry Hastings9cf065c2012-06-22 16:30:09 -07007755 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007756 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007757 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7758 path_converter, &path,
7759 &flags, &mode,
7760#ifdef HAVE_OPENAT
7761 dir_fd_converter, &dir_fd
7762#else
7763 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007764#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007765 ))
7766 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007767
Victor Stinnerdaf45552013-08-28 00:53:59 +02007768#ifdef MS_WINDOWS
7769 flags |= O_NOINHERIT;
7770#elif defined(O_CLOEXEC)
7771 flags |= O_CLOEXEC;
7772#endif
7773
Victor Stinner8c62be82010-05-06 00:08:46 +00007774 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007775#ifdef MS_WINDOWS
7776 if (path.wide)
7777 fd = _wopen(path.wide, flags, mode);
7778 else
7779#endif
7780#ifdef HAVE_OPENAT
7781 if (dir_fd != DEFAULT_DIR_FD)
7782 fd = openat(dir_fd, path.narrow, flags, mode);
7783 else
7784#endif
7785 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007786 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007787
Larry Hastings9cf065c2012-06-22 16:30:09 -07007788 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007789 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007790 goto exit;
7791 }
7792
Victor Stinnerdaf45552013-08-28 00:53:59 +02007793#ifndef MS_WINDOWS
7794 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7795 close(fd);
7796 goto exit;
7797 }
7798#endif
7799
Larry Hastings9cf065c2012-06-22 16:30:09 -07007800 return_value = PyLong_FromLong((long)fd);
7801
7802exit:
7803 path_cleanup(&path);
7804 return return_value;
7805}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007806
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007807PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007808"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007809Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007810
Benjamin Peterson932bba32014-02-11 10:16:16 -05007811/*
7812The underscore at end of function name avoids a name clash with the libc
7813function posix_close.
7814*/
Barry Warsaw53699e91996-12-10 23:23:01 +00007815static PyObject *
Benjamin Peterson932bba32014-02-11 10:16:16 -05007816posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007817{
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 int fd, res;
7819 if (!PyArg_ParseTuple(args, "i:close", &fd))
7820 return NULL;
7821 if (!_PyVerify_fd(fd))
7822 return posix_error();
7823 Py_BEGIN_ALLOW_THREADS
7824 res = close(fd);
7825 Py_END_ALLOW_THREADS
7826 if (res < 0)
7827 return posix_error();
7828 Py_INCREF(Py_None);
7829 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007830}
7831
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007832
Victor Stinner8c62be82010-05-06 00:08:46 +00007833PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007834"closerange(fd_low, fd_high)\n\n\
7835Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7836
7837static PyObject *
7838posix_closerange(PyObject *self, PyObject *args)
7839{
Victor Stinner8c62be82010-05-06 00:08:46 +00007840 int fd_from, fd_to, i;
7841 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7842 return NULL;
7843 Py_BEGIN_ALLOW_THREADS
7844 for (i = fd_from; i < fd_to; i++)
7845 if (_PyVerify_fd(i))
7846 close(i);
7847 Py_END_ALLOW_THREADS
7848 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007849}
7850
7851
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007852PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007853"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007854Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007855
Barry Warsaw53699e91996-12-10 23:23:01 +00007856static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007857posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007858{
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 int fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007860
Victor Stinner8c62be82010-05-06 00:08:46 +00007861 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7862 return NULL;
Tim Golden23005082013-10-25 11:22:37 +01007863
Victor Stinnerdaf45552013-08-28 00:53:59 +02007864 fd = _Py_dup(fd);
7865 if (fd == -1)
7866 return NULL;
7867
Victor Stinner8c62be82010-05-06 00:08:46 +00007868 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007869}
7870
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007871
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007872PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007873"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007874Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007875
Barry Warsaw53699e91996-12-10 23:23:01 +00007876static PyObject *
Victor Stinnerdaf45552013-08-28 00:53:59 +02007877posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007878{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007879 static char *keywords[] = {"fd", "fd2", "inheritable", NULL};
7880 int fd, fd2;
7881 int inheritable = 1;
7882 int res;
7883#if defined(HAVE_DUP3) && \
7884 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7885 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7886 int dup3_works = -1;
7887#endif
7888
7889 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords,
7890 &fd, &fd2, &inheritable))
Victor Stinner8c62be82010-05-06 00:08:46 +00007891 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007892
Victor Stinner8c62be82010-05-06 00:08:46 +00007893 if (!_PyVerify_fd_dup2(fd, fd2))
7894 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007895
7896#ifdef MS_WINDOWS
7897 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007898 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007899 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007900 if (res < 0)
7901 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007902
7903 /* Character files like console cannot be make non-inheritable */
7904 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7905 close(fd2);
7906 return NULL;
7907 }
7908
7909#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7910 Py_BEGIN_ALLOW_THREADS
7911 if (!inheritable)
7912 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7913 else
7914 res = dup2(fd, fd2);
7915 Py_END_ALLOW_THREADS
7916 if (res < 0)
7917 return posix_error();
7918
7919#else
7920
7921#ifdef HAVE_DUP3
7922 if (!inheritable && dup3_works != 0) {
7923 Py_BEGIN_ALLOW_THREADS
7924 res = dup3(fd, fd2, O_CLOEXEC);
7925 Py_END_ALLOW_THREADS
7926 if (res < 0) {
7927 if (dup3_works == -1)
7928 dup3_works = (errno != ENOSYS);
7929 if (dup3_works)
7930 return posix_error();
7931 }
7932 }
7933
7934 if (inheritable || dup3_works == 0)
7935 {
7936#endif
7937 Py_BEGIN_ALLOW_THREADS
7938 res = dup2(fd, fd2);
7939 Py_END_ALLOW_THREADS
7940 if (res < 0)
7941 return posix_error();
7942
7943 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7944 close(fd2);
7945 return NULL;
7946 }
7947#ifdef HAVE_DUP3
7948 }
7949#endif
7950
7951#endif
7952
Victor Stinner8c62be82010-05-06 00:08:46 +00007953 Py_INCREF(Py_None);
7954 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007955}
7956
Ross Lagerwall7807c352011-03-17 20:20:30 +02007957#ifdef HAVE_LOCKF
7958PyDoc_STRVAR(posix_lockf__doc__,
7959"lockf(fd, cmd, len)\n\n\
7960Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7961fd is an open file descriptor.\n\
7962cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7963F_TEST.\n\
7964len specifies the section of the file to lock.");
7965
7966static PyObject *
7967posix_lockf(PyObject *self, PyObject *args)
7968{
7969 int fd, cmd, res;
7970 off_t len;
7971 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7972 &fd, &cmd, _parse_off_t, &len))
7973 return NULL;
7974
7975 Py_BEGIN_ALLOW_THREADS
7976 res = lockf(fd, cmd, len);
7977 Py_END_ALLOW_THREADS
7978
7979 if (res < 0)
7980 return posix_error();
7981
7982 Py_RETURN_NONE;
7983}
7984#endif
7985
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007986
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007987PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007988"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007989Set the current position of a file descriptor.\n\
7990Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007991
Barry Warsaw53699e91996-12-10 23:23:01 +00007992static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007993posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007994{
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007996#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007997 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007998#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00008000#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02008001 PyObject *posobj;
8002 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00008003 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00008004#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008005 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8006 switch (how) {
8007 case 0: how = SEEK_SET; break;
8008 case 1: how = SEEK_CUR; break;
8009 case 2: how = SEEK_END; break;
8010 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008011#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008012
Ross Lagerwall8e749672011-03-17 21:54:07 +02008013#if !defined(HAVE_LARGEFILE_SUPPORT)
8014 pos = PyLong_AsLong(posobj);
8015#else
8016 pos = PyLong_AsLongLong(posobj);
8017#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 if (PyErr_Occurred())
8019 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008020
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 if (!_PyVerify_fd(fd))
8022 return posix_error();
8023 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008024#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00008026#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008027 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00008028#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008029 Py_END_ALLOW_THREADS
8030 if (res < 0)
8031 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008032
8033#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008034 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008035#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008036 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008037#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008038}
8039
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008040
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008041PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008042"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008043Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008044
Barry Warsaw53699e91996-12-10 23:23:01 +00008045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008046posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008047{
Victor Stinner8c62be82010-05-06 00:08:46 +00008048 int fd, size;
8049 Py_ssize_t n;
8050 PyObject *buffer;
8051 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
8052 return NULL;
8053 if (size < 0) {
8054 errno = EINVAL;
8055 return posix_error();
8056 }
8057 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8058 if (buffer == NULL)
8059 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00008060 if (!_PyVerify_fd(fd)) {
8061 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00008062 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00008063 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008064 Py_BEGIN_ALLOW_THREADS
8065 n = read(fd, PyBytes_AS_STRING(buffer), size);
8066 Py_END_ALLOW_THREADS
8067 if (n < 0) {
8068 Py_DECREF(buffer);
8069 return posix_error();
8070 }
8071 if (n != size)
8072 _PyBytes_Resize(&buffer, n);
8073 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008074}
8075
Ross Lagerwall7807c352011-03-17 20:20:30 +02008076#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8077 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008078static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008079iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8080{
8081 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008082 Py_ssize_t blen, total = 0;
8083
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008084 *iov = PyMem_New(struct iovec, cnt);
8085 if (*iov == NULL) {
8086 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008087 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008088 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008089
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008090 *buf = PyMem_New(Py_buffer, cnt);
8091 if (*buf == NULL) {
8092 PyMem_Del(*iov);
8093 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008094 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008095 }
8096
8097 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008098 PyObject *item = PySequence_GetItem(seq, i);
8099 if (item == NULL)
8100 goto fail;
8101 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8102 Py_DECREF(item);
8103 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008104 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008105 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008106 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008107 blen = (*buf)[i].len;
8108 (*iov)[i].iov_len = blen;
8109 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008110 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008111 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008112
8113fail:
8114 PyMem_Del(*iov);
8115 for (j = 0; j < i; j++) {
8116 PyBuffer_Release(&(*buf)[j]);
8117 }
8118 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008119 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008120}
8121
8122static void
8123iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8124{
8125 int i;
8126 PyMem_Del(iov);
8127 for (i = 0; i < cnt; i++) {
8128 PyBuffer_Release(&buf[i]);
8129 }
8130 PyMem_Del(buf);
8131}
8132#endif
8133
Ross Lagerwall7807c352011-03-17 20:20:30 +02008134#ifdef HAVE_READV
8135PyDoc_STRVAR(posix_readv__doc__,
8136"readv(fd, buffers) -> bytesread\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008137Read from a file descriptor fd into a number of mutable, bytes-like\n\
8138objects (\"buffers\"). readv will transfer data into each buffer\n\
8139until it is full and then move on to the next buffer in the sequence\n\
8140to hold the rest of the data.\n\n\
8141readv returns the total number of bytes read (which may be less than\n\
8142the total capacity of all the buffers.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008143
8144static PyObject *
8145posix_readv(PyObject *self, PyObject *args)
8146{
8147 int fd, cnt;
8148 Py_ssize_t n;
8149 PyObject *seq;
8150 struct iovec *iov;
8151 Py_buffer *buf;
8152
8153 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8154 return NULL;
8155 if (!PySequence_Check(seq)) {
8156 PyErr_SetString(PyExc_TypeError,
8157 "readv() arg 2 must be a sequence");
8158 return NULL;
8159 }
8160 cnt = PySequence_Size(seq);
8161
Victor Stinner57ddf782014-01-08 15:21:28 +01008162 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE) < 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008163 return NULL;
8164
8165 Py_BEGIN_ALLOW_THREADS
8166 n = readv(fd, iov, cnt);
8167 Py_END_ALLOW_THREADS
8168
8169 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008170 if (n < 0)
8171 return posix_error();
8172
Ross Lagerwall7807c352011-03-17 20:20:30 +02008173 return PyLong_FromSsize_t(n);
8174}
8175#endif
8176
8177#ifdef HAVE_PREAD
8178PyDoc_STRVAR(posix_pread__doc__,
8179"pread(fd, buffersize, offset) -> string\n\n\
8180Read from a file descriptor, fd, at a position of offset. It will read up\n\
8181to buffersize number of bytes. The file offset remains unchanged.");
8182
8183static PyObject *
8184posix_pread(PyObject *self, PyObject *args)
8185{
8186 int fd, size;
8187 off_t offset;
8188 Py_ssize_t n;
8189 PyObject *buffer;
8190 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8191 return NULL;
8192
8193 if (size < 0) {
8194 errno = EINVAL;
8195 return posix_error();
8196 }
8197 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8198 if (buffer == NULL)
8199 return NULL;
8200 if (!_PyVerify_fd(fd)) {
8201 Py_DECREF(buffer);
8202 return posix_error();
8203 }
8204 Py_BEGIN_ALLOW_THREADS
8205 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8206 Py_END_ALLOW_THREADS
8207 if (n < 0) {
8208 Py_DECREF(buffer);
8209 return posix_error();
8210 }
8211 if (n != size)
8212 _PyBytes_Resize(&buffer, n);
8213 return buffer;
8214}
8215#endif
8216
8217PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008218"write(fd, data) -> byteswritten\n\n\
8219Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008220
8221static PyObject *
8222posix_write(PyObject *self, PyObject *args)
8223{
8224 Py_buffer pbuf;
8225 int fd;
8226 Py_ssize_t size, len;
8227
8228 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8229 return NULL;
8230 if (!_PyVerify_fd(fd)) {
8231 PyBuffer_Release(&pbuf);
8232 return posix_error();
8233 }
8234 len = pbuf.len;
8235 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008236#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008237 if (len > INT_MAX)
8238 len = INT_MAX;
8239 size = write(fd, pbuf.buf, (int)len);
8240#else
8241 size = write(fd, pbuf.buf, len);
8242#endif
8243 Py_END_ALLOW_THREADS
8244 PyBuffer_Release(&pbuf);
8245 if (size < 0)
8246 return posix_error();
8247 return PyLong_FromSsize_t(size);
8248}
8249
8250#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008251PyDoc_STRVAR(posix_sendfile__doc__,
8252"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8253sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8254 -> byteswritten\n\
8255Copy nbytes bytes from file descriptor in to file descriptor out.");
8256
8257static PyObject *
8258posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8259{
8260 int in, out;
8261 Py_ssize_t ret;
8262 off_t offset;
8263
8264#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8265#ifndef __APPLE__
8266 Py_ssize_t len;
8267#endif
8268 PyObject *headers = NULL, *trailers = NULL;
8269 Py_buffer *hbuf, *tbuf;
8270 off_t sbytes;
8271 struct sf_hdtr sf;
8272 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008273 static char *keywords[] = {"out", "in",
8274 "offset", "count",
8275 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008276
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008277 sf.headers = NULL;
8278 sf.trailers = NULL;
8279
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008280#ifdef __APPLE__
8281 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008282 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008283#else
8284 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008285 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008286#endif
8287 &headers, &trailers, &flags))
8288 return NULL;
8289 if (headers != NULL) {
8290 if (!PySequence_Check(headers)) {
8291 PyErr_SetString(PyExc_TypeError,
8292 "sendfile() headers must be a sequence or None");
8293 return NULL;
8294 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008295 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008296 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008297 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008298 (i = iov_setup(&(sf.headers), &hbuf,
8299 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008300 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008301#ifdef __APPLE__
8302 sbytes += i;
8303#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008304 }
8305 }
8306 if (trailers != NULL) {
8307 if (!PySequence_Check(trailers)) {
8308 PyErr_SetString(PyExc_TypeError,
8309 "sendfile() trailers must be a sequence or None");
8310 return NULL;
8311 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008312 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008313 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008314 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008315 (i = iov_setup(&(sf.trailers), &tbuf,
8316 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008317 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008318#ifdef __APPLE__
8319 sbytes += i;
8320#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008321 }
8322 }
8323
8324 Py_BEGIN_ALLOW_THREADS
8325#ifdef __APPLE__
8326 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8327#else
8328 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8329#endif
8330 Py_END_ALLOW_THREADS
8331
8332 if (sf.headers != NULL)
8333 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8334 if (sf.trailers != NULL)
8335 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8336
8337 if (ret < 0) {
8338 if ((errno == EAGAIN) || (errno == EBUSY)) {
8339 if (sbytes != 0) {
8340 // some data has been sent
8341 goto done;
8342 }
8343 else {
8344 // no data has been sent; upper application is supposed
8345 // to retry on EAGAIN or EBUSY
8346 return posix_error();
8347 }
8348 }
8349 return posix_error();
8350 }
8351 goto done;
8352
8353done:
8354 #if !defined(HAVE_LARGEFILE_SUPPORT)
8355 return Py_BuildValue("l", sbytes);
8356 #else
8357 return Py_BuildValue("L", sbytes);
8358 #endif
8359
8360#else
8361 Py_ssize_t count;
8362 PyObject *offobj;
8363 static char *keywords[] = {"out", "in",
8364 "offset", "count", NULL};
8365 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8366 keywords, &out, &in, &offobj, &count))
8367 return NULL;
8368#ifdef linux
8369 if (offobj == Py_None) {
8370 Py_BEGIN_ALLOW_THREADS
8371 ret = sendfile(out, in, NULL, count);
8372 Py_END_ALLOW_THREADS
8373 if (ret < 0)
8374 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008375 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008376 }
8377#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008378 if (!_parse_off_t(offobj, &offset))
8379 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008380 Py_BEGIN_ALLOW_THREADS
8381 ret = sendfile(out, in, &offset, count);
8382 Py_END_ALLOW_THREADS
8383 if (ret < 0)
8384 return posix_error();
8385 return Py_BuildValue("n", ret);
8386#endif
8387}
8388#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008389
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008390PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008391"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008392Like stat(), but for an open file descriptor.\n\
8393Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008394
Barry Warsaw53699e91996-12-10 23:23:01 +00008395static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008396posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008397{
Victor Stinner8c62be82010-05-06 00:08:46 +00008398 int fd;
8399 STRUCT_STAT st;
8400 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008401 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008402 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008403 Py_BEGIN_ALLOW_THREADS
8404 res = FSTAT(fd, &st);
8405 Py_END_ALLOW_THREADS
8406 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008407#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008408 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008409#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008410 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008411#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008412 }
Tim Peters5aa91602002-01-30 05:46:57 +00008413
Victor Stinner4195b5c2012-02-08 23:03:19 +01008414 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008415}
8416
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008417PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008418"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008419Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008420connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008421
8422static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008423posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008424{
Victor Stinner8c62be82010-05-06 00:08:46 +00008425 int fd;
8426 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8427 return NULL;
8428 if (!_PyVerify_fd(fd))
8429 return PyBool_FromLong(0);
8430 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008431}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008432
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008433#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008434PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008435"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008436Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008437
Barry Warsaw53699e91996-12-10 23:23:01 +00008438static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008439posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008440{
Victor Stinner8c62be82010-05-06 00:08:46 +00008441 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008442#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008443 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008444 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008445 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008446#else
8447 int res;
8448#endif
8449
8450#ifdef MS_WINDOWS
8451 attr.nLength = sizeof(attr);
8452 attr.lpSecurityDescriptor = NULL;
8453 attr.bInheritHandle = FALSE;
8454
8455 Py_BEGIN_ALLOW_THREADS
8456 ok = CreatePipe(&read, &write, &attr, 0);
8457 if (ok) {
8458 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8459 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8460 if (fds[0] == -1 || fds[1] == -1) {
8461 CloseHandle(read);
8462 CloseHandle(write);
8463 ok = 0;
8464 }
8465 }
8466 Py_END_ALLOW_THREADS
8467
Victor Stinner8c62be82010-05-06 00:08:46 +00008468 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008469 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008470#else
8471
8472#ifdef HAVE_PIPE2
8473 Py_BEGIN_ALLOW_THREADS
8474 res = pipe2(fds, O_CLOEXEC);
8475 Py_END_ALLOW_THREADS
8476
8477 if (res != 0 && errno == ENOSYS)
8478 {
8479#endif
8480 Py_BEGIN_ALLOW_THREADS
8481 res = pipe(fds);
8482 Py_END_ALLOW_THREADS
8483
8484 if (res == 0) {
8485 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8486 close(fds[0]);
8487 close(fds[1]);
8488 return NULL;
8489 }
8490 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8491 close(fds[0]);
8492 close(fds[1]);
8493 return NULL;
8494 }
8495 }
8496#ifdef HAVE_PIPE2
8497 }
8498#endif
8499
8500 if (res != 0)
8501 return PyErr_SetFromErrno(PyExc_OSError);
8502#endif /* !MS_WINDOWS */
8503 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008504}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008505#endif /* HAVE_PIPE */
8506
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008507#ifdef HAVE_PIPE2
8508PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008509"pipe2(flags) -> (read_end, write_end)\n\n\
8510Create a pipe with flags set atomically.\n\
8511flags can be constructed by ORing together one or more of these values:\n\
8512O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008513");
8514
8515static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008516posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008517{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008518 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008519 int fds[2];
8520 int res;
8521
Serhiy Storchaka78980432013-01-15 01:12:17 +02008522 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008523 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008524 return NULL;
8525
8526 res = pipe2(fds, flags);
8527 if (res != 0)
8528 return posix_error();
8529 return Py_BuildValue("(ii)", fds[0], fds[1]);
8530}
8531#endif /* HAVE_PIPE2 */
8532
Ross Lagerwall7807c352011-03-17 20:20:30 +02008533#ifdef HAVE_WRITEV
8534PyDoc_STRVAR(posix_writev__doc__,
8535"writev(fd, buffers) -> byteswritten\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008536Write the contents of *buffers* to file descriptor *fd*. *buffers*\n\
8537must be a sequence of bytes-like objects.\n\n\
8538writev writes the contents of each object to the file descriptor\n\
8539and returns the total number of bytes written.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008540
8541static PyObject *
8542posix_writev(PyObject *self, PyObject *args)
8543{
8544 int fd, cnt;
8545 Py_ssize_t res;
8546 PyObject *seq;
8547 struct iovec *iov;
8548 Py_buffer *buf;
8549 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8550 return NULL;
8551 if (!PySequence_Check(seq)) {
8552 PyErr_SetString(PyExc_TypeError,
8553 "writev() arg 2 must be a sequence");
8554 return NULL;
8555 }
8556 cnt = PySequence_Size(seq);
8557
Victor Stinner57ddf782014-01-08 15:21:28 +01008558 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008559 return NULL;
8560 }
8561
8562 Py_BEGIN_ALLOW_THREADS
8563 res = writev(fd, iov, cnt);
8564 Py_END_ALLOW_THREADS
8565
8566 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008567 if (res < 0)
8568 return posix_error();
8569
Ross Lagerwall7807c352011-03-17 20:20:30 +02008570 return PyLong_FromSsize_t(res);
8571}
8572#endif
8573
8574#ifdef HAVE_PWRITE
8575PyDoc_STRVAR(posix_pwrite__doc__,
8576"pwrite(fd, string, offset) -> byteswritten\n\n\
8577Write string to a file descriptor, fd, from offset, leaving the file\n\
8578offset unchanged.");
8579
8580static PyObject *
8581posix_pwrite(PyObject *self, PyObject *args)
8582{
8583 Py_buffer pbuf;
8584 int fd;
8585 off_t offset;
8586 Py_ssize_t size;
8587
8588 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8589 return NULL;
8590
8591 if (!_PyVerify_fd(fd)) {
8592 PyBuffer_Release(&pbuf);
8593 return posix_error();
8594 }
8595 Py_BEGIN_ALLOW_THREADS
8596 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8597 Py_END_ALLOW_THREADS
8598 PyBuffer_Release(&pbuf);
8599 if (size < 0)
8600 return posix_error();
8601 return PyLong_FromSsize_t(size);
8602}
8603#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008604
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008605#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008606PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008607"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8608Create a FIFO (a POSIX named pipe).\n\
8609\n\
8610If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8611 and path should be relative; path will then be relative to that directory.\n\
8612dir_fd may not be implemented on your platform.\n\
8613 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008614
Barry Warsaw53699e91996-12-10 23:23:01 +00008615static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008616posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008617{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008618 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008619 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008620 int dir_fd = DEFAULT_DIR_FD;
8621 int result;
8622 PyObject *return_value = NULL;
8623 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8624
8625 memset(&path, 0, sizeof(path));
8626 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8627 path_converter, &path,
8628 &mode,
8629#ifdef HAVE_MKFIFOAT
8630 dir_fd_converter, &dir_fd
8631#else
8632 dir_fd_unavailable, &dir_fd
8633#endif
8634 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008635 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008636
Victor Stinner8c62be82010-05-06 00:08:46 +00008637 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008638#ifdef HAVE_MKFIFOAT
8639 if (dir_fd != DEFAULT_DIR_FD)
8640 result = mkfifoat(dir_fd, path.narrow, mode);
8641 else
8642#endif
8643 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008644 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008645
8646 if (result < 0) {
8647 return_value = posix_error();
8648 goto exit;
8649 }
8650
8651 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008652 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008653
8654exit:
8655 path_cleanup(&path);
8656 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008657}
8658#endif
8659
Neal Norwitz11690112002-07-30 01:08:28 +00008660#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008661PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008662"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008663Create a filesystem node (file, device special file or named pipe)\n\
8664named filename. mode specifies both the permissions to use and the\n\
8665type of node to be created, being combined (bitwise OR) with one of\n\
8666S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008667device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008668os.makedev()), otherwise it is ignored.\n\
8669\n\
8670If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8671 and path should be relative; path will then be relative to that directory.\n\
8672dir_fd may not be implemented on your platform.\n\
8673 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008674
8675
8676static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008677posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008678{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008679 path_t path;
8680 int mode = 0666;
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008681 dev_t device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008682 int dir_fd = DEFAULT_DIR_FD;
8683 int result;
8684 PyObject *return_value = NULL;
8685 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8686
8687 memset(&path, 0, sizeof(path));
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008688 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|iO&$O&:mknod", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008689 path_converter, &path,
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008690 &mode, _Py_Dev_Converter, &device,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008691#ifdef HAVE_MKNODAT
8692 dir_fd_converter, &dir_fd
8693#else
8694 dir_fd_unavailable, &dir_fd
8695#endif
8696 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008697 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008698
Victor Stinner8c62be82010-05-06 00:08:46 +00008699 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008700#ifdef HAVE_MKNODAT
8701 if (dir_fd != DEFAULT_DIR_FD)
8702 result = mknodat(dir_fd, path.narrow, mode, device);
8703 else
8704#endif
8705 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008707
8708 if (result < 0) {
8709 return_value = posix_error();
8710 goto exit;
8711 }
8712
8713 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008714 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008715
Larry Hastings9cf065c2012-06-22 16:30:09 -07008716exit:
8717 path_cleanup(&path);
8718 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008719}
8720#endif
8721
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008722#ifdef HAVE_DEVICE_MACROS
8723PyDoc_STRVAR(posix_major__doc__,
8724"major(device) -> major number\n\
8725Extracts a device major number from a raw device number.");
8726
8727static PyObject *
8728posix_major(PyObject *self, PyObject *args)
8729{
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008730 dev_t device;
8731 if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00008732 return NULL;
8733 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008734}
8735
8736PyDoc_STRVAR(posix_minor__doc__,
8737"minor(device) -> minor number\n\
8738Extracts a device minor number from a raw device number.");
8739
8740static PyObject *
8741posix_minor(PyObject *self, PyObject *args)
8742{
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008743 dev_t device;
8744 if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00008745 return NULL;
8746 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008747}
8748
8749PyDoc_STRVAR(posix_makedev__doc__,
8750"makedev(major, minor) -> device number\n\
8751Composes a raw device number from the major and minor device numbers.");
8752
8753static PyObject *
8754posix_makedev(PyObject *self, PyObject *args)
8755{
Victor Stinner8c62be82010-05-06 00:08:46 +00008756 int major, minor;
8757 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8758 return NULL;
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008759 return _PyLong_FromDev(makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008760}
8761#endif /* device macros */
8762
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008763
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008764#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008765PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008766"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008767Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008768
Barry Warsaw53699e91996-12-10 23:23:01 +00008769static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008770posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008771{
Victor Stinner8c62be82010-05-06 00:08:46 +00008772 int fd;
8773 off_t length;
8774 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008775
Ross Lagerwall7807c352011-03-17 20:20:30 +02008776 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008777 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008778
Victor Stinner8c62be82010-05-06 00:08:46 +00008779 Py_BEGIN_ALLOW_THREADS
8780 res = ftruncate(fd, length);
8781 Py_END_ALLOW_THREADS
8782 if (res < 0)
8783 return posix_error();
8784 Py_INCREF(Py_None);
8785 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008786}
8787#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008788
Ross Lagerwall7807c352011-03-17 20:20:30 +02008789#ifdef HAVE_TRUNCATE
8790PyDoc_STRVAR(posix_truncate__doc__,
8791"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008792Truncate the file given by path to length bytes.\n\
8793On some platforms, path may also be specified as an open file descriptor.\n\
8794 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008795
8796static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008797posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008798{
Georg Brandl306336b2012-06-24 12:55:33 +02008799 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008800 off_t length;
8801 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008802 PyObject *result = NULL;
8803 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008804
Georg Brandl306336b2012-06-24 12:55:33 +02008805 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008806 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008807#ifdef HAVE_FTRUNCATE
8808 path.allow_fd = 1;
8809#endif
8810 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8811 path_converter, &path,
8812 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008813 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008814
8815 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008816#ifdef HAVE_FTRUNCATE
8817 if (path.fd != -1)
8818 res = ftruncate(path.fd, length);
8819 else
8820#endif
8821 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008822 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008823 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008824 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008825 else {
8826 Py_INCREF(Py_None);
8827 result = Py_None;
8828 }
8829 path_cleanup(&path);
8830 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008831}
8832#endif
8833
Victor Stinnerd6b17692014-09-30 12:20:05 +02008834/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8835 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8836 defined, which is the case in Python on AIX. AIX bug report:
8837 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8838#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8839# define POSIX_FADVISE_AIX_BUG
8840#endif
8841
8842#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008843PyDoc_STRVAR(posix_posix_fallocate__doc__,
8844"posix_fallocate(fd, offset, len)\n\n\
8845Ensures that enough disk space is allocated for the file specified by fd\n\
8846starting from offset and continuing for len bytes.");
8847
8848static PyObject *
8849posix_posix_fallocate(PyObject *self, PyObject *args)
8850{
8851 off_t len, offset;
8852 int res, fd;
8853
8854 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8855 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8856 return NULL;
8857
8858 Py_BEGIN_ALLOW_THREADS
8859 res = posix_fallocate(fd, offset, len);
8860 Py_END_ALLOW_THREADS
8861 if (res != 0) {
8862 errno = res;
8863 return posix_error();
8864 }
8865 Py_RETURN_NONE;
8866}
8867#endif
8868
Victor Stinnerd6b17692014-09-30 12:20:05 +02008869#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008870PyDoc_STRVAR(posix_posix_fadvise__doc__,
8871"posix_fadvise(fd, offset, len, advice)\n\n\
8872Announces an intention to access data in a specific pattern thus allowing\n\
8873the kernel to make optimizations.\n\
8874The advice applies to the region of the file specified by fd starting at\n\
8875offset and continuing for len bytes.\n\
8876advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8877POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8878POSIX_FADV_DONTNEED.");
8879
8880static PyObject *
8881posix_posix_fadvise(PyObject *self, PyObject *args)
8882{
8883 off_t len, offset;
8884 int res, fd, advice;
8885
8886 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8887 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8888 return NULL;
8889
8890 Py_BEGIN_ALLOW_THREADS
8891 res = posix_fadvise(fd, offset, len, advice);
8892 Py_END_ALLOW_THREADS
8893 if (res != 0) {
8894 errno = res;
8895 return posix_error();
8896 }
8897 Py_RETURN_NONE;
8898}
8899#endif
8900
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008901#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008902PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008903"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008904Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008905
Fred Drake762e2061999-08-26 17:23:54 +00008906/* Save putenv() parameters as values here, so we can collect them when they
8907 * get re-set with another call for the same key. */
8908static PyObject *posix_putenv_garbage;
8909
Tim Peters5aa91602002-01-30 05:46:57 +00008910static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008911posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008912{
Victor Stinner84ae1182010-05-06 22:05:07 +00008913 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008914#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008915 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008916 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008917
Victor Stinner8c62be82010-05-06 00:08:46 +00008918 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008919 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008920 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008921 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008922
Victor Stinner65170952011-11-22 22:16:17 +01008923 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008924 if (newstr == NULL) {
8925 PyErr_NoMemory();
8926 goto error;
8927 }
Victor Stinner65170952011-11-22 22:16:17 +01008928 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8929 PyErr_Format(PyExc_ValueError,
8930 "the environment variable is longer than %u characters",
8931 _MAX_ENV);
8932 goto error;
8933 }
8934
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008936 if (newenv == NULL)
8937 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008938 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008939 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008940 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008941 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008942#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008943 PyObject *os1, *os2;
8944 char *s1, *s2;
8945 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008946
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008947 if (!PyArg_ParseTuple(args,
8948 "O&O&:putenv",
8949 PyUnicode_FSConverter, &os1,
8950 PyUnicode_FSConverter, &os2))
8951 return NULL;
8952 s1 = PyBytes_AsString(os1);
8953 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008954
Victor Stinner65170952011-11-22 22:16:17 +01008955 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008956 if (newstr == NULL) {
8957 PyErr_NoMemory();
8958 goto error;
8959 }
8960
Victor Stinner8c62be82010-05-06 00:08:46 +00008961 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008962 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008963 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008964 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008965 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008966#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008967
Victor Stinner8c62be82010-05-06 00:08:46 +00008968 /* Install the first arg and newstr in posix_putenv_garbage;
8969 * this will cause previous value to be collected. This has to
8970 * happen after the real putenv() call because the old value
8971 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008972 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008973 /* really not much we can do; just leak */
8974 PyErr_Clear();
8975 }
8976 else {
8977 Py_DECREF(newstr);
8978 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008979
Martin v. Löwis011e8422009-05-05 04:43:17 +00008980#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008981 Py_DECREF(os1);
8982 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008983#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008984 Py_RETURN_NONE;
8985
8986error:
8987#ifndef MS_WINDOWS
8988 Py_DECREF(os1);
8989 Py_DECREF(os2);
8990#endif
8991 Py_XDECREF(newstr);
8992 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008993}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008994#endif /* putenv */
8995
Guido van Rossumc524d952001-10-19 01:31:59 +00008996#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008997PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008998"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008999Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00009000
9001static PyObject *
9002posix_unsetenv(PyObject *self, PyObject *args)
9003{
Victor Stinner65170952011-11-22 22:16:17 +01009004 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01009005#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009006 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009007#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009008
9009 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00009010
Victor Stinner65170952011-11-22 22:16:17 +01009011 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00009012 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00009013
Victor Stinner984890f2011-11-24 13:53:38 +01009014#ifdef HAVE_BROKEN_UNSETENV
9015 unsetenv(PyBytes_AS_STRING(name));
9016#else
Victor Stinner65170952011-11-22 22:16:17 +01009017 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06009018 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06009019 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01009020 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06009021 }
Victor Stinner984890f2011-11-24 13:53:38 +01009022#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009023
Victor Stinner8c62be82010-05-06 00:08:46 +00009024 /* Remove the key from posix_putenv_garbage;
9025 * this will cause it to be collected. This has to
9026 * happen after the real unsetenv() call because the
9027 * old value was still accessible until then.
9028 */
Victor Stinner65170952011-11-22 22:16:17 +01009029 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009030 /* really not much we can do; just leak */
9031 PyErr_Clear();
9032 }
Victor Stinner65170952011-11-22 22:16:17 +01009033 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00009034 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009035}
9036#endif /* unsetenv */
9037
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009038PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009039"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009040Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009041
Guido van Rossumf68d8e52001-04-14 17:55:09 +00009042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009043posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00009044{
Victor Stinner8c62be82010-05-06 00:08:46 +00009045 int code;
9046 char *message;
9047 if (!PyArg_ParseTuple(args, "i:strerror", &code))
9048 return NULL;
9049 message = strerror(code);
9050 if (message == NULL) {
9051 PyErr_SetString(PyExc_ValueError,
9052 "strerror() argument out of range");
9053 return NULL;
9054 }
Victor Stinner1b579672011-12-17 05:47:23 +01009055 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009056}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009057
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009058
Guido van Rossumc9641791998-08-04 15:26:23 +00009059#ifdef HAVE_SYS_WAIT_H
9060
Fred Drake106c1a02002-04-23 15:58:02 +00009061#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009062PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009063"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009064Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00009065
9066static PyObject *
9067posix_WCOREDUMP(PyObject *self, PyObject *args)
9068{
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 WAIT_TYPE status;
9070 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009071
Victor Stinner8c62be82010-05-06 00:08:46 +00009072 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
9073 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009074
Victor Stinner8c62be82010-05-06 00:08:46 +00009075 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009076}
9077#endif /* WCOREDUMP */
9078
9079#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009080PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009081"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00009082Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009083job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00009084
9085static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009086posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00009087{
Victor Stinner8c62be82010-05-06 00:08:46 +00009088 WAIT_TYPE status;
9089 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009090
Victor Stinner8c62be82010-05-06 00:08:46 +00009091 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
9092 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009093
Victor Stinner8c62be82010-05-06 00:08:46 +00009094 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009095}
9096#endif /* WIFCONTINUED */
9097
Guido van Rossumc9641791998-08-04 15:26:23 +00009098#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009099PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009100"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009101Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009102
9103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009104posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009105{
Victor Stinner8c62be82010-05-06 00:08:46 +00009106 WAIT_TYPE status;
9107 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009108
Victor Stinner8c62be82010-05-06 00:08:46 +00009109 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
9110 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009111
Victor Stinner8c62be82010-05-06 00:08:46 +00009112 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009113}
9114#endif /* WIFSTOPPED */
9115
9116#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009117PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009118"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009119Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009120
9121static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009122posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009123{
Victor Stinner8c62be82010-05-06 00:08:46 +00009124 WAIT_TYPE status;
9125 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009126
Victor Stinner8c62be82010-05-06 00:08:46 +00009127 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9128 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009129
Victor Stinner8c62be82010-05-06 00:08:46 +00009130 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009131}
9132#endif /* WIFSIGNALED */
9133
9134#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009135PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009136"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009137Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009138system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009139
9140static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009141posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009142{
Victor Stinner8c62be82010-05-06 00:08:46 +00009143 WAIT_TYPE status;
9144 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009145
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9147 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009148
Victor Stinner8c62be82010-05-06 00:08:46 +00009149 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009150}
9151#endif /* WIFEXITED */
9152
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009153#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009154PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009155"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009156Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009157
9158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009159posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009160{
Victor Stinner8c62be82010-05-06 00:08:46 +00009161 WAIT_TYPE status;
9162 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009163
Victor Stinner8c62be82010-05-06 00:08:46 +00009164 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9165 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009166
Victor Stinner8c62be82010-05-06 00:08:46 +00009167 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009168}
9169#endif /* WEXITSTATUS */
9170
9171#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009172PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009173"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009174Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009175value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009176
9177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009178posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009179{
Victor Stinner8c62be82010-05-06 00:08:46 +00009180 WAIT_TYPE status;
9181 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009182
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9184 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009185
Victor Stinner8c62be82010-05-06 00:08:46 +00009186 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009187}
9188#endif /* WTERMSIG */
9189
9190#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009191PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009192"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009193Return the signal that stopped the process that provided\n\
9194the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009195
9196static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009197posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009198{
Victor Stinner8c62be82010-05-06 00:08:46 +00009199 WAIT_TYPE status;
9200 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009201
Victor Stinner8c62be82010-05-06 00:08:46 +00009202 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9203 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009204
Victor Stinner8c62be82010-05-06 00:08:46 +00009205 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009206}
9207#endif /* WSTOPSIG */
9208
9209#endif /* HAVE_SYS_WAIT_H */
9210
9211
Thomas Wouters477c8d52006-05-27 19:21:47 +00009212#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009213#ifdef _SCO_DS
9214/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9215 needed definitions in sys/statvfs.h */
9216#define _SVID3
9217#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009218#include <sys/statvfs.h>
9219
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009220static PyObject*
9221_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009222 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9223 if (v == NULL)
9224 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009225
9226#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009227 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9228 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9229 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9230 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9231 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9232 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9233 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9234 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9235 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9236 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009237#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009238 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9239 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9240 PyStructSequence_SET_ITEM(v, 2,
9241 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9242 PyStructSequence_SET_ITEM(v, 3,
9243 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9244 PyStructSequence_SET_ITEM(v, 4,
9245 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9246 PyStructSequence_SET_ITEM(v, 5,
9247 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9248 PyStructSequence_SET_ITEM(v, 6,
9249 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9250 PyStructSequence_SET_ITEM(v, 7,
9251 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9252 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9253 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009254#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009255 if (PyErr_Occurred()) {
9256 Py_DECREF(v);
9257 return NULL;
9258 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009259
Victor Stinner8c62be82010-05-06 00:08:46 +00009260 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009261}
9262
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009263PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009264"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009265Perform an fstatvfs system call on the given fd.\n\
9266Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009267
9268static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009269posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009270{
Victor Stinner8c62be82010-05-06 00:08:46 +00009271 int fd, res;
9272 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009273
Victor Stinner8c62be82010-05-06 00:08:46 +00009274 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9275 return NULL;
9276 Py_BEGIN_ALLOW_THREADS
9277 res = fstatvfs(fd, &st);
9278 Py_END_ALLOW_THREADS
9279 if (res != 0)
9280 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009281
Victor Stinner8c62be82010-05-06 00:08:46 +00009282 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009283}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009284#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009285
9286
Thomas Wouters477c8d52006-05-27 19:21:47 +00009287#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009288#include <sys/statvfs.h>
9289
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009290PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009291"statvfs(path)\n\n\
9292Perform a statvfs system call on the given path.\n\
9293\n\
9294path may always be specified as a string.\n\
9295On some platforms, path may also be specified as an open file descriptor.\n\
9296 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009297
9298static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009299posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009300{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009301 static char *keywords[] = {"path", NULL};
9302 path_t path;
9303 int result;
9304 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009306
Larry Hastings9cf065c2012-06-22 16:30:09 -07009307 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009308 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009309#ifdef HAVE_FSTATVFS
9310 path.allow_fd = 1;
9311#endif
9312 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9313 path_converter, &path
9314 ))
9315 return NULL;
9316
9317 Py_BEGIN_ALLOW_THREADS
9318#ifdef HAVE_FSTATVFS
9319 if (path.fd != -1) {
9320#ifdef __APPLE__
9321 /* handle weak-linking on Mac OS X 10.3 */
9322 if (fstatvfs == NULL) {
9323 fd_specified("statvfs", path.fd);
9324 goto exit;
9325 }
9326#endif
9327 result = fstatvfs(path.fd, &st);
9328 }
9329 else
9330#endif
9331 result = statvfs(path.narrow, &st);
9332 Py_END_ALLOW_THREADS
9333
9334 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009335 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009336 goto exit;
9337 }
9338
9339 return_value = _pystatvfs_fromstructstatvfs(st);
9340
9341exit:
9342 path_cleanup(&path);
9343 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009344}
9345#endif /* HAVE_STATVFS */
9346
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009347#ifdef MS_WINDOWS
9348PyDoc_STRVAR(win32__getdiskusage__doc__,
9349"_getdiskusage(path) -> (total, free)\n\n\
9350Return disk usage statistics about the given path as (total, free) tuple.");
9351
9352static PyObject *
9353win32__getdiskusage(PyObject *self, PyObject *args)
9354{
9355 BOOL retval;
9356 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009357 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009358
Victor Stinner6139c1b2011-11-09 22:14:14 +01009359 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009360 return NULL;
9361
9362 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009363 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009364 Py_END_ALLOW_THREADS
9365 if (retval == 0)
9366 return PyErr_SetFromWindowsErr(0);
9367
9368 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9369}
9370#endif
9371
9372
Fred Drakec9680921999-12-13 16:37:25 +00009373/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9374 * It maps strings representing configuration variable names to
9375 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009376 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009377 * rarely-used constants. There are three separate tables that use
9378 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009379 *
9380 * This code is always included, even if none of the interfaces that
9381 * need it are included. The #if hackery needed to avoid it would be
9382 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009383 */
9384struct constdef {
9385 char *name;
9386 long value;
9387};
9388
Fred Drake12c6e2d1999-12-14 21:25:03 +00009389static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009390conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009391 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009392{
Christian Heimes217cfd12007-12-02 14:31:20 +00009393 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009394 *valuep = PyLong_AS_LONG(arg);
9395 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009396 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009397 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009398 /* look up the value in the table using a binary search */
9399 size_t lo = 0;
9400 size_t mid;
9401 size_t hi = tablesize;
9402 int cmp;
9403 const char *confname;
9404 if (!PyUnicode_Check(arg)) {
9405 PyErr_SetString(PyExc_TypeError,
9406 "configuration names must be strings or integers");
9407 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009408 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009409 confname = _PyUnicode_AsString(arg);
9410 if (confname == NULL)
9411 return 0;
9412 while (lo < hi) {
9413 mid = (lo + hi) / 2;
9414 cmp = strcmp(confname, table[mid].name);
9415 if (cmp < 0)
9416 hi = mid;
9417 else if (cmp > 0)
9418 lo = mid + 1;
9419 else {
9420 *valuep = table[mid].value;
9421 return 1;
9422 }
9423 }
9424 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9425 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009426 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009427}
9428
9429
9430#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9431static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009432#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009433 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009434#endif
9435#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009436 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009437#endif
Fred Drakec9680921999-12-13 16:37:25 +00009438#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009439 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009440#endif
9441#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009442 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009443#endif
9444#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009445 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009446#endif
9447#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009448 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009449#endif
9450#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009451 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009452#endif
9453#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009454 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009455#endif
9456#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009457 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009458#endif
9459#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009460 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009461#endif
9462#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009463 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009464#endif
9465#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009466 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009467#endif
9468#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009470#endif
9471#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009472 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009473#endif
9474#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009475 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009476#endif
9477#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009478 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009479#endif
9480#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009481 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009482#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009483#ifdef _PC_ACL_ENABLED
9484 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9485#endif
9486#ifdef _PC_MIN_HOLE_SIZE
9487 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9488#endif
9489#ifdef _PC_ALLOC_SIZE_MIN
9490 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9491#endif
9492#ifdef _PC_REC_INCR_XFER_SIZE
9493 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9494#endif
9495#ifdef _PC_REC_MAX_XFER_SIZE
9496 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9497#endif
9498#ifdef _PC_REC_MIN_XFER_SIZE
9499 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9500#endif
9501#ifdef _PC_REC_XFER_ALIGN
9502 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9503#endif
9504#ifdef _PC_SYMLINK_MAX
9505 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9506#endif
9507#ifdef _PC_XATTR_ENABLED
9508 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9509#endif
9510#ifdef _PC_XATTR_EXISTS
9511 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9512#endif
9513#ifdef _PC_TIMESTAMP_RESOLUTION
9514 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9515#endif
Fred Drakec9680921999-12-13 16:37:25 +00009516};
9517
Fred Drakec9680921999-12-13 16:37:25 +00009518static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009519conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009520{
9521 return conv_confname(arg, valuep, posix_constants_pathconf,
9522 sizeof(posix_constants_pathconf)
9523 / sizeof(struct constdef));
9524}
9525#endif
9526
9527#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009528PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009529"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009530Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009531If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009532
9533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009534posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009535{
9536 PyObject *result = NULL;
9537 int name, fd;
9538
Fred Drake12c6e2d1999-12-14 21:25:03 +00009539 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9540 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009541 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009542
Stefan Krah0e803b32010-11-26 16:16:47 +00009543 errno = 0;
9544 limit = fpathconf(fd, name);
9545 if (limit == -1 && errno != 0)
9546 posix_error();
9547 else
9548 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009549 }
9550 return result;
9551}
9552#endif
9553
9554
9555#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009556PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009557"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009558Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009559If there is no limit, return -1.\n\
9560On some platforms, path may also be specified as an open file descriptor.\n\
9561 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009562
9563static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009564posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009565{
Georg Brandl306336b2012-06-24 12:55:33 +02009566 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009567 PyObject *result = NULL;
9568 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009569 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009570
Georg Brandl306336b2012-06-24 12:55:33 +02009571 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009572 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009573#ifdef HAVE_FPATHCONF
9574 path.allow_fd = 1;
9575#endif
9576 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9577 path_converter, &path,
9578 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009580
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009582#ifdef HAVE_FPATHCONF
9583 if (path.fd != -1)
9584 limit = fpathconf(path.fd, name);
9585 else
9586#endif
9587 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 if (limit == -1 && errno != 0) {
9589 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009590 /* could be a path or name problem */
9591 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009592 else
Victor Stinner292c8352012-10-30 02:17:38 +01009593 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 }
9595 else
9596 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009597 }
Georg Brandl306336b2012-06-24 12:55:33 +02009598 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009599 return result;
9600}
9601#endif
9602
9603#ifdef HAVE_CONFSTR
9604static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009605#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009607#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009608#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009610#endif
9611#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009613#endif
Fred Draked86ed291999-12-15 15:34:33 +00009614#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009616#endif
9617#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009619#endif
9620#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009622#endif
9623#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009625#endif
Fred Drakec9680921999-12-13 16:37:25 +00009626#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009628#endif
9629#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009630 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009631#endif
9632#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009633 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009634#endif
9635#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009636 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009637#endif
9638#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009640#endif
9641#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009643#endif
9644#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009646#endif
9647#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009649#endif
Fred Draked86ed291999-12-15 15:34:33 +00009650#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009652#endif
Fred Drakec9680921999-12-13 16:37:25 +00009653#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009655#endif
Fred Draked86ed291999-12-15 15:34:33 +00009656#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009658#endif
9659#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009661#endif
9662#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009664#endif
9665#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009666 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009667#endif
Fred Drakec9680921999-12-13 16:37:25 +00009668#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009670#endif
9671#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009673#endif
9674#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009676#endif
9677#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009679#endif
9680#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009682#endif
9683#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009685#endif
9686#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009688#endif
9689#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009691#endif
9692#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009694#endif
9695#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009697#endif
9698#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009700#endif
9701#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009703#endif
9704#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009706#endif
9707#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009709#endif
9710#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009712#endif
9713#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009715#endif
Fred Draked86ed291999-12-15 15:34:33 +00009716#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009718#endif
9719#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009721#endif
9722#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009724#endif
9725#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009727#endif
9728#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009730#endif
9731#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009733#endif
9734#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009736#endif
9737#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009739#endif
9740#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009742#endif
9743#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009745#endif
9746#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009748#endif
9749#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009751#endif
9752#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009754#endif
Fred Drakec9680921999-12-13 16:37:25 +00009755};
9756
9757static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009758conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009759{
9760 return conv_confname(arg, valuep, posix_constants_confstr,
9761 sizeof(posix_constants_confstr)
9762 / sizeof(struct constdef));
9763}
9764
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009765PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009766"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009767Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009768
9769static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009770posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009771{
9772 PyObject *result = NULL;
9773 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009774 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009775 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009776
Victor Stinnercb043522010-09-10 23:49:04 +00009777 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9778 return NULL;
9779
9780 errno = 0;
9781 len = confstr(name, buffer, sizeof(buffer));
9782 if (len == 0) {
9783 if (errno) {
9784 posix_error();
9785 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009786 }
9787 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009788 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009789 }
9790 }
Victor Stinnercb043522010-09-10 23:49:04 +00009791
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009792 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009793 char *buf = PyMem_Malloc(len);
9794 if (buf == NULL)
9795 return PyErr_NoMemory();
9796 confstr(name, buf, len);
9797 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9798 PyMem_Free(buf);
9799 }
9800 else
9801 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009802 return result;
9803}
9804#endif
9805
9806
9807#ifdef HAVE_SYSCONF
9808static struct constdef posix_constants_sysconf[] = {
9809#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
Fred Draked86ed291999-12-15 15:34:33 +00009839#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009841#endif
9842#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009844#endif
Fred Drakec9680921999-12-13 16:37:25 +00009845#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
Fred Drakec9680921999-12-13 16:37:25 +00009848#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
Fred Draked86ed291999-12-15 15:34:33 +00009863#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009865#endif
Fred Drakec9680921999-12-13 16:37:25 +00009866#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
9872#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
Fred Draked86ed291999-12-15 15:34:33 +00009881#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009883#endif
Fred Drakec9680921999-12-13 16:37:25 +00009884#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
9887#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
9890#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
9893#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
9908#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
Fred Draked86ed291999-12-15 15:34:33 +00009953#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009955#endif
Fred Drakec9680921999-12-13 16:37:25 +00009956#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
Fred Draked86ed291999-12-15 15:34:33 +00009965#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009967#endif
Fred Drakec9680921999-12-13 16:37:25 +00009968#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
Fred Draked86ed291999-12-15 15:34:33 +00009971#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009973#endif
9974#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009976#endif
Fred Drakec9680921999-12-13 16:37:25 +00009977#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
Fred Draked86ed291999-12-15 15:34:33 +00009989#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009991#endif
Fred Drakec9680921999-12-13 16:37:25 +00009992#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
Fred Draked86ed291999-12-15 15:34:33 +000010013#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010015#endif
Fred Drakec9680921999-12-13 16:37:25 +000010016#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
Fred Draked86ed291999-12-15 15:34:33 +000010022#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010024#endif
Fred Drakec9680921999-12-13 16:37:25 +000010025#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
Fred Draked86ed291999-12-15 15:34:33 +000010052#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010054#endif
10055#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010057#endif
Fred Drakec9680921999-12-13 16:37:25 +000010058#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
Fred Draked86ed291999-12-15 15:34:33 +000010163#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010165#endif
Fred Drakec9680921999-12-13 16:37:25 +000010166#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
10259#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
10262#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
10265#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
10268#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
10271#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010273#endif
10274#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
10277#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010279#endif
10280#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010282#endif
10283#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010285#endif
10286#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
10289#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010291#endif
10292#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010294#endif
10295#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301};
10302
10303static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010304conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010305{
10306 return conv_confname(arg, valuep, posix_constants_sysconf,
10307 sizeof(posix_constants_sysconf)
10308 / sizeof(struct constdef));
10309}
10310
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010311PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010312"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010313Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010314
10315static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010316posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010317{
10318 PyObject *result = NULL;
10319 int name;
10320
10321 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +020010322 long value;
Fred Drakec9680921999-12-13 16:37:25 +000010323
10324 errno = 0;
10325 value = sysconf(name);
10326 if (value == -1 && errno != 0)
10327 posix_error();
10328 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010329 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010330 }
10331 return result;
10332}
10333#endif
10334
10335
Fred Drakebec628d1999-12-15 18:31:10 +000010336/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010337 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010338 * the exported dictionaries that are used to publish information about the
10339 * names available on the host platform.
10340 *
10341 * Sorting the table at runtime ensures that the table is properly ordered
10342 * when used, even for platforms we're not able to test on. It also makes
10343 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010344 */
Fred Drakebec628d1999-12-15 18:31:10 +000010345
10346static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010347cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010348{
10349 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010351 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010353
10354 return strcmp(c1->name, c2->name);
10355}
10356
10357static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010358setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010360{
Fred Drakebec628d1999-12-15 18:31:10 +000010361 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010362 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010363
10364 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10365 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010366 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010368
Barry Warsaw3155db32000-04-13 15:20:40 +000010369 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 PyObject *o = PyLong_FromLong(table[i].value);
10371 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10372 Py_XDECREF(o);
10373 Py_DECREF(d);
10374 return -1;
10375 }
10376 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010377 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010378 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010379}
10380
Fred Drakebec628d1999-12-15 18:31:10 +000010381/* Return -1 on failure, 0 on success. */
10382static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010383setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010384{
10385#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010386 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010387 sizeof(posix_constants_pathconf)
10388 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010389 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010390 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010391#endif
10392#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010393 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010394 sizeof(posix_constants_confstr)
10395 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010396 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010397 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010398#endif
10399#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010400 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010401 sizeof(posix_constants_sysconf)
10402 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010403 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010404 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010405#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010406 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010407}
Fred Draked86ed291999-12-15 15:34:33 +000010408
10409
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010410PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010411"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010412Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010413in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010414
10415static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010416posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010417{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010418 abort();
10419 /*NOTREACHED*/
10420 Py_FatalError("abort() called from Python code didn't abort!");
10421 return NULL;
10422}
Fred Drakebec628d1999-12-15 18:31:10 +000010423
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010424#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010425PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010426"startfile(filepath [, operation]) - Start a file with its associated\n\
10427application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010428\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010429When \"operation\" is not specified or \"open\", this acts like\n\
10430double-clicking the file in Explorer, or giving the file name as an\n\
10431argument to the DOS \"start\" command: the file is opened with whatever\n\
10432application (if any) its extension is associated.\n\
10433When another \"operation\" is given, it specifies what should be done with\n\
10434the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010435\n\
10436startfile returns as soon as the associated application is launched.\n\
10437There is no option to wait for the application to close, and no way\n\
10438to retrieve the application's exit status.\n\
10439\n\
10440The filepath is relative to the current directory. If you want to use\n\
10441an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010442the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010443
10444static PyObject *
10445win32_startfile(PyObject *self, PyObject *args)
10446{
Victor Stinner8c62be82010-05-06 00:08:46 +000010447 PyObject *ofilepath;
10448 char *filepath;
10449 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010450 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010452
Victor Stinnereb5657a2011-09-30 01:44:27 +020010453 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 if (!PyArg_ParseTuple(args, "U|s:startfile",
10455 &unipath, &operation)) {
10456 PyErr_Clear();
10457 goto normal;
10458 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010459
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010461 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010462 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010463 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 PyErr_Clear();
10465 operation = NULL;
10466 goto normal;
10467 }
10468 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010469
Victor Stinnereb5657a2011-09-30 01:44:27 +020010470 wpath = PyUnicode_AsUnicode(unipath);
10471 if (wpath == NULL)
10472 goto normal;
10473 if (uoperation) {
10474 woperation = PyUnicode_AsUnicode(uoperation);
10475 if (woperation == NULL)
10476 goto normal;
10477 }
10478 else
10479 woperation = NULL;
10480
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010482 rc = ShellExecuteW((HWND)0, woperation, wpath,
10483 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 Py_END_ALLOW_THREADS
10485
Victor Stinnereb5657a2011-09-30 01:44:27 +020010486 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010488 win32_error_object("startfile", unipath);
10489 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 }
10491 Py_INCREF(Py_None);
10492 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010493
10494normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010495 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10496 PyUnicode_FSConverter, &ofilepath,
10497 &operation))
10498 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010499 if (win32_warn_bytes_api()) {
10500 Py_DECREF(ofilepath);
10501 return NULL;
10502 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 filepath = PyBytes_AsString(ofilepath);
10504 Py_BEGIN_ALLOW_THREADS
10505 rc = ShellExecute((HWND)0, operation, filepath,
10506 NULL, NULL, SW_SHOWNORMAL);
10507 Py_END_ALLOW_THREADS
10508 if (rc <= (HINSTANCE)32) {
10509 PyObject *errval = win32_error("startfile", filepath);
10510 Py_DECREF(ofilepath);
10511 return errval;
10512 }
10513 Py_DECREF(ofilepath);
10514 Py_INCREF(Py_None);
10515 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010516}
10517#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010518
Martin v. Löwis438b5342002-12-27 10:16:42 +000010519#ifdef HAVE_GETLOADAVG
10520PyDoc_STRVAR(posix_getloadavg__doc__,
10521"getloadavg() -> (float, float, float)\n\n\
10522Return the number of processes in the system run queue averaged over\n\
10523the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10524was unobtainable");
10525
10526static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010527posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010528{
10529 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010530 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010531 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10532 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010533 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010534 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010535}
10536#endif
10537
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010538PyDoc_STRVAR(device_encoding__doc__,
10539"device_encoding(fd) -> str\n\n\
10540Return a string describing the encoding of the device\n\
10541if the output is a terminal; else return None.");
10542
10543static PyObject *
10544device_encoding(PyObject *self, PyObject *args)
10545{
Victor Stinner8c62be82010-05-06 00:08:46 +000010546 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010547
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10549 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010550
10551 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010552}
10553
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010554#ifdef HAVE_SETRESUID
10555PyDoc_STRVAR(posix_setresuid__doc__,
10556"setresuid(ruid, euid, suid)\n\n\
10557Set the current process's real, effective, and saved user ids.");
10558
10559static PyObject*
10560posix_setresuid (PyObject *self, PyObject *args)
10561{
Victor Stinner8c62be82010-05-06 00:08:46 +000010562 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010563 uid_t ruid, euid, suid;
10564 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10565 _Py_Uid_Converter, &ruid,
10566 _Py_Uid_Converter, &euid,
10567 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 return NULL;
10569 if (setresuid(ruid, euid, suid) < 0)
10570 return posix_error();
10571 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010572}
10573#endif
10574
10575#ifdef HAVE_SETRESGID
10576PyDoc_STRVAR(posix_setresgid__doc__,
10577"setresgid(rgid, egid, sgid)\n\n\
10578Set the current process's real, effective, and saved group ids.");
10579
10580static PyObject*
10581posix_setresgid (PyObject *self, PyObject *args)
10582{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010583 gid_t rgid, egid, sgid;
10584 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10585 _Py_Gid_Converter, &rgid,
10586 _Py_Gid_Converter, &egid,
10587 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010588 return NULL;
10589 if (setresgid(rgid, egid, sgid) < 0)
10590 return posix_error();
10591 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010592}
10593#endif
10594
10595#ifdef HAVE_GETRESUID
10596PyDoc_STRVAR(posix_getresuid__doc__,
10597"getresuid() -> (ruid, euid, suid)\n\n\
10598Get tuple of the current process's real, effective, and saved user ids.");
10599
10600static PyObject*
10601posix_getresuid (PyObject *self, PyObject *noargs)
10602{
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 if (getresuid(&ruid, &euid, &suid) < 0)
10605 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010606 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10607 _PyLong_FromUid(euid),
10608 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010609}
10610#endif
10611
10612#ifdef HAVE_GETRESGID
10613PyDoc_STRVAR(posix_getresgid__doc__,
10614"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010615Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010616
10617static PyObject*
10618posix_getresgid (PyObject *self, PyObject *noargs)
10619{
Victor Stinner8c62be82010-05-06 00:08:46 +000010620 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010621 if (getresgid(&rgid, &egid, &sgid) < 0)
10622 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010623 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10624 _PyLong_FromGid(egid),
10625 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010626}
10627#endif
10628
Benjamin Peterson9428d532011-09-14 11:45:52 -040010629#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010630
Benjamin Peterson799bd802011-08-31 22:15:17 -040010631PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010632"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10633Return the value of extended attribute attribute on path.\n\
10634\n\
10635path may be either a string or an open file descriptor.\n\
10636If follow_symlinks is False, and the last element of the path is a symbolic\n\
10637 link, getxattr will examine the symbolic link itself instead of the file\n\
10638 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010639
10640static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010641posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010642{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010643 path_t path;
10644 path_t attribute;
10645 int follow_symlinks = 1;
10646 PyObject *buffer = NULL;
10647 int i;
10648 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010649
Larry Hastings9cf065c2012-06-22 16:30:09 -070010650 memset(&path, 0, sizeof(path));
10651 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010652 path.function_name = "getxattr";
10653 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010654 path.allow_fd = 1;
10655 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10656 path_converter, &path,
10657 path_converter, &attribute,
10658 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010659 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010660
Larry Hastings9cf065c2012-06-22 16:30:09 -070010661 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10662 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010663
Larry Hastings9cf065c2012-06-22 16:30:09 -070010664 for (i = 0; ; i++) {
10665 void *ptr;
10666 ssize_t result;
10667 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10668 Py_ssize_t buffer_size = buffer_sizes[i];
10669 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010670 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010671 goto exit;
10672 }
10673 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10674 if (!buffer)
10675 goto exit;
10676 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010677
Larry Hastings9cf065c2012-06-22 16:30:09 -070010678 Py_BEGIN_ALLOW_THREADS;
10679 if (path.fd >= 0)
10680 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10681 else if (follow_symlinks)
10682 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10683 else
10684 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10685 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010686
Larry Hastings9cf065c2012-06-22 16:30:09 -070010687 if (result < 0) {
10688 Py_DECREF(buffer);
10689 buffer = NULL;
10690 if (errno == ERANGE)
10691 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010692 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010693 goto exit;
10694 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010695
Larry Hastings9cf065c2012-06-22 16:30:09 -070010696 if (result != buffer_size) {
10697 /* Can only shrink. */
10698 _PyBytes_Resize(&buffer, result);
10699 }
10700 break;
10701 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010702
Larry Hastings9cf065c2012-06-22 16:30:09 -070010703exit:
10704 path_cleanup(&path);
10705 path_cleanup(&attribute);
10706 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010707}
10708
10709PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010710"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10711Set extended attribute attribute on path to value.\n\
10712path may be either a string or an open file descriptor.\n\
10713If follow_symlinks is False, and the last element of the path is a symbolic\n\
10714 link, setxattr will modify the symbolic link itself instead of the file\n\
10715 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010716
10717static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010718posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010719{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010720 path_t path;
10721 path_t attribute;
10722 Py_buffer value;
10723 int flags = 0;
10724 int follow_symlinks = 1;
10725 int result;
10726 PyObject *return_value = NULL;
10727 static char *keywords[] = {"path", "attribute", "value",
10728 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010729
Larry Hastings9cf065c2012-06-22 16:30:09 -070010730 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010731 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010732 path.allow_fd = 1;
10733 memset(&attribute, 0, sizeof(attribute));
10734 memset(&value, 0, sizeof(value));
10735 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10736 keywords,
10737 path_converter, &path,
10738 path_converter, &attribute,
10739 &value, &flags,
10740 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010741 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010742
10743 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10744 goto exit;
10745
Benjamin Peterson799bd802011-08-31 22:15:17 -040010746 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010747 if (path.fd > -1)
10748 result = fsetxattr(path.fd, attribute.narrow,
10749 value.buf, value.len, flags);
10750 else if (follow_symlinks)
10751 result = setxattr(path.narrow, attribute.narrow,
10752 value.buf, value.len, flags);
10753 else
10754 result = lsetxattr(path.narrow, attribute.narrow,
10755 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010756 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010757
Larry Hastings9cf065c2012-06-22 16:30:09 -070010758 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010759 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010760 goto exit;
10761 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010762
Larry Hastings9cf065c2012-06-22 16:30:09 -070010763 return_value = Py_None;
10764 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010765
Larry Hastings9cf065c2012-06-22 16:30:09 -070010766exit:
10767 path_cleanup(&path);
10768 path_cleanup(&attribute);
10769 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010770
Larry Hastings9cf065c2012-06-22 16:30:09 -070010771 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010772}
10773
10774PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010775"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10776Remove extended attribute attribute on path.\n\
10777path may be either a string or an open file descriptor.\n\
10778If follow_symlinks is False, and the last element of the path is a symbolic\n\
10779 link, removexattr will modify the symbolic link itself instead of the file\n\
10780 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010781
10782static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010783posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010784{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010785 path_t path;
10786 path_t attribute;
10787 int follow_symlinks = 1;
10788 int result;
10789 PyObject *return_value = NULL;
10790 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010791
Larry Hastings9cf065c2012-06-22 16:30:09 -070010792 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010793 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010794 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010795 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010796 path.allow_fd = 1;
10797 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10798 keywords,
10799 path_converter, &path,
10800 path_converter, &attribute,
10801 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010802 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010803
10804 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10805 goto exit;
10806
Benjamin Peterson799bd802011-08-31 22:15:17 -040010807 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010808 if (path.fd > -1)
10809 result = fremovexattr(path.fd, attribute.narrow);
10810 else if (follow_symlinks)
10811 result = removexattr(path.narrow, attribute.narrow);
10812 else
10813 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010814 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010815
Larry Hastings9cf065c2012-06-22 16:30:09 -070010816 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010817 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010818 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010819 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010820
Larry Hastings9cf065c2012-06-22 16:30:09 -070010821 return_value = Py_None;
10822 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010823
Larry Hastings9cf065c2012-06-22 16:30:09 -070010824exit:
10825 path_cleanup(&path);
10826 path_cleanup(&attribute);
10827
10828 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010829}
10830
10831PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010832"listxattr(path='.', *, follow_symlinks=True)\n\n\
10833Return a list of extended attributes on path.\n\
10834\n\
10835path may be either None, a string, or an open file descriptor.\n\
10836if path is None, listxattr will examine the current directory.\n\
10837If follow_symlinks is False, and the last element of the path is a symbolic\n\
10838 link, listxattr will examine the symbolic link itself instead of the file\n\
10839 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010840
10841static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010842posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010843{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010844 path_t path;
10845 int follow_symlinks = 1;
10846 Py_ssize_t i;
10847 PyObject *result = NULL;
10848 char *buffer = NULL;
10849 char *name;
10850 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010851
Larry Hastings9cf065c2012-06-22 16:30:09 -070010852 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010853 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010854 path.allow_fd = 1;
10855 path.fd = -1;
10856 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10857 path_converter, &path,
10858 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010859 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010860
Larry Hastings9cf065c2012-06-22 16:30:09 -070010861 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10862 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010863
Larry Hastings9cf065c2012-06-22 16:30:09 -070010864 name = path.narrow ? path.narrow : ".";
10865 for (i = 0; ; i++) {
10866 char *start, *trace, *end;
10867 ssize_t length;
10868 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10869 Py_ssize_t buffer_size = buffer_sizes[i];
10870 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010871 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010872 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010873 break;
10874 }
10875 buffer = PyMem_MALLOC(buffer_size);
10876 if (!buffer) {
10877 PyErr_NoMemory();
10878 break;
10879 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010880
Larry Hastings9cf065c2012-06-22 16:30:09 -070010881 Py_BEGIN_ALLOW_THREADS;
10882 if (path.fd > -1)
10883 length = flistxattr(path.fd, buffer, buffer_size);
10884 else if (follow_symlinks)
10885 length = listxattr(name, buffer, buffer_size);
10886 else
10887 length = llistxattr(name, buffer, buffer_size);
10888 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010889
Larry Hastings9cf065c2012-06-22 16:30:09 -070010890 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010891 if (errno == ERANGE) {
10892 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010893 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010894 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010895 }
Victor Stinner292c8352012-10-30 02:17:38 +010010896 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010897 break;
10898 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010899
Larry Hastings9cf065c2012-06-22 16:30:09 -070010900 result = PyList_New(0);
10901 if (!result) {
10902 goto exit;
10903 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010904
Larry Hastings9cf065c2012-06-22 16:30:09 -070010905 end = buffer + length;
10906 for (trace = start = buffer; trace != end; trace++) {
10907 if (!*trace) {
10908 int error;
10909 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10910 trace - start);
10911 if (!attribute) {
10912 Py_DECREF(result);
10913 result = NULL;
10914 goto exit;
10915 }
10916 error = PyList_Append(result, attribute);
10917 Py_DECREF(attribute);
10918 if (error) {
10919 Py_DECREF(result);
10920 result = NULL;
10921 goto exit;
10922 }
10923 start = trace + 1;
10924 }
10925 }
10926 break;
10927 }
10928exit:
10929 path_cleanup(&path);
10930 if (buffer)
10931 PyMem_FREE(buffer);
10932 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010933}
10934
Benjamin Peterson9428d532011-09-14 11:45:52 -040010935#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010936
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010937
Georg Brandl2fb477c2012-02-21 00:33:36 +010010938PyDoc_STRVAR(posix_urandom__doc__,
10939"urandom(n) -> str\n\n\
10940Return n random bytes suitable for cryptographic use.");
10941
10942static PyObject *
10943posix_urandom(PyObject *self, PyObject *args)
10944{
10945 Py_ssize_t size;
10946 PyObject *result;
10947 int ret;
10948
10949 /* Read arguments */
10950 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10951 return NULL;
10952 if (size < 0)
10953 return PyErr_Format(PyExc_ValueError,
10954 "negative argument not allowed");
10955 result = PyBytes_FromStringAndSize(NULL, size);
10956 if (result == NULL)
10957 return NULL;
10958
10959 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10960 PyBytes_GET_SIZE(result));
10961 if (ret == -1) {
10962 Py_DECREF(result);
10963 return NULL;
10964 }
10965 return result;
10966}
10967
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010968/* Terminal size querying */
10969
10970static PyTypeObject TerminalSizeType;
10971
10972PyDoc_STRVAR(TerminalSize_docstring,
10973 "A tuple of (columns, lines) for holding terminal window size");
10974
10975static PyStructSequence_Field TerminalSize_fields[] = {
10976 {"columns", "width of the terminal window in characters"},
10977 {"lines", "height of the terminal window in characters"},
10978 {NULL, NULL}
10979};
10980
10981static PyStructSequence_Desc TerminalSize_desc = {
10982 "os.terminal_size",
10983 TerminalSize_docstring,
10984 TerminalSize_fields,
10985 2,
10986};
10987
10988#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10989PyDoc_STRVAR(termsize__doc__,
10990 "Return the size of the terminal window as (columns, lines).\n" \
10991 "\n" \
10992 "The optional argument fd (default standard output) specifies\n" \
10993 "which file descriptor should be queried.\n" \
10994 "\n" \
10995 "If the file descriptor is not connected to a terminal, an OSError\n" \
10996 "is thrown.\n" \
10997 "\n" \
10998 "This function will only be defined if an implementation is\n" \
10999 "available for this system.\n" \
11000 "\n" \
11001 "shutil.get_terminal_size is the high-level function which should \n" \
11002 "normally be used, os.get_terminal_size is the low-level implementation.");
11003
11004static PyObject*
11005get_terminal_size(PyObject *self, PyObject *args)
11006{
11007 int columns, lines;
11008 PyObject *termsize;
11009
11010 int fd = fileno(stdout);
11011 /* Under some conditions stdout may not be connected and
11012 * fileno(stdout) may point to an invalid file descriptor. For example
11013 * GUI apps don't have valid standard streams by default.
11014 *
11015 * If this happens, and the optional fd argument is not present,
11016 * the ioctl below will fail returning EBADF. This is what we want.
11017 */
11018
11019 if (!PyArg_ParseTuple(args, "|i", &fd))
11020 return NULL;
11021
11022#ifdef TERMSIZE_USE_IOCTL
11023 {
11024 struct winsize w;
11025 if (ioctl(fd, TIOCGWINSZ, &w))
11026 return PyErr_SetFromErrno(PyExc_OSError);
11027 columns = w.ws_col;
11028 lines = w.ws_row;
11029 }
11030#endif /* TERMSIZE_USE_IOCTL */
11031
11032#ifdef TERMSIZE_USE_CONIO
11033 {
11034 DWORD nhandle;
11035 HANDLE handle;
11036 CONSOLE_SCREEN_BUFFER_INFO csbi;
11037 switch (fd) {
11038 case 0: nhandle = STD_INPUT_HANDLE;
11039 break;
11040 case 1: nhandle = STD_OUTPUT_HANDLE;
11041 break;
11042 case 2: nhandle = STD_ERROR_HANDLE;
11043 break;
11044 default:
11045 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11046 }
11047 handle = GetStdHandle(nhandle);
11048 if (handle == NULL)
11049 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11050 if (handle == INVALID_HANDLE_VALUE)
11051 return PyErr_SetFromWindowsErr(0);
11052
11053 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11054 return PyErr_SetFromWindowsErr(0);
11055
11056 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11057 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11058 }
11059#endif /* TERMSIZE_USE_CONIO */
11060
11061 termsize = PyStructSequence_New(&TerminalSizeType);
11062 if (termsize == NULL)
11063 return NULL;
11064 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11065 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11066 if (PyErr_Occurred()) {
11067 Py_DECREF(termsize);
11068 return NULL;
11069 }
11070 return termsize;
11071}
11072#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11073
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011074PyDoc_STRVAR(posix_cpu_count__doc__,
11075"cpu_count() -> integer\n\n\
11076Return the number of CPUs in the system, or None if this value cannot be\n\
11077established.");
11078
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011079static PyObject *
11080posix_cpu_count(PyObject *self)
11081{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011082 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011083#ifdef MS_WINDOWS
11084 SYSTEM_INFO sysinfo;
11085 GetSystemInfo(&sysinfo);
11086 ncpu = sysinfo.dwNumberOfProcessors;
11087#elif defined(__hpux)
11088 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11089#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11090 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011091#elif defined(__DragonFly__) || \
11092 defined(__OpenBSD__) || \
11093 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011094 defined(__NetBSD__) || \
11095 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011096 int mib[2];
11097 size_t len = sizeof(ncpu);
11098 mib[0] = CTL_HW;
11099 mib[1] = HW_NCPU;
11100 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11101 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011102#endif
11103 if (ncpu >= 1)
11104 return PyLong_FromLong(ncpu);
11105 else
11106 Py_RETURN_NONE;
11107}
11108
Victor Stinnerdaf45552013-08-28 00:53:59 +020011109PyDoc_STRVAR(get_inheritable__doc__,
11110 "get_inheritable(fd) -> bool\n" \
11111 "\n" \
11112 "Get the close-on-exe flag of the specified file descriptor.");
11113
11114static PyObject*
11115posix_get_inheritable(PyObject *self, PyObject *args)
11116{
11117 int fd;
11118 int inheritable;
11119
11120 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd))
11121 return NULL;
11122
11123 if (!_PyVerify_fd(fd))
11124 return posix_error();
11125
11126 inheritable = _Py_get_inheritable(fd);
11127 if (inheritable < 0)
11128 return NULL;
11129 return PyBool_FromLong(inheritable);
11130}
11131
11132PyDoc_STRVAR(set_inheritable__doc__,
11133 "set_inheritable(fd, inheritable)\n" \
11134 "\n" \
11135 "Set the inheritable flag of the specified file descriptor.");
11136
11137static PyObject*
11138posix_set_inheritable(PyObject *self, PyObject *args)
11139{
11140 int fd, inheritable;
11141
11142 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable))
11143 return NULL;
11144
11145 if (!_PyVerify_fd(fd))
11146 return posix_error();
11147
11148 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
11149 return NULL;
11150 Py_RETURN_NONE;
11151}
11152
11153
11154#ifdef MS_WINDOWS
11155PyDoc_STRVAR(get_handle_inheritable__doc__,
11156 "get_handle_inheritable(fd) -> bool\n" \
11157 "\n" \
11158 "Get the close-on-exe flag of the specified file descriptor.");
11159
11160static PyObject*
11161posix_get_handle_inheritable(PyObject *self, PyObject *args)
11162{
11163 Py_intptr_t handle;
11164 DWORD flags;
11165
11166 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle))
11167 return NULL;
11168
11169 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11170 PyErr_SetFromWindowsErr(0);
11171 return NULL;
11172 }
11173
11174 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT);
11175}
11176
11177PyDoc_STRVAR(set_handle_inheritable__doc__,
11178 "set_handle_inheritable(fd, inheritable)\n" \
11179 "\n" \
11180 "Set the inheritable flag of the specified handle.");
11181
11182static PyObject*
11183posix_set_handle_inheritable(PyObject *self, PyObject *args)
11184{
11185 int inheritable = 1;
11186 Py_intptr_t handle;
11187 DWORD flags;
11188
11189 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable",
11190 &handle, &inheritable))
11191 return NULL;
11192
11193 if (inheritable)
11194 flags = HANDLE_FLAG_INHERIT;
11195 else
11196 flags = 0;
11197 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11198 PyErr_SetFromWindowsErr(0);
11199 return NULL;
11200 }
11201 Py_RETURN_NONE;
11202}
11203#endif /* MS_WINDOWS */
11204
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011205
Larry Hastings7726ac92014-01-31 22:03:12 -080011206/*[clinic input]
11207dump buffer
11208[clinic start generated code]*/
11209
11210#ifndef OS_TTYNAME_METHODDEF
11211 #define OS_TTYNAME_METHODDEF
11212#endif /* !defined(OS_TTYNAME_METHODDEF) */
11213/*[clinic end generated code: output=5d071bbc8f49ea12 input=524ce2e021e4eba6]*/
11214
Larry Hastings31826802013-10-19 00:09:25 -070011215
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011216static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070011217
11218 OS_STAT_METHODDEF
11219 OS_ACCESS_METHODDEF
11220 OS_TTYNAME_METHODDEF
11221
Larry Hastings9cf065c2012-06-22 16:30:09 -070011222 {"chdir", (PyCFunction)posix_chdir,
11223 METH_VARARGS | METH_KEYWORDS,
11224 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011225#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011226 {"chflags", (PyCFunction)posix_chflags,
11227 METH_VARARGS | METH_KEYWORDS,
11228 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011229#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011230 {"chmod", (PyCFunction)posix_chmod,
11231 METH_VARARGS | METH_KEYWORDS,
11232 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011233#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011234 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011235#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011236#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070011237 {"chown", (PyCFunction)posix_chown,
11238 METH_VARARGS | METH_KEYWORDS,
11239 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011240#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000011241#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011242 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011243#endif /* HAVE_LCHMOD */
11244#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011245 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011246#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000011247#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011248 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011249#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011250#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011252#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000011253#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000011254 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000011255#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011256#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000011257 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011258#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 {"getcwd", (PyCFunction)posix_getcwd_unicode,
11260 METH_NOARGS, posix_getcwd__doc__},
11261 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
11262 METH_NOARGS, posix_getcwdb__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011263#if defined(HAVE_LINK) || defined(MS_WINDOWS)
11264 {"link", (PyCFunction)posix_link,
11265 METH_VARARGS | METH_KEYWORDS,
11266 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011267#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011268 {"listdir", (PyCFunction)posix_listdir,
11269 METH_VARARGS | METH_KEYWORDS,
11270 posix_listdir__doc__},
11271 {"lstat", (PyCFunction)posix_lstat,
11272 METH_VARARGS | METH_KEYWORDS,
11273 posix_lstat__doc__},
11274 {"mkdir", (PyCFunction)posix_mkdir,
11275 METH_VARARGS | METH_KEYWORDS,
11276 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011277#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011278 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011279#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011280#ifdef HAVE_GETPRIORITY
11281 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11282#endif /* HAVE_GETPRIORITY */
11283#ifdef HAVE_SETPRIORITY
11284 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11285#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011286#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011287 {"readlink", (PyCFunction)posix_readlink,
11288 METH_VARARGS | METH_KEYWORDS,
11289 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011290#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011291#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011292 {"readlink", (PyCFunction)win_readlink,
11293 METH_VARARGS | METH_KEYWORDS,
11294 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011295#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011296 {"rename", (PyCFunction)posix_rename,
11297 METH_VARARGS | METH_KEYWORDS,
11298 posix_rename__doc__},
11299 {"replace", (PyCFunction)posix_replace,
11300 METH_VARARGS | METH_KEYWORDS,
11301 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011302 {"rmdir", (PyCFunction)posix_rmdir,
11303 METH_VARARGS | METH_KEYWORDS,
11304 posix_rmdir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011306#if defined(HAVE_SYMLINK)
11307 {"symlink", (PyCFunction)posix_symlink,
11308 METH_VARARGS | METH_KEYWORDS,
11309 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011310#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011311#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011313#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011314 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011315#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011317#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011318 {"unlink", (PyCFunction)posix_unlink,
11319 METH_VARARGS | METH_KEYWORDS,
11320 posix_unlink__doc__},
11321 {"remove", (PyCFunction)posix_unlink,
11322 METH_VARARGS | METH_KEYWORDS,
11323 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011324 {"utime", (PyCFunction)posix_utime,
11325 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011326#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011327 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011328#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011329 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011330#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011331 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011332 {"execve", (PyCFunction)posix_execve,
11333 METH_VARARGS | METH_KEYWORDS,
11334 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011335#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011336#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11338 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000011339#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011340#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011341 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011342#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011343#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011344 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011345#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011346#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011347#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011348 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11349 {"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 +020011350#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011351#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011352 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011353#endif
11354#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011355 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011356#endif
11357#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011358 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011359#endif
11360#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011361 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011362#endif
11363#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011364 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011365#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011366 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011367#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011368 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11369 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11370#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011371#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011372#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011373 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011374#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011375#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011376 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011377#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011378#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011379 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011380#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011381#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011382 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011383#endif /* HAVE_GETEUID */
11384#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011386#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011387#ifdef HAVE_GETGROUPLIST
11388 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11389#endif
Fred Drakec9680921999-12-13 16:37:25 +000011390#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011392#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011394#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011395 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011396#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011397#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011398 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011399#endif /* HAVE_GETPPID */
11400#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011401 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011402#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011403#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011404 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011405#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011406#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011407 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011408#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011409#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011410 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011411#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011412#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011413 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011414#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011415#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011416 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11417 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011418#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011419#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011420 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011421#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011422#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011424#endif /* HAVE_SETEUID */
11425#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011426 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011427#endif /* HAVE_SETEGID */
11428#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011429 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011430#endif /* HAVE_SETREUID */
11431#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011432 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011433#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011434#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011435 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011436#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011437#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011438 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011439#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011440#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011442#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011443#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011445#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011446#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011447 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011448#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011449#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011450 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011451#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011452#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011453 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011454#endif /* HAVE_WAIT3 */
11455#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011456 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011457#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011458#if defined(HAVE_WAITID) && !defined(__APPLE__)
11459 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11460#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011461#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011462 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011463#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011464#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011466#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011467#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011468 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011469#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011470#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011471 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011472#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011473#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011474 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011475#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011476#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011477 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011478#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011479 {"open", (PyCFunction)posix_open,\
11480 METH_VARARGS | METH_KEYWORDS,
11481 posix_open__doc__},
Benjamin Peterson932bba32014-02-11 10:16:16 -050011482 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11484 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11485 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011486 {"dup2", (PyCFunction)posix_dup2,
11487 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011488#ifdef HAVE_LOCKF
11489 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11490#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011491 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11492 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011493#ifdef HAVE_READV
11494 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11495#endif
11496#ifdef HAVE_PREAD
11497 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11498#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011499 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011500#ifdef HAVE_WRITEV
11501 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11502#endif
11503#ifdef HAVE_PWRITE
11504 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11505#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011506#ifdef HAVE_SENDFILE
11507 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11508 posix_sendfile__doc__},
11509#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011510 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011511 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011512#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011513 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011514#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011515#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011516 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011517#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011518#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011519 {"mkfifo", (PyCFunction)posix_mkfifo,
11520 METH_VARARGS | METH_KEYWORDS,
11521 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011522#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011523#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011524 {"mknod", (PyCFunction)posix_mknod,
11525 METH_VARARGS | METH_KEYWORDS,
11526 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011527#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011528#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011529 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11530 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11531 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011532#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011533#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011534 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011535#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011536#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011537 {"truncate", (PyCFunction)posix_truncate,
11538 METH_VARARGS | METH_KEYWORDS,
11539 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011540#endif
Victor Stinnerd6b17692014-09-30 12:20:05 +020011541#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011542 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11543#endif
Victor Stinnerd6b17692014-09-30 12:20:05 +020011544#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011545 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11546#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011547#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011549#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011550#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011551 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011552#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011553 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011554#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011556#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011557#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011559#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011560#ifdef HAVE_SYNC
11561 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11562#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011563#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011564 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011565#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011566#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011567#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011568 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011569#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011570#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011571 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011572#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011573#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011574 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011575#endif /* WIFSTOPPED */
11576#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011577 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011578#endif /* WIFSIGNALED */
11579#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011580 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011581#endif /* WIFEXITED */
11582#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011583 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011584#endif /* WEXITSTATUS */
11585#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011586 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011587#endif /* WTERMSIG */
11588#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011589 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011590#endif /* WSTOPSIG */
11591#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011592#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011593 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011594#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011595#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011596 {"statvfs", (PyCFunction)posix_statvfs,
11597 METH_VARARGS | METH_KEYWORDS,
11598 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011599#endif
Fred Drakec9680921999-12-13 16:37:25 +000011600#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011601 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011602#endif
11603#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011604 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011605#endif
11606#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011607 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011608#endif
11609#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011610 {"pathconf", (PyCFunction)posix_pathconf,
11611 METH_VARARGS | METH_KEYWORDS,
11612 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011613#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011614 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011615#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011616 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011617 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011618 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011619 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011620 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011621#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011622#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011623 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011624#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011625 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011626#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011627 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011628#endif
11629#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011630 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011631#endif
11632#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011633 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011634#endif
11635#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011636 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011637#endif
11638
Benjamin Peterson9428d532011-09-14 11:45:52 -040011639#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011640 {"setxattr", (PyCFunction)posix_setxattr,
11641 METH_VARARGS | METH_KEYWORDS,
11642 posix_setxattr__doc__},
11643 {"getxattr", (PyCFunction)posix_getxattr,
11644 METH_VARARGS | METH_KEYWORDS,
11645 posix_getxattr__doc__},
11646 {"removexattr", (PyCFunction)posix_removexattr,
11647 METH_VARARGS | METH_KEYWORDS,
11648 posix_removexattr__doc__},
11649 {"listxattr", (PyCFunction)posix_listxattr,
11650 METH_VARARGS | METH_KEYWORDS,
11651 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011652#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011653#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11654 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11655#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011656 {"cpu_count", (PyCFunction)posix_cpu_count,
11657 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011658 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__},
11659 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__},
11660#ifdef MS_WINDOWS
11661 {"get_handle_inheritable", posix_get_handle_inheritable,
11662 METH_VARARGS, get_handle_inheritable__doc__},
11663 {"set_handle_inheritable", posix_set_handle_inheritable,
11664 METH_VARARGS, set_handle_inheritable__doc__},
11665#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011666 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011667};
11668
11669
Brian Curtin52173d42010-12-02 18:29:18 +000011670#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011671static int
Brian Curtin52173d42010-12-02 18:29:18 +000011672enable_symlink()
11673{
11674 HANDLE tok;
11675 TOKEN_PRIVILEGES tok_priv;
11676 LUID luid;
11677 int meth_idx = 0;
11678
11679 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011680 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011681
11682 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011683 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011684
11685 tok_priv.PrivilegeCount = 1;
11686 tok_priv.Privileges[0].Luid = luid;
11687 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11688
11689 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11690 sizeof(TOKEN_PRIVILEGES),
11691 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011692 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011693
Brian Curtin3b4499c2010-12-28 14:31:47 +000011694 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11695 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011696}
11697#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11698
Barry Warsaw4a342091996-12-19 23:50:02 +000011699static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011700all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011701{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011702#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011703 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011704#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011705#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011706 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011707#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011708#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011709 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011710#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011711#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011712 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011713#endif
Fred Drakec9680921999-12-13 16:37:25 +000011714#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011715 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011716#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011717#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011718 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011719#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011720#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011721 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011722#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011723#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011724 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011725#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011726#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011727 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011728#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011729#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011730 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011731#endif
11732#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011733 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011734#endif
11735#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011736 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011737#endif
11738#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011739 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011740#endif
11741#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011742 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011743#endif
11744#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011745 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011746#endif
11747#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011748 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011749#endif
11750#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011751 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011752#endif
11753#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011754 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011755#endif
11756#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011757 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011758#endif
11759#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011760 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011761#endif
11762#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011763 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011764#endif
11765#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011766 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011767#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011768#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011769 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011770#endif
11771#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011772 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011773#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011774#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011775 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011776#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011777#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011778 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011779#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011780#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011781 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011782#endif
11783#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011784 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011785#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011786#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011787 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011788#endif
11789#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011790 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011791#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011792#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011793 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011794#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011795#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011796 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011797#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011798#ifdef O_TMPFILE
11799 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11800#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011801#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011802 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011803#endif
11804#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011805 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011806#endif
11807#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011808 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011809#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011810#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011811 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011812#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011813#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011814 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011815#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011816
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011817
Jesus Cea94363612012-06-22 18:32:07 +020011818#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011819 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011820#endif
11821#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011822 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011823#endif
11824
Tim Peters5aa91602002-01-30 05:46:57 +000011825/* MS Windows */
11826#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011827 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011828 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011829#endif
11830#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011831 /* Optimize for short life (keep in memory). */
11832 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011833 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011834#endif
11835#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011836 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011837 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011838#endif
11839#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011840 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011841 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011842#endif
11843#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011844 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011845 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011846#endif
11847
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011848/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011849#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011850 /* Send a SIGIO signal whenever input or output
11851 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011852 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011853#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011854#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011855 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011856 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011857#endif
11858#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011859 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011860 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011861#endif
11862#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011863 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011864 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011865#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011866#ifdef O_NOLINKS
11867 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011868 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011869#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011870#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011871 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011872 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011873#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011874
Victor Stinner8c62be82010-05-06 00:08:46 +000011875 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011876#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011877 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011878#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011879#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011880 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011881#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011882#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011883 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011884#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011885#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011886 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011887#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011888#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011889 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011890#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011891#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011892 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011893#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011894#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011895 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011896#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011897#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011898 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011899#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011900#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011901 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011902#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011903#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011904 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011905#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011906#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011907 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011908#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011909#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011910 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011911#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011912#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011913 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011914#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011915#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011916 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011917#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011918#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011919 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011920#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011921#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011922 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011923#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011924#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011925 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011926#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011927
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011928 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011929#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011930 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011931#endif /* ST_RDONLY */
11932#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011933 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011934#endif /* ST_NOSUID */
11935
doko@ubuntu.comca616a22013-12-08 15:23:07 +010011936 /* GNU extensions */
11937#ifdef ST_NODEV
11938 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
11939#endif /* ST_NODEV */
11940#ifdef ST_NOEXEC
11941 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
11942#endif /* ST_NOEXEC */
11943#ifdef ST_SYNCHRONOUS
11944 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
11945#endif /* ST_SYNCHRONOUS */
11946#ifdef ST_MANDLOCK
11947 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
11948#endif /* ST_MANDLOCK */
11949#ifdef ST_WRITE
11950 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
11951#endif /* ST_WRITE */
11952#ifdef ST_APPEND
11953 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
11954#endif /* ST_APPEND */
11955#ifdef ST_NOATIME
11956 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
11957#endif /* ST_NOATIME */
11958#ifdef ST_NODIRATIME
11959 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
11960#endif /* ST_NODIRATIME */
11961#ifdef ST_RELATIME
11962 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
11963#endif /* ST_RELATIME */
11964
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011965 /* FreeBSD sendfile() constants */
11966#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011967 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011968#endif
11969#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011970 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011971#endif
11972#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011973 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011974#endif
11975
Ross Lagerwall7807c352011-03-17 20:20:30 +020011976 /* constants for posix_fadvise */
11977#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011978 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011979#endif
11980#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011981 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011982#endif
11983#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011984 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011985#endif
11986#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011987 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011988#endif
11989#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011990 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011991#endif
11992#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011993 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011994#endif
11995
11996 /* constants for waitid */
11997#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011998 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11999 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12000 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012001#endif
12002#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012003 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012004#endif
12005#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012006 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012007#endif
12008#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012009 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012010#endif
12011#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012012 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012013#endif
12014#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012015 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012016#endif
12017#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012018 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012019#endif
12020#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012021 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012022#endif
12023
12024 /* constants for lockf */
12025#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012026 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012027#endif
12028#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012029 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012030#endif
12031#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012032 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012033#endif
12034#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012035 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012036#endif
12037
Guido van Rossum246bc171999-02-01 23:54:31 +000012038#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012039 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12040 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12041 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12042 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12043 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012044#endif
12045
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012046#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012047 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12048 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12049 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012050#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012051 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012052#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012053#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012054 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012055#endif
12056#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012057 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012058#endif
12059#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012060 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012061#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012062#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012063 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012064#endif
12065#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012066 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012067#endif
12068#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012069 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012070#endif
12071#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012072 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012073#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012074#endif
12075
Benjamin Peterson9428d532011-09-14 11:45:52 -040012076#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012077 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12078 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12079 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012080#endif
12081
Victor Stinner8b905bd2011-10-25 13:34:04 +020012082#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012083 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012084#endif
12085#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012086 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012087#endif
12088#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012089 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012090#endif
12091#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012092 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012093#endif
12094#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012095 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012096#endif
12097#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012098 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012099#endif
12100#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012101 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012102#endif
12103
Victor Stinner8c62be82010-05-06 00:08:46 +000012104 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012105}
12106
12107
Tim Peters5aa91602002-01-30 05:46:57 +000012108#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000012109#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012110#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000012111
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000012112#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000012113#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012114#define MODNAME "posix"
12115#endif
12116
Martin v. Löwis1a214512008-06-11 05:26:20 +000012117static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012118 PyModuleDef_HEAD_INIT,
12119 MODNAME,
12120 posix__doc__,
12121 -1,
12122 posix_methods,
12123 NULL,
12124 NULL,
12125 NULL,
12126 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012127};
12128
12129
Larry Hastings9cf065c2012-06-22 16:30:09 -070012130static char *have_functions[] = {
12131
12132#ifdef HAVE_FACCESSAT
12133 "HAVE_FACCESSAT",
12134#endif
12135
12136#ifdef HAVE_FCHDIR
12137 "HAVE_FCHDIR",
12138#endif
12139
12140#ifdef HAVE_FCHMOD
12141 "HAVE_FCHMOD",
12142#endif
12143
12144#ifdef HAVE_FCHMODAT
12145 "HAVE_FCHMODAT",
12146#endif
12147
12148#ifdef HAVE_FCHOWN
12149 "HAVE_FCHOWN",
12150#endif
12151
Larry Hastings00964ed2013-08-12 13:49:30 -040012152#ifdef HAVE_FCHOWNAT
12153 "HAVE_FCHOWNAT",
12154#endif
12155
Larry Hastings9cf065c2012-06-22 16:30:09 -070012156#ifdef HAVE_FEXECVE
12157 "HAVE_FEXECVE",
12158#endif
12159
12160#ifdef HAVE_FDOPENDIR
12161 "HAVE_FDOPENDIR",
12162#endif
12163
Georg Brandl306336b2012-06-24 12:55:33 +020012164#ifdef HAVE_FPATHCONF
12165 "HAVE_FPATHCONF",
12166#endif
12167
Larry Hastings9cf065c2012-06-22 16:30:09 -070012168#ifdef HAVE_FSTATAT
12169 "HAVE_FSTATAT",
12170#endif
12171
12172#ifdef HAVE_FSTATVFS
12173 "HAVE_FSTATVFS",
12174#endif
12175
Georg Brandl306336b2012-06-24 12:55:33 +020012176#ifdef HAVE_FTRUNCATE
12177 "HAVE_FTRUNCATE",
12178#endif
12179
Larry Hastings9cf065c2012-06-22 16:30:09 -070012180#ifdef HAVE_FUTIMENS
12181 "HAVE_FUTIMENS",
12182#endif
12183
12184#ifdef HAVE_FUTIMES
12185 "HAVE_FUTIMES",
12186#endif
12187
12188#ifdef HAVE_FUTIMESAT
12189 "HAVE_FUTIMESAT",
12190#endif
12191
12192#ifdef HAVE_LINKAT
12193 "HAVE_LINKAT",
12194#endif
12195
12196#ifdef HAVE_LCHFLAGS
12197 "HAVE_LCHFLAGS",
12198#endif
12199
12200#ifdef HAVE_LCHMOD
12201 "HAVE_LCHMOD",
12202#endif
12203
12204#ifdef HAVE_LCHOWN
12205 "HAVE_LCHOWN",
12206#endif
12207
12208#ifdef HAVE_LSTAT
12209 "HAVE_LSTAT",
12210#endif
12211
12212#ifdef HAVE_LUTIMES
12213 "HAVE_LUTIMES",
12214#endif
12215
12216#ifdef HAVE_MKDIRAT
12217 "HAVE_MKDIRAT",
12218#endif
12219
12220#ifdef HAVE_MKFIFOAT
12221 "HAVE_MKFIFOAT",
12222#endif
12223
12224#ifdef HAVE_MKNODAT
12225 "HAVE_MKNODAT",
12226#endif
12227
12228#ifdef HAVE_OPENAT
12229 "HAVE_OPENAT",
12230#endif
12231
12232#ifdef HAVE_READLINKAT
12233 "HAVE_READLINKAT",
12234#endif
12235
12236#ifdef HAVE_RENAMEAT
12237 "HAVE_RENAMEAT",
12238#endif
12239
12240#ifdef HAVE_SYMLINKAT
12241 "HAVE_SYMLINKAT",
12242#endif
12243
12244#ifdef HAVE_UNLINKAT
12245 "HAVE_UNLINKAT",
12246#endif
12247
12248#ifdef HAVE_UTIMENSAT
12249 "HAVE_UTIMENSAT",
12250#endif
12251
12252#ifdef MS_WINDOWS
12253 "MS_WINDOWS",
12254#endif
12255
12256 NULL
12257};
12258
12259
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012260PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012261INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012262{
Victor Stinner8c62be82010-05-06 00:08:46 +000012263 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012264 PyObject *list;
12265 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012266
Brian Curtin52173d42010-12-02 18:29:18 +000012267#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012268 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012269#endif
12270
Victor Stinner8c62be82010-05-06 00:08:46 +000012271 m = PyModule_Create(&posixmodule);
12272 if (m == NULL)
12273 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012274
Victor Stinner8c62be82010-05-06 00:08:46 +000012275 /* Initialize environ dictionary */
12276 v = convertenviron();
12277 Py_XINCREF(v);
12278 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12279 return NULL;
12280 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012281
Victor Stinner8c62be82010-05-06 00:08:46 +000012282 if (all_ins(m))
12283 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012284
Victor Stinner8c62be82010-05-06 00:08:46 +000012285 if (setup_confname_tables(m))
12286 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012287
Victor Stinner8c62be82010-05-06 00:08:46 +000012288 Py_INCREF(PyExc_OSError);
12289 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012290
Guido van Rossumb3d39562000-01-31 18:41:26 +000012291#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012292 if (posix_putenv_garbage == NULL)
12293 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012294#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012295
Victor Stinner8c62be82010-05-06 00:08:46 +000012296 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012297#if defined(HAVE_WAITID) && !defined(__APPLE__)
12298 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012299 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12300 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012301#endif
12302
Christian Heimes25827622013-10-12 01:27:08 +020012303 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012304 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12305 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12306 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012307 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12308 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012309 structseq_new = StatResultType.tp_new;
12310 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012311
Christian Heimes25827622013-10-12 01:27:08 +020012312 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012313 if (PyStructSequence_InitType2(&StatVFSResultType,
12314 &statvfs_result_desc) < 0)
12315 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012316#ifdef NEED_TICKS_PER_SECOND
12317# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012318 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012319# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012320 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012321# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012322 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012323# endif
12324#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012325
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012326#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012327 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012328 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12329 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012330 SchedParamType.tp_new = sched_param_new;
12331#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012332
12333 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012334 if (PyStructSequence_InitType2(&TerminalSizeType,
12335 &TerminalSize_desc) < 0)
12336 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012337 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012338#if defined(HAVE_WAITID) && !defined(__APPLE__)
12339 Py_INCREF((PyObject*) &WaitidResultType);
12340 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12341#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012342 Py_INCREF((PyObject*) &StatResultType);
12343 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12344 Py_INCREF((PyObject*) &StatVFSResultType);
12345 PyModule_AddObject(m, "statvfs_result",
12346 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012347
12348#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012349 Py_INCREF(&SchedParamType);
12350 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012351#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012352
Larry Hastings605a62d2012-06-24 04:33:36 -070012353 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012354 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12355 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012356 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12357
12358 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012359 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12360 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012361 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12362
Thomas Wouters477c8d52006-05-27 19:21:47 +000012363#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012364 /*
12365 * Step 2 of weak-linking support on Mac OS X.
12366 *
12367 * The code below removes functions that are not available on the
12368 * currently active platform.
12369 *
12370 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012371 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012372 * OSX 10.4.
12373 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012374#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012375 if (fstatvfs == NULL) {
12376 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12377 return NULL;
12378 }
12379 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012380#endif /* HAVE_FSTATVFS */
12381
12382#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012383 if (statvfs == NULL) {
12384 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12385 return NULL;
12386 }
12387 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012388#endif /* HAVE_STATVFS */
12389
12390# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012391 if (lchown == NULL) {
12392 if (PyObject_DelAttrString(m, "lchown") == -1) {
12393 return NULL;
12394 }
12395 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012396#endif /* HAVE_LCHOWN */
12397
12398
12399#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012400
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012401 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012402 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12403
Larry Hastings6fe20b32012-04-19 15:07:49 -070012404 billion = PyLong_FromLong(1000000000);
12405 if (!billion)
12406 return NULL;
12407
Larry Hastings9cf065c2012-06-22 16:30:09 -070012408 /* suppress "function not used" warnings */
12409 {
12410 int ignored;
12411 fd_specified("", -1);
12412 follow_symlinks_specified("", 1);
12413 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12414 dir_fd_converter(Py_None, &ignored);
12415 dir_fd_unavailable(Py_None, &ignored);
12416 }
12417
12418 /*
12419 * provide list of locally available functions
12420 * so os.py can populate support_* lists
12421 */
12422 list = PyList_New(0);
12423 if (!list)
12424 return NULL;
12425 for (trace = have_functions; *trace; trace++) {
12426 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12427 if (!unicode)
12428 return NULL;
12429 if (PyList_Append(list, unicode))
12430 return NULL;
12431 Py_DECREF(unicode);
12432 }
12433 PyModule_AddObject(m, "_have_functions", list);
12434
12435 initialized = 1;
12436
Victor Stinner8c62be82010-05-06 00:08:46 +000012437 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000012438}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012439
12440#ifdef __cplusplus
12441}
12442#endif