blob: f22168d318553584215e9726058d8c57c6c3aa2d [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
Victor Stinner528a9ab2015-09-03 21:30:26 +02004784#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004785
4786static int
Victor Stinner484df002014-10-09 13:52:31 +02004787utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004788{
4789#ifdef HAVE_UTIMENSAT
4790 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4791 UTIME_TO_TIMESPEC;
4792 return utimensat(dir_fd, path, time, flags);
4793#elif defined(HAVE_FUTIMESAT)
4794 UTIME_TO_TIMEVAL;
4795 /*
4796 * follow_symlinks will never be false here;
4797 * we only allow !follow_symlinks and dir_fd together
4798 * if we have utimensat()
4799 */
4800 assert(follow_symlinks);
4801 return futimesat(dir_fd, path, time);
4802#endif
4803}
4804
4805#endif
4806
Victor Stinner528a9ab2015-09-03 21:30:26 +02004807#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004808
4809static int
Victor Stinner484df002014-10-09 13:52:31 +02004810utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811{
4812#ifdef HAVE_FUTIMENS
4813 UTIME_TO_TIMESPEC;
4814 return futimens(fd, time);
4815#else
4816 UTIME_TO_TIMEVAL;
4817 return futimes(fd, time);
4818#endif
4819}
4820
4821#endif
4822
4823
4824#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4825 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4826
4827#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4828
4829static int
Victor Stinner484df002014-10-09 13:52:31 +02004830utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004831{
4832#ifdef HAVE_UTIMENSAT
4833 UTIME_TO_TIMESPEC;
4834 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4835#else
4836 UTIME_TO_TIMEVAL;
4837 return lutimes(path, time);
4838#endif
4839}
4840
4841#endif
4842
4843#ifndef MS_WINDOWS
4844
4845static int
Victor Stinner484df002014-10-09 13:52:31 +02004846utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004847{
4848#ifdef HAVE_UTIMENSAT
4849 UTIME_TO_TIMESPEC;
4850 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4851#elif defined(HAVE_UTIMES)
4852 UTIME_TO_TIMEVAL;
4853 return utimes(path, time);
4854#elif defined(HAVE_UTIME_H)
4855 UTIME_TO_UTIMBUF;
4856 return utime(path, time);
4857#else
4858 UTIME_TO_TIME_T;
4859 return utime(path, time);
4860#endif
4861}
4862
4863#endif
4864
Larry Hastings76ad59b2012-05-03 00:30:07 -07004865static int
4866split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4867{
4868 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004869 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004870 divmod = PyNumber_Divmod(py_long, billion);
4871 if (!divmod)
4872 goto exit;
4873 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4874 if ((*s == -1) && PyErr_Occurred())
4875 goto exit;
4876 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004877 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004878 goto exit;
4879
4880 result = 1;
4881exit:
4882 Py_XDECREF(divmod);
4883 return result;
4884}
4885
Larry Hastings9cf065c2012-06-22 16:30:09 -07004886static PyObject *
4887posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004888{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004889 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004890 PyObject *times = NULL;
4891 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004892 int dir_fd = DEFAULT_DIR_FD;
4893 int follow_symlinks = 1;
4894 char *keywords[] = {"path", "times", "ns", "dir_fd",
4895 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004896
Larry Hastings9cf065c2012-06-22 16:30:09 -07004897 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004898
Larry Hastings9cf065c2012-06-22 16:30:09 -07004899#ifdef MS_WINDOWS
4900 HANDLE hFile;
4901 FILETIME atime, mtime;
4902#else
4903 int result;
4904#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004905
Larry Hastings9cf065c2012-06-22 16:30:09 -07004906 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004907
Larry Hastings9cf065c2012-06-22 16:30:09 -07004908 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004909 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004910 memset(&utime, 0, sizeof(utime_t));
Victor Stinner528a9ab2015-09-03 21:30:26 +02004911#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004912 path.allow_fd = 1;
4913#endif
4914 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4915 "O&|O$OO&p:utime", keywords,
4916 path_converter, &path,
4917 &times, &ns,
Victor Stinner528a9ab2015-09-03 21:30:26 +02004918#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004919 dir_fd_converter, &dir_fd,
4920#else
4921 dir_fd_unavailable, &dir_fd,
4922#endif
4923 &follow_symlinks
4924 ))
4925 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004926
Larry Hastings9cf065c2012-06-22 16:30:09 -07004927 if (times && (times != Py_None) && ns) {
4928 PyErr_SetString(PyExc_ValueError,
4929 "utime: you may specify either 'times'"
4930 " or 'ns' but not both");
4931 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004932 }
4933
4934 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004935 time_t a_sec, m_sec;
4936 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004937 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004938 PyErr_SetString(PyExc_TypeError,
4939 "utime: 'times' must be either"
4940 " a tuple of two ints or None");
4941 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004942 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004943 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004944 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004945 &a_sec, &a_nsec, _PyTime_ROUND_DOWN) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004946 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004947 &m_sec, &m_nsec, _PyTime_ROUND_DOWN) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004948 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004949 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004950 utime.atime_s = a_sec;
4951 utime.atime_ns = a_nsec;
4952 utime.mtime_s = m_sec;
4953 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004954 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004955 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004956 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004957 PyErr_SetString(PyExc_TypeError,
4958 "utime: 'ns' must be a tuple of two ints");
4959 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004960 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004961 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004962 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004963 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004964 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004965 &utime.mtime_s, &utime.mtime_ns)) {
4966 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004967 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004968 }
4969 else {
4970 /* times and ns are both None/unspecified. use "now". */
4971 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004972 }
4973
Larry Hastings9cf065c2012-06-22 16:30:09 -07004974#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4975 if (follow_symlinks_specified("utime", follow_symlinks))
4976 goto exit;
4977#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004978
Larry Hastings9cf065c2012-06-22 16:30:09 -07004979 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4980 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4981 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4982 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004983
Larry Hastings9cf065c2012-06-22 16:30:09 -07004984#if !defined(HAVE_UTIMENSAT)
4985 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004986 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004987 "utime: cannot use dir_fd and follow_symlinks "
4988 "together on this platform");
4989 goto exit;
4990 }
4991#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004992
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004993#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004994 Py_BEGIN_ALLOW_THREADS
4995 if (path.wide)
4996 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004997 NULL, OPEN_EXISTING,
4998 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004999 else
5000 hFile = CreateFileA(path.narrow, 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 Py_END_ALLOW_THREADS
5004 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01005005 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005006 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07005007 }
5008
Larry Hastings9cf065c2012-06-22 16:30:09 -07005009 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005010 GetSystemTimeAsFileTime(&mtime);
5011 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005012 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005013 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005014 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5015 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005016 }
5017 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5018 /* Avoid putting the file name into the error here,
5019 as that may confuse the user into believing that
5020 something is wrong with the file, when it also
5021 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005022 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005023 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005025#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005026 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005027
Larry Hastings9cf065c2012-06-22 16:30:09 -07005028#if UTIME_HAVE_NOFOLLOW_SYMLINKS
5029 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
5030 result = utime_nofollow_symlinks(&utime, path.narrow);
5031 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005032#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005033
Victor Stinner528a9ab2015-09-03 21:30:26 +02005034#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005035 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
5036 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
5037 else
5038#endif
5039
Victor Stinner528a9ab2015-09-03 21:30:26 +02005040#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005041 if (path.fd != -1)
5042 result = utime_fd(&utime, path.fd);
5043 else
5044#endif
5045
5046 result = utime_default(&utime, path.narrow);
5047
5048 Py_END_ALLOW_THREADS
5049
5050 if (result < 0) {
5051 /* see previous comment about not putting filename in error here */
5052 return_value = posix_error();
5053 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005054 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005055
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005056#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005057
5058 Py_INCREF(Py_None);
5059 return_value = Py_None;
5060
5061exit:
5062 path_cleanup(&path);
5063#ifdef MS_WINDOWS
5064 if (hFile != INVALID_HANDLE_VALUE)
5065 CloseHandle(hFile);
5066#endif
5067 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005068}
5069
Guido van Rossum3b066191991-06-04 19:40:25 +00005070/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005071
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005072PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005073"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005074Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005075
Barry Warsaw53699e91996-12-10 23:23:01 +00005076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005077posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005078{
Victor Stinner8c62be82010-05-06 00:08:46 +00005079 int sts;
5080 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5081 return NULL;
5082 _exit(sts);
5083 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005084}
5085
Martin v. Löwis114619e2002-10-07 06:44:21 +00005086#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5087static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00005088free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005089{
Victor Stinner8c62be82010-05-06 00:08:46 +00005090 Py_ssize_t i;
5091 for (i = 0; i < count; i++)
5092 PyMem_Free(array[i]);
5093 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005094}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005095
Antoine Pitrou69f71142009-05-24 21:25:49 +00005096static
Martin v. Löwis011e8422009-05-05 04:43:17 +00005097int fsconvert_strdup(PyObject *o, char**out)
5098{
Victor Stinner8c62be82010-05-06 00:08:46 +00005099 PyObject *bytes;
5100 Py_ssize_t size;
5101 if (!PyUnicode_FSConverter(o, &bytes))
5102 return 0;
5103 size = PyBytes_GET_SIZE(bytes);
5104 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01005105 if (!*out) {
5106 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01005108 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 memcpy(*out, PyBytes_AsString(bytes), size+1);
5110 Py_DECREF(bytes);
5111 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005112}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005113#endif
5114
Ross Lagerwall7807c352011-03-17 20:20:30 +02005115#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005116static char**
5117parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5118{
Victor Stinner8c62be82010-05-06 00:08:46 +00005119 char **envlist;
5120 Py_ssize_t i, pos, envc;
5121 PyObject *keys=NULL, *vals=NULL;
5122 PyObject *key, *val, *key2, *val2;
5123 char *p, *k, *v;
5124 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005125
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 i = PyMapping_Size(env);
5127 if (i < 0)
5128 return NULL;
5129 envlist = PyMem_NEW(char *, i + 1);
5130 if (envlist == NULL) {
5131 PyErr_NoMemory();
5132 return NULL;
5133 }
5134 envc = 0;
5135 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005136 if (!keys)
5137 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005138 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005139 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005140 goto error;
5141 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5142 PyErr_Format(PyExc_TypeError,
5143 "env.keys() or env.values() is not a list");
5144 goto error;
5145 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005146
Victor Stinner8c62be82010-05-06 00:08:46 +00005147 for (pos = 0; pos < i; pos++) {
5148 key = PyList_GetItem(keys, pos);
5149 val = PyList_GetItem(vals, pos);
5150 if (!key || !val)
5151 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005152
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 if (PyUnicode_FSConverter(key, &key2) == 0)
5154 goto error;
5155 if (PyUnicode_FSConverter(val, &val2) == 0) {
5156 Py_DECREF(key2);
5157 goto error;
5158 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005159
Victor Stinner8c62be82010-05-06 00:08:46 +00005160 k = PyBytes_AsString(key2);
5161 v = PyBytes_AsString(val2);
5162 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005163
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 p = PyMem_NEW(char, len);
5165 if (p == NULL) {
5166 PyErr_NoMemory();
5167 Py_DECREF(key2);
5168 Py_DECREF(val2);
5169 goto error;
5170 }
5171 PyOS_snprintf(p, len, "%s=%s", k, v);
5172 envlist[envc++] = p;
5173 Py_DECREF(key2);
5174 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 }
5176 Py_DECREF(vals);
5177 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005178
Victor Stinner8c62be82010-05-06 00:08:46 +00005179 envlist[envc] = 0;
5180 *envc_ptr = envc;
5181 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005182
5183error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005184 Py_XDECREF(keys);
5185 Py_XDECREF(vals);
5186 while (--envc >= 0)
5187 PyMem_DEL(envlist[envc]);
5188 PyMem_DEL(envlist);
5189 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005190}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005191
Ross Lagerwall7807c352011-03-17 20:20:30 +02005192static char**
5193parse_arglist(PyObject* argv, Py_ssize_t *argc)
5194{
5195 int i;
5196 char **argvlist = PyMem_NEW(char *, *argc+1);
5197 if (argvlist == NULL) {
5198 PyErr_NoMemory();
5199 return NULL;
5200 }
5201 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005202 PyObject* item = PySequence_ITEM(argv, i);
5203 if (item == NULL)
5204 goto fail;
5205 if (!fsconvert_strdup(item, &argvlist[i])) {
5206 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005207 goto fail;
5208 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005209 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005210 }
5211 argvlist[*argc] = NULL;
5212 return argvlist;
5213fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005214 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005215 free_string_array(argvlist, *argc);
5216 return NULL;
5217}
5218#endif
5219
5220#ifdef HAVE_EXECV
5221PyDoc_STRVAR(posix_execv__doc__,
5222"execv(path, args)\n\n\
5223Execute an executable path with arguments, replacing current process.\n\
5224\n\
5225 path: path of executable file\n\
5226 args: tuple or list of strings");
5227
5228static PyObject *
5229posix_execv(PyObject *self, PyObject *args)
5230{
5231 PyObject *opath;
5232 char *path;
5233 PyObject *argv;
5234 char **argvlist;
5235 Py_ssize_t argc;
5236
5237 /* execv has two arguments: (path, argv), where
5238 argv is a list or tuple of strings. */
5239
5240 if (!PyArg_ParseTuple(args, "O&O:execv",
5241 PyUnicode_FSConverter,
5242 &opath, &argv))
5243 return NULL;
5244 path = PyBytes_AsString(opath);
5245 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5246 PyErr_SetString(PyExc_TypeError,
5247 "execv() arg 2 must be a tuple or list");
5248 Py_DECREF(opath);
5249 return NULL;
5250 }
5251 argc = PySequence_Size(argv);
5252 if (argc < 1) {
5253 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5254 Py_DECREF(opath);
5255 return NULL;
5256 }
5257
5258 argvlist = parse_arglist(argv, &argc);
5259 if (argvlist == NULL) {
5260 Py_DECREF(opath);
5261 return NULL;
5262 }
5263
5264 execv(path, argvlist);
5265
5266 /* If we get here it's definitely an error */
5267
5268 free_string_array(argvlist, argc);
5269 Py_DECREF(opath);
5270 return posix_error();
5271}
5272
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005273PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005274"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005275Execute a path with arguments and environment, replacing current process.\n\
5276\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005277 path: path of executable file\n\
5278 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005279 env: dictionary of strings mapping to strings\n\
5280\n\
5281On some platforms, you may specify an open file descriptor for path;\n\
5282 execve will execute the program the file descriptor is open to.\n\
5283 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005284
Barry Warsaw53699e91996-12-10 23:23:01 +00005285static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005286posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005287{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005288 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005289 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005290 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005291 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005292 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005293 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005294
Victor Stinner8c62be82010-05-06 00:08:46 +00005295 /* execve has three arguments: (path, argv, env), where
5296 argv is a list or tuple of strings and env is a dictionary
5297 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005298
Larry Hastings9cf065c2012-06-22 16:30:09 -07005299 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005300 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005301#ifdef HAVE_FEXECVE
5302 path.allow_fd = 1;
5303#endif
5304 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5305 path_converter, &path,
5306 &argv, &env
5307 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005308 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005309
Ross Lagerwall7807c352011-03-17 20:20:30 +02005310 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005311 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005312 "execve: argv must be a tuple or list");
5313 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005315 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005316 if (!PyMapping_Check(env)) {
5317 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005318 "execve: environment must be a mapping object");
5319 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005320 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005321
Ross Lagerwall7807c352011-03-17 20:20:30 +02005322 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005323 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005324 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005325 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005326
Victor Stinner8c62be82010-05-06 00:08:46 +00005327 envlist = parse_envlist(env, &envc);
5328 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005329 goto fail;
5330
Larry Hastings9cf065c2012-06-22 16:30:09 -07005331#ifdef HAVE_FEXECVE
5332 if (path.fd > -1)
5333 fexecve(path.fd, argvlist, envlist);
5334 else
5335#endif
5336 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005337
5338 /* If we get here it's definitely an error */
5339
Victor Stinner292c8352012-10-30 02:17:38 +01005340 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005341
5342 while (--envc >= 0)
5343 PyMem_DEL(envlist[envc]);
5344 PyMem_DEL(envlist);
5345 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005346 if (argvlist)
5347 free_string_array(argvlist, argc);
5348 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005349 return NULL;
5350}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005351#endif /* HAVE_EXECV */
5352
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005353
Guido van Rossuma1065681999-01-25 23:20:23 +00005354#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005355PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005356"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005357Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005358\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005359 mode: mode of process creation\n\
5360 path: path of executable file\n\
5361 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005362
5363static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005364posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005365{
Victor Stinner8c62be82010-05-06 00:08:46 +00005366 PyObject *opath;
5367 char *path;
5368 PyObject *argv;
5369 char **argvlist;
5370 int mode, i;
5371 Py_ssize_t argc;
5372 Py_intptr_t spawnval;
5373 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005374
Victor Stinner8c62be82010-05-06 00:08:46 +00005375 /* spawnv has three arguments: (mode, path, argv), where
5376 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005377
Victor Stinner8c62be82010-05-06 00:08:46 +00005378 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5379 PyUnicode_FSConverter,
5380 &opath, &argv))
5381 return NULL;
5382 path = PyBytes_AsString(opath);
5383 if (PyList_Check(argv)) {
5384 argc = PyList_Size(argv);
5385 getitem = PyList_GetItem;
5386 }
5387 else if (PyTuple_Check(argv)) {
5388 argc = PyTuple_Size(argv);
5389 getitem = PyTuple_GetItem;
5390 }
5391 else {
5392 PyErr_SetString(PyExc_TypeError,
5393 "spawnv() arg 2 must be a tuple or list");
5394 Py_DECREF(opath);
5395 return NULL;
5396 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005397
Victor Stinner8c62be82010-05-06 00:08:46 +00005398 argvlist = PyMem_NEW(char *, argc+1);
5399 if (argvlist == NULL) {
5400 Py_DECREF(opath);
5401 return PyErr_NoMemory();
5402 }
5403 for (i = 0; i < argc; i++) {
5404 if (!fsconvert_strdup((*getitem)(argv, i),
5405 &argvlist[i])) {
5406 free_string_array(argvlist, i);
5407 PyErr_SetString(
5408 PyExc_TypeError,
5409 "spawnv() arg 2 must contain only strings");
5410 Py_DECREF(opath);
5411 return NULL;
5412 }
5413 }
5414 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005415
Victor Stinner8c62be82010-05-06 00:08:46 +00005416 if (mode == _OLD_P_OVERLAY)
5417 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005418
Victor Stinner8c62be82010-05-06 00:08:46 +00005419 Py_BEGIN_ALLOW_THREADS
5420 spawnval = _spawnv(mode, path, argvlist);
5421 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005422
Victor Stinner8c62be82010-05-06 00:08:46 +00005423 free_string_array(argvlist, argc);
5424 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005425
Victor Stinner8c62be82010-05-06 00:08:46 +00005426 if (spawnval == -1)
5427 return posix_error();
5428 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005429 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005430}
5431
5432
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005433PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005434"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005435Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005436\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005437 mode: mode of process creation\n\
5438 path: path of executable file\n\
5439 args: tuple or list of arguments\n\
5440 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005441
5442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005443posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005444{
Victor Stinner8c62be82010-05-06 00:08:46 +00005445 PyObject *opath;
5446 char *path;
5447 PyObject *argv, *env;
5448 char **argvlist;
5449 char **envlist;
5450 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005451 int mode;
5452 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005453 Py_intptr_t spawnval;
5454 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5455 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005456
Victor Stinner8c62be82010-05-06 00:08:46 +00005457 /* spawnve has four arguments: (mode, path, argv, env), where
5458 argv is a list or tuple of strings and env is a dictionary
5459 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005460
Victor Stinner8c62be82010-05-06 00:08:46 +00005461 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5462 PyUnicode_FSConverter,
5463 &opath, &argv, &env))
5464 return NULL;
5465 path = PyBytes_AsString(opath);
5466 if (PyList_Check(argv)) {
5467 argc = PyList_Size(argv);
5468 getitem = PyList_GetItem;
5469 }
5470 else if (PyTuple_Check(argv)) {
5471 argc = PyTuple_Size(argv);
5472 getitem = PyTuple_GetItem;
5473 }
5474 else {
5475 PyErr_SetString(PyExc_TypeError,
5476 "spawnve() arg 2 must be a tuple or list");
5477 goto fail_0;
5478 }
5479 if (!PyMapping_Check(env)) {
5480 PyErr_SetString(PyExc_TypeError,
5481 "spawnve() arg 3 must be a mapping object");
5482 goto fail_0;
5483 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005484
Victor Stinner8c62be82010-05-06 00:08:46 +00005485 argvlist = PyMem_NEW(char *, argc+1);
5486 if (argvlist == NULL) {
5487 PyErr_NoMemory();
5488 goto fail_0;
5489 }
5490 for (i = 0; i < argc; i++) {
5491 if (!fsconvert_strdup((*getitem)(argv, i),
5492 &argvlist[i]))
5493 {
5494 lastarg = i;
5495 goto fail_1;
5496 }
5497 }
5498 lastarg = argc;
5499 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005500
Victor Stinner8c62be82010-05-06 00:08:46 +00005501 envlist = parse_envlist(env, &envc);
5502 if (envlist == NULL)
5503 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005504
Victor Stinner8c62be82010-05-06 00:08:46 +00005505 if (mode == _OLD_P_OVERLAY)
5506 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005507
Victor Stinner8c62be82010-05-06 00:08:46 +00005508 Py_BEGIN_ALLOW_THREADS
5509 spawnval = _spawnve(mode, path, argvlist, envlist);
5510 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005511
Victor Stinner8c62be82010-05-06 00:08:46 +00005512 if (spawnval == -1)
5513 (void) posix_error();
5514 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005515 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005516
Victor Stinner8c62be82010-05-06 00:08:46 +00005517 while (--envc >= 0)
5518 PyMem_DEL(envlist[envc]);
5519 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005520 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005521 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005522 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005523 Py_DECREF(opath);
5524 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005525}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005526
Guido van Rossuma1065681999-01-25 23:20:23 +00005527#endif /* HAVE_SPAWNV */
5528
5529
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005530#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005531PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005532"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005533Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5534\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005535Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005536
5537static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005538posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005539{
Victor Stinner8c62be82010-05-06 00:08:46 +00005540 pid_t pid;
5541 int result = 0;
5542 _PyImport_AcquireLock();
5543 pid = fork1();
5544 if (pid == 0) {
5545 /* child: this clobbers and resets the import lock. */
5546 PyOS_AfterFork();
5547 } else {
5548 /* parent: release the import lock. */
5549 result = _PyImport_ReleaseLock();
5550 }
5551 if (pid == -1)
5552 return posix_error();
5553 if (result < 0) {
5554 /* Don't clobber the OSError if the fork failed. */
5555 PyErr_SetString(PyExc_RuntimeError,
5556 "not holding the import lock");
5557 return NULL;
5558 }
5559 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005560}
5561#endif
5562
5563
Guido van Rossumad0ee831995-03-01 10:34:45 +00005564#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005565PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005566"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005567Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005568Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005569
Barry Warsaw53699e91996-12-10 23:23:01 +00005570static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005571posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005572{
Victor Stinner8c62be82010-05-06 00:08:46 +00005573 pid_t pid;
5574 int result = 0;
5575 _PyImport_AcquireLock();
5576 pid = fork();
5577 if (pid == 0) {
5578 /* child: this clobbers and resets the import lock. */
5579 PyOS_AfterFork();
5580 } else {
5581 /* parent: release the import lock. */
5582 result = _PyImport_ReleaseLock();
5583 }
5584 if (pid == -1)
5585 return posix_error();
5586 if (result < 0) {
5587 /* Don't clobber the OSError if the fork failed. */
5588 PyErr_SetString(PyExc_RuntimeError,
5589 "not holding the import lock");
5590 return NULL;
5591 }
5592 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005593}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005594#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005595
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005596#ifdef HAVE_SCHED_H
5597
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005598#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5599
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005600PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5601"sched_get_priority_max(policy)\n\n\
5602Get the maximum scheduling priority for *policy*.");
5603
5604static PyObject *
5605posix_sched_get_priority_max(PyObject *self, PyObject *args)
5606{
5607 int policy, max;
5608
5609 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5610 return NULL;
5611 max = sched_get_priority_max(policy);
5612 if (max < 0)
5613 return posix_error();
5614 return PyLong_FromLong(max);
5615}
5616
5617PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5618"sched_get_priority_min(policy)\n\n\
5619Get the minimum scheduling priority for *policy*.");
5620
5621static PyObject *
5622posix_sched_get_priority_min(PyObject *self, PyObject *args)
5623{
5624 int policy, min;
5625
5626 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5627 return NULL;
5628 min = sched_get_priority_min(policy);
5629 if (min < 0)
5630 return posix_error();
5631 return PyLong_FromLong(min);
5632}
5633
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005634#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5635
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005636#ifdef HAVE_SCHED_SETSCHEDULER
5637
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005638PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5639"sched_getscheduler(pid)\n\n\
5640Get the scheduling policy for the process with a PID of *pid*.\n\
5641Passing a PID of 0 returns the scheduling policy for the calling process.");
5642
5643static PyObject *
5644posix_sched_getscheduler(PyObject *self, PyObject *args)
5645{
5646 pid_t pid;
5647 int policy;
5648
5649 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5650 return NULL;
5651 policy = sched_getscheduler(pid);
5652 if (policy < 0)
5653 return posix_error();
5654 return PyLong_FromLong(policy);
5655}
5656
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005657#endif
5658
5659#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5660
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005661static PyObject *
5662sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5663{
5664 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005665 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005666
5667 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5668 return NULL;
5669 res = PyStructSequence_New(type);
5670 if (!res)
5671 return NULL;
5672 Py_INCREF(priority);
5673 PyStructSequence_SET_ITEM(res, 0, priority);
5674 return res;
5675}
5676
5677PyDoc_STRVAR(sched_param__doc__,
5678"sched_param(sched_priority): A scheduling parameter.\n\n\
5679Current has only one field: sched_priority");
5680
5681static PyStructSequence_Field sched_param_fields[] = {
5682 {"sched_priority", "the scheduling priority"},
5683 {0}
5684};
5685
5686static PyStructSequence_Desc sched_param_desc = {
5687 "sched_param", /* name */
5688 sched_param__doc__, /* doc */
5689 sched_param_fields,
5690 1
5691};
5692
5693static int
5694convert_sched_param(PyObject *param, struct sched_param *res)
5695{
5696 long priority;
5697
5698 if (Py_TYPE(param) != &SchedParamType) {
5699 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5700 return 0;
5701 }
5702 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5703 if (priority == -1 && PyErr_Occurred())
5704 return 0;
5705 if (priority > INT_MAX || priority < INT_MIN) {
5706 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5707 return 0;
5708 }
5709 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5710 return 1;
5711}
5712
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005713#endif
5714
5715#ifdef HAVE_SCHED_SETSCHEDULER
5716
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005717PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5718"sched_setscheduler(pid, policy, param)\n\n\
5719Set the scheduling policy, *policy*, for *pid*.\n\
5720If *pid* is 0, the calling process is changed.\n\
5721*param* is an instance of sched_param.");
5722
5723static PyObject *
5724posix_sched_setscheduler(PyObject *self, PyObject *args)
5725{
5726 pid_t pid;
5727 int policy;
5728 struct sched_param param;
5729
5730 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5731 &pid, &policy, &convert_sched_param, &param))
5732 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005733
5734 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005735 ** sched_setscheduler() returns 0 in Linux, but the previous
5736 ** scheduling policy under Solaris/Illumos, and others.
5737 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005738 */
5739 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005740 return posix_error();
5741 Py_RETURN_NONE;
5742}
5743
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005744#endif
5745
5746#ifdef HAVE_SCHED_SETPARAM
5747
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005748PyDoc_STRVAR(posix_sched_getparam__doc__,
5749"sched_getparam(pid) -> sched_param\n\n\
5750Returns scheduling parameters for the process with *pid* as an instance of the\n\
5751sched_param class. A PID of 0 means the calling process.");
5752
5753static PyObject *
5754posix_sched_getparam(PyObject *self, PyObject *args)
5755{
5756 pid_t pid;
5757 struct sched_param param;
5758 PyObject *res, *priority;
5759
5760 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5761 return NULL;
5762 if (sched_getparam(pid, &param))
5763 return posix_error();
5764 res = PyStructSequence_New(&SchedParamType);
5765 if (!res)
5766 return NULL;
5767 priority = PyLong_FromLong(param.sched_priority);
5768 if (!priority) {
5769 Py_DECREF(res);
5770 return NULL;
5771 }
5772 PyStructSequence_SET_ITEM(res, 0, priority);
5773 return res;
5774}
5775
5776PyDoc_STRVAR(posix_sched_setparam__doc__,
5777"sched_setparam(pid, param)\n\n\
5778Set scheduling parameters for a process with PID *pid*.\n\
5779A PID of 0 means the calling process.");
5780
5781static PyObject *
5782posix_sched_setparam(PyObject *self, PyObject *args)
5783{
5784 pid_t pid;
5785 struct sched_param param;
5786
5787 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5788 &pid, &convert_sched_param, &param))
5789 return NULL;
5790 if (sched_setparam(pid, &param))
5791 return posix_error();
5792 Py_RETURN_NONE;
5793}
5794
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005795#endif
5796
5797#ifdef HAVE_SCHED_RR_GET_INTERVAL
5798
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005799PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5800"sched_rr_get_interval(pid) -> float\n\n\
5801Return the round-robin quantum for the process with PID *pid* in seconds.");
5802
5803static PyObject *
5804posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5805{
5806 pid_t pid;
5807 struct timespec interval;
5808
5809 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5810 return NULL;
5811 if (sched_rr_get_interval(pid, &interval))
5812 return posix_error();
5813 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5814}
5815
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005816#endif
5817
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005818PyDoc_STRVAR(posix_sched_yield__doc__,
5819"sched_yield()\n\n\
5820Voluntarily relinquish the CPU.");
5821
5822static PyObject *
5823posix_sched_yield(PyObject *self, PyObject *noargs)
5824{
5825 if (sched_yield())
5826 return posix_error();
5827 Py_RETURN_NONE;
5828}
5829
Benjamin Peterson2740af82011-08-02 17:41:34 -05005830#ifdef HAVE_SCHED_SETAFFINITY
5831
Antoine Pitrou84869872012-08-04 16:16:35 +02005832/* The minimum number of CPUs allocated in a cpu_set_t */
5833static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005834
5835PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5836"sched_setaffinity(pid, cpu_set)\n\n\
5837Set the affinity of the process with PID *pid* to *cpu_set*.");
5838
5839static PyObject *
5840posix_sched_setaffinity(PyObject *self, PyObject *args)
5841{
5842 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005843 int ncpus;
5844 size_t setsize;
5845 cpu_set_t *mask = NULL;
5846 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005847
Antoine Pitrou84869872012-08-04 16:16:35 +02005848 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5849 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005850 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005851
5852 iterator = PyObject_GetIter(iterable);
5853 if (iterator == NULL)
5854 return NULL;
5855
5856 ncpus = NCPUS_START;
5857 setsize = CPU_ALLOC_SIZE(ncpus);
5858 mask = CPU_ALLOC(ncpus);
5859 if (mask == NULL) {
5860 PyErr_NoMemory();
5861 goto error;
5862 }
5863 CPU_ZERO_S(setsize, mask);
5864
5865 while ((item = PyIter_Next(iterator))) {
5866 long cpu;
5867 if (!PyLong_Check(item)) {
5868 PyErr_Format(PyExc_TypeError,
5869 "expected an iterator of ints, "
5870 "but iterator yielded %R",
5871 Py_TYPE(item));
5872 Py_DECREF(item);
5873 goto error;
5874 }
5875 cpu = PyLong_AsLong(item);
5876 Py_DECREF(item);
5877 if (cpu < 0) {
5878 if (!PyErr_Occurred())
5879 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5880 goto error;
5881 }
5882 if (cpu > INT_MAX - 1) {
5883 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5884 goto error;
5885 }
5886 if (cpu >= ncpus) {
5887 /* Grow CPU mask to fit the CPU number */
5888 int newncpus = ncpus;
5889 cpu_set_t *newmask;
5890 size_t newsetsize;
5891 while (newncpus <= cpu) {
5892 if (newncpus > INT_MAX / 2)
5893 newncpus = cpu + 1;
5894 else
5895 newncpus = newncpus * 2;
5896 }
5897 newmask = CPU_ALLOC(newncpus);
5898 if (newmask == NULL) {
5899 PyErr_NoMemory();
5900 goto error;
5901 }
5902 newsetsize = CPU_ALLOC_SIZE(newncpus);
5903 CPU_ZERO_S(newsetsize, newmask);
5904 memcpy(newmask, mask, setsize);
5905 CPU_FREE(mask);
5906 setsize = newsetsize;
5907 mask = newmask;
5908 ncpus = newncpus;
5909 }
5910 CPU_SET_S(cpu, setsize, mask);
5911 }
5912 Py_CLEAR(iterator);
5913
5914 if (sched_setaffinity(pid, setsize, mask)) {
5915 posix_error();
5916 goto error;
5917 }
5918 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005919 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005920
5921error:
5922 if (mask)
5923 CPU_FREE(mask);
5924 Py_XDECREF(iterator);
5925 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005926}
5927
5928PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5929"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5930Return the affinity of the process with PID *pid*.\n\
5931The returned cpu_set will be of size *ncpus*.");
5932
5933static PyObject *
5934posix_sched_getaffinity(PyObject *self, PyObject *args)
5935{
5936 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005937 int cpu, ncpus, count;
5938 size_t setsize;
5939 cpu_set_t *mask = NULL;
5940 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005941
Antoine Pitrou84869872012-08-04 16:16:35 +02005942 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5943 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005944 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005945
5946 ncpus = NCPUS_START;
5947 while (1) {
5948 setsize = CPU_ALLOC_SIZE(ncpus);
5949 mask = CPU_ALLOC(ncpus);
5950 if (mask == NULL)
5951 return PyErr_NoMemory();
5952 if (sched_getaffinity(pid, setsize, mask) == 0)
5953 break;
5954 CPU_FREE(mask);
5955 if (errno != EINVAL)
5956 return posix_error();
5957 if (ncpus > INT_MAX / 2) {
5958 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5959 "a large enough CPU set");
5960 return NULL;
5961 }
5962 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005963 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005964
5965 res = PySet_New(NULL);
5966 if (res == NULL)
5967 goto error;
5968 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5969 if (CPU_ISSET_S(cpu, setsize, mask)) {
5970 PyObject *cpu_num = PyLong_FromLong(cpu);
5971 --count;
5972 if (cpu_num == NULL)
5973 goto error;
5974 if (PySet_Add(res, cpu_num)) {
5975 Py_DECREF(cpu_num);
5976 goto error;
5977 }
5978 Py_DECREF(cpu_num);
5979 }
5980 }
5981 CPU_FREE(mask);
5982 return res;
5983
5984error:
5985 if (mask)
5986 CPU_FREE(mask);
5987 Py_XDECREF(res);
5988 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005989}
5990
Benjamin Peterson2740af82011-08-02 17:41:34 -05005991#endif /* HAVE_SCHED_SETAFFINITY */
5992
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005993#endif /* HAVE_SCHED_H */
5994
Neal Norwitzb59798b2003-03-21 01:43:31 +00005995/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005996/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5997#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005998#define DEV_PTY_FILE "/dev/ptc"
5999#define HAVE_DEV_PTMX
6000#else
6001#define DEV_PTY_FILE "/dev/ptmx"
6002#endif
6003
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006004#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006005#ifdef HAVE_PTY_H
6006#include <pty.h>
6007#else
6008#ifdef HAVE_LIBUTIL_H
6009#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006010#else
6011#ifdef HAVE_UTIL_H
6012#include <util.h>
6013#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006014#endif /* HAVE_LIBUTIL_H */
6015#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006016#ifdef HAVE_STROPTS_H
6017#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006018#endif
6019#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006020
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006021#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006022PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006023"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006024Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006025
6026static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006027posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006028{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006029 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006030#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006031 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006032#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006033#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006034 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006035#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006037#endif
6038#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006039
Thomas Wouters70c21a12000-07-14 14:28:33 +00006040#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006041 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006042 goto posix_error;
6043
6044 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6045 goto error;
6046 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6047 goto error;
6048
Neal Norwitzb59798b2003-03-21 01:43:31 +00006049#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006050 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6051 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006052 goto posix_error;
6053 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6054 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006055
Victor Stinnerdaf45552013-08-28 00:53:59 +02006056 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006057 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006058 goto posix_error;
6059
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006060#else
Victor Stinner000de532013-11-25 23:19:58 +01006061 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006062 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006063 goto posix_error;
6064
Victor Stinner8c62be82010-05-06 00:08:46 +00006065 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006066
Victor Stinner8c62be82010-05-06 00:08:46 +00006067 /* change permission of slave */
6068 if (grantpt(master_fd) < 0) {
6069 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006070 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006072
Victor Stinner8c62be82010-05-06 00:08:46 +00006073 /* unlock slave */
6074 if (unlockpt(master_fd) < 0) {
6075 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006076 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006078
Victor Stinner8c62be82010-05-06 00:08:46 +00006079 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006080
Victor Stinner8c62be82010-05-06 00:08:46 +00006081 slave_name = ptsname(master_fd); /* get name of slave */
6082 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006083 goto posix_error;
6084
6085 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00006086 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006087 goto posix_error;
Victor Stinner000de532013-11-25 23:19:58 +01006088
6089 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6090 goto posix_error;
6091
Neal Norwitzb59798b2003-03-21 01:43:31 +00006092#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006093 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6094 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006095#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006096 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006097#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006098#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006099#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006100
Victor Stinner8c62be82010-05-06 00:08:46 +00006101 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006102
Victor Stinnerdaf45552013-08-28 00:53:59 +02006103posix_error:
6104 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006105#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006106error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006107#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02006108 if (master_fd != -1)
6109 close(master_fd);
6110 if (slave_fd != -1)
6111 close(slave_fd);
6112 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006113}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006114#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006115
6116#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006117PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006118"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006119Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6120Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006121To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006122
6123static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006124posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006125{
Victor Stinner8c62be82010-05-06 00:08:46 +00006126 int master_fd = -1, result = 0;
6127 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006128
Victor Stinner8c62be82010-05-06 00:08:46 +00006129 _PyImport_AcquireLock();
6130 pid = forkpty(&master_fd, NULL, NULL, NULL);
6131 if (pid == 0) {
6132 /* child: this clobbers and resets the import lock. */
6133 PyOS_AfterFork();
6134 } else {
6135 /* parent: release the import lock. */
6136 result = _PyImport_ReleaseLock();
6137 }
6138 if (pid == -1)
6139 return posix_error();
6140 if (result < 0) {
6141 /* Don't clobber the OSError if the fork failed. */
6142 PyErr_SetString(PyExc_RuntimeError,
6143 "not holding the import lock");
6144 return NULL;
6145 }
6146 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006147}
6148#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006149
Ross Lagerwall7807c352011-03-17 20:20:30 +02006150
Guido van Rossumad0ee831995-03-01 10:34:45 +00006151#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006152PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006153"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006154Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006155
Barry Warsaw53699e91996-12-10 23:23:01 +00006156static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006157posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006158{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006159 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006160}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006161#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006163
Guido van Rossumad0ee831995-03-01 10:34:45 +00006164#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006165PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006166"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006167Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006168
Barry Warsaw53699e91996-12-10 23:23:01 +00006169static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006170posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006171{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006172 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006173}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006174#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006176
Guido van Rossumad0ee831995-03-01 10:34:45 +00006177#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006178PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006179"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006180Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006181
Barry Warsaw53699e91996-12-10 23:23:01 +00006182static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006183posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006184{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006185 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006186}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006187#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006188
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006189
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006190PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006191"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006192Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006193
Barry Warsaw53699e91996-12-10 23:23:01 +00006194static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006195posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006196{
Victor Stinner8c62be82010-05-06 00:08:46 +00006197 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006198}
6199
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006200#ifdef HAVE_GETGROUPLIST
6201PyDoc_STRVAR(posix_getgrouplist__doc__,
6202"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6203Returns a list of groups to which a user belongs.\n\n\
6204 user: username to lookup\n\
6205 group: base group id of the user");
6206
6207static PyObject *
6208posix_getgrouplist(PyObject *self, PyObject *args)
6209{
6210#ifdef NGROUPS_MAX
6211#define MAX_GROUPS NGROUPS_MAX
6212#else
6213 /* defined to be 16 on Solaris7, so this should be a small number */
6214#define MAX_GROUPS 64
6215#endif
6216
6217 const char *user;
6218 int i, ngroups;
6219 PyObject *list;
6220#ifdef __APPLE__
6221 int *groups, basegid;
6222#else
6223 gid_t *groups, basegid;
6224#endif
6225 ngroups = MAX_GROUPS;
6226
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006227#ifdef __APPLE__
6228 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006229 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006230#else
6231 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6232 _Py_Gid_Converter, &basegid))
6233 return NULL;
6234#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006235
6236#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006237 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006238#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006239 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006240#endif
6241 if (groups == NULL)
6242 return PyErr_NoMemory();
6243
6244 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6245 PyMem_Del(groups);
6246 return posix_error();
6247 }
6248
6249 list = PyList_New(ngroups);
6250 if (list == NULL) {
6251 PyMem_Del(groups);
6252 return NULL;
6253 }
6254
6255 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006256#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006257 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006258#else
6259 PyObject *o = _PyLong_FromGid(groups[i]);
6260#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006261 if (o == NULL) {
6262 Py_DECREF(list);
6263 PyMem_Del(groups);
6264 return NULL;
6265 }
6266 PyList_SET_ITEM(list, i, o);
6267 }
6268
6269 PyMem_Del(groups);
6270
6271 return list;
6272}
6273#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006274
Fred Drakec9680921999-12-13 16:37:25 +00006275#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006276PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006277"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006278Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006279
6280static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006281posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006282{
6283 PyObject *result = NULL;
6284
Fred Drakec9680921999-12-13 16:37:25 +00006285#ifdef NGROUPS_MAX
6286#define MAX_GROUPS NGROUPS_MAX
6287#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006289#define MAX_GROUPS 64
6290#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006291 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006292
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006293 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006294 * This is a helper variable to store the intermediate result when
6295 * that happens.
6296 *
6297 * To keep the code readable the OSX behaviour is unconditional,
6298 * according to the POSIX spec this should be safe on all unix-y
6299 * systems.
6300 */
6301 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006303
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006304#ifdef __APPLE__
6305 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6306 * there are more groups than can fit in grouplist. Therefore, on OS X
6307 * always first call getgroups with length 0 to get the actual number
6308 * of groups.
6309 */
6310 n = getgroups(0, NULL);
6311 if (n < 0) {
6312 return posix_error();
6313 } else if (n <= MAX_GROUPS) {
6314 /* groups will fit in existing array */
6315 alt_grouplist = grouplist;
6316 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006317 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006318 if (alt_grouplist == NULL) {
6319 errno = EINVAL;
6320 return posix_error();
6321 }
6322 }
6323
6324 n = getgroups(n, alt_grouplist);
6325 if (n == -1) {
6326 if (alt_grouplist != grouplist) {
6327 PyMem_Free(alt_grouplist);
6328 }
6329 return posix_error();
6330 }
6331#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006332 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006333 if (n < 0) {
6334 if (errno == EINVAL) {
6335 n = getgroups(0, NULL);
6336 if (n == -1) {
6337 return posix_error();
6338 }
6339 if (n == 0) {
6340 /* Avoid malloc(0) */
6341 alt_grouplist = grouplist;
6342 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006343 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006344 if (alt_grouplist == NULL) {
6345 errno = EINVAL;
6346 return posix_error();
6347 }
6348 n = getgroups(n, alt_grouplist);
6349 if (n == -1) {
6350 PyMem_Free(alt_grouplist);
6351 return posix_error();
6352 }
6353 }
6354 } else {
6355 return posix_error();
6356 }
6357 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006358#endif
6359
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006360 result = PyList_New(n);
6361 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006362 int i;
6363 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006364 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006366 Py_DECREF(result);
6367 result = NULL;
6368 break;
Fred Drakec9680921999-12-13 16:37:25 +00006369 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006370 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006371 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006372 }
6373
6374 if (alt_grouplist != grouplist) {
6375 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006376 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006377
Fred Drakec9680921999-12-13 16:37:25 +00006378 return result;
6379}
6380#endif
6381
Antoine Pitroub7572f02009-12-02 20:46:48 +00006382#ifdef HAVE_INITGROUPS
6383PyDoc_STRVAR(posix_initgroups__doc__,
6384"initgroups(username, gid) -> None\n\n\
6385Call the system initgroups() to initialize the group access list with all of\n\
6386the groups of which the specified username is a member, plus the specified\n\
6387group id.");
6388
6389static PyObject *
6390posix_initgroups(PyObject *self, PyObject *args)
6391{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006392 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006393 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006394 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006395#ifdef __APPLE__
6396 int gid;
6397#else
6398 gid_t gid;
6399#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006400
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006401#ifdef __APPLE__
6402 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6403 PyUnicode_FSConverter, &oname,
6404 &gid))
6405#else
6406 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6407 PyUnicode_FSConverter, &oname,
6408 _Py_Gid_Converter, &gid))
6409#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006410 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006411 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006412
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006413 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006414 Py_DECREF(oname);
6415 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006416 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006417
Victor Stinner8c62be82010-05-06 00:08:46 +00006418 Py_INCREF(Py_None);
6419 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006420}
6421#endif
6422
Martin v. Löwis606edc12002-06-13 21:09:11 +00006423#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006424PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006425"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006426Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006427
6428static PyObject *
6429posix_getpgid(PyObject *self, PyObject *args)
6430{
Victor Stinner8c62be82010-05-06 00:08:46 +00006431 pid_t pid, pgid;
6432 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6433 return NULL;
6434 pgid = getpgid(pid);
6435 if (pgid < 0)
6436 return posix_error();
6437 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006438}
6439#endif /* HAVE_GETPGID */
6440
6441
Guido van Rossumb6775db1994-08-01 11:34:53 +00006442#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006443PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006444"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006445Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006446
Barry Warsaw53699e91996-12-10 23:23:01 +00006447static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006448posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006449{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006450#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006451 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006452#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006454#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006455}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006456#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006457
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006458
Guido van Rossumb6775db1994-08-01 11:34:53 +00006459#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006460PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006461"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006462Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006463
Barry Warsaw53699e91996-12-10 23:23:01 +00006464static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006465posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006466{
Guido van Rossum64933891994-10-20 21:56:42 +00006467#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006468 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006469#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006470 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006471#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006472 return posix_error();
6473 Py_INCREF(Py_None);
6474 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006475}
6476
Guido van Rossumb6775db1994-08-01 11:34:53 +00006477#endif /* HAVE_SETPGRP */
6478
Guido van Rossumad0ee831995-03-01 10:34:45 +00006479#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006480
6481#ifdef MS_WINDOWS
6482#include <tlhelp32.h>
6483
6484static PyObject*
6485win32_getppid()
6486{
6487 HANDLE snapshot;
6488 pid_t mypid;
6489 PyObject* result = NULL;
6490 BOOL have_record;
6491 PROCESSENTRY32 pe;
6492
6493 mypid = getpid(); /* This function never fails */
6494
6495 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6496 if (snapshot == INVALID_HANDLE_VALUE)
6497 return PyErr_SetFromWindowsErr(GetLastError());
6498
6499 pe.dwSize = sizeof(pe);
6500 have_record = Process32First(snapshot, &pe);
6501 while (have_record) {
6502 if (mypid == (pid_t)pe.th32ProcessID) {
6503 /* We could cache the ulong value in a static variable. */
6504 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6505 break;
6506 }
6507
6508 have_record = Process32Next(snapshot, &pe);
6509 }
6510
6511 /* If our loop exits and our pid was not found (result will be NULL)
6512 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6513 * error anyway, so let's raise it. */
6514 if (!result)
6515 result = PyErr_SetFromWindowsErr(GetLastError());
6516
6517 CloseHandle(snapshot);
6518
6519 return result;
6520}
6521#endif /*MS_WINDOWS*/
6522
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006523PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006524"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006525Return the parent's process id. If the parent process has already exited,\n\
6526Windows machines will still return its id; others systems will return the id\n\
6527of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006528
Barry Warsaw53699e91996-12-10 23:23:01 +00006529static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006530posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006531{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006532#ifdef MS_WINDOWS
6533 return win32_getppid();
6534#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006535 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006536#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006537}
6538#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006539
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006540
Fred Drake12c6e2d1999-12-14 21:25:03 +00006541#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006542PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006543"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006544Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006545
6546static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006547posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006548{
Victor Stinner8c62be82010-05-06 00:08:46 +00006549 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006550#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006551 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006552 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006553
6554 if (GetUserNameW(user_name, &num_chars)) {
6555 /* num_chars is the number of unicode chars plus null terminator */
6556 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006557 }
6558 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006559 result = PyErr_SetFromWindowsErr(GetLastError());
6560#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006561 char *name;
6562 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006563
Victor Stinner8c62be82010-05-06 00:08:46 +00006564 errno = 0;
6565 name = getlogin();
6566 if (name == NULL) {
6567 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006568 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006569 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006570 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006571 }
6572 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006573 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006574 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006575#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006576 return result;
6577}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006578#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006579
Guido van Rossumad0ee831995-03-01 10:34:45 +00006580#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006581PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006582"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006583Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006584
Barry Warsaw53699e91996-12-10 23:23:01 +00006585static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006586posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006587{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006588 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006589}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006590#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006591
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006592
Guido van Rossumad0ee831995-03-01 10:34:45 +00006593#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006594PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006595"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006596Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006597
Barry Warsaw53699e91996-12-10 23:23:01 +00006598static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006599posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006600{
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 pid_t pid;
6602 int sig;
6603 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6604 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 if (kill(pid, sig) == -1)
6606 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 Py_INCREF(Py_None);
6608 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006609}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006610#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006611
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006612#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006613PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006614"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006615Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006616
6617static PyObject *
6618posix_killpg(PyObject *self, PyObject *args)
6619{
Victor Stinner8c62be82010-05-06 00:08:46 +00006620 int sig;
6621 pid_t pgid;
6622 /* XXX some man pages make the `pgid` parameter an int, others
6623 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6624 take the same type. Moreover, pid_t is always at least as wide as
6625 int (else compilation of this module fails), which is safe. */
6626 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6627 return NULL;
6628 if (killpg(pgid, sig) == -1)
6629 return posix_error();
6630 Py_INCREF(Py_None);
6631 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006632}
6633#endif
6634
Brian Curtineb24d742010-04-12 17:16:38 +00006635#ifdef MS_WINDOWS
6636PyDoc_STRVAR(win32_kill__doc__,
6637"kill(pid, sig)\n\n\
6638Kill a process with a signal.");
6639
6640static PyObject *
6641win32_kill(PyObject *self, PyObject *args)
6642{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006643 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006644 pid_t pid;
6645 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006647
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006648 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006650
Victor Stinner8c62be82010-05-06 00:08:46 +00006651 /* Console processes which share a common console can be sent CTRL+C or
6652 CTRL+BREAK events, provided they handle said events. */
6653 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006654 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006655 err = GetLastError();
6656 PyErr_SetFromWindowsErr(err);
6657 }
6658 else
6659 Py_RETURN_NONE;
6660 }
Brian Curtineb24d742010-04-12 17:16:38 +00006661
Victor Stinner8c62be82010-05-06 00:08:46 +00006662 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6663 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006664 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 if (handle == NULL) {
6666 err = GetLastError();
6667 return PyErr_SetFromWindowsErr(err);
6668 }
Brian Curtineb24d742010-04-12 17:16:38 +00006669
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 if (TerminateProcess(handle, sig) == 0) {
6671 err = GetLastError();
6672 result = PyErr_SetFromWindowsErr(err);
6673 } else {
6674 Py_INCREF(Py_None);
6675 result = Py_None;
6676 }
Brian Curtineb24d742010-04-12 17:16:38 +00006677
Victor Stinner8c62be82010-05-06 00:08:46 +00006678 CloseHandle(handle);
6679 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006680}
6681#endif /* MS_WINDOWS */
6682
Guido van Rossumc0125471996-06-28 18:55:32 +00006683#ifdef HAVE_PLOCK
6684
6685#ifdef HAVE_SYS_LOCK_H
6686#include <sys/lock.h>
6687#endif
6688
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006689PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006690"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006691Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006692
Barry Warsaw53699e91996-12-10 23:23:01 +00006693static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006694posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006695{
Victor Stinner8c62be82010-05-06 00:08:46 +00006696 int op;
6697 if (!PyArg_ParseTuple(args, "i:plock", &op))
6698 return NULL;
6699 if (plock(op) == -1)
6700 return posix_error();
6701 Py_INCREF(Py_None);
6702 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006703}
6704#endif
6705
Guido van Rossumb6775db1994-08-01 11:34:53 +00006706#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006707PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006708"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006709Set the current process's user id.");
6710
Barry Warsaw53699e91996-12-10 23:23:01 +00006711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006712posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006713{
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006715 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006716 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006717 if (setuid(uid) < 0)
6718 return posix_error();
6719 Py_INCREF(Py_None);
6720 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006721}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006722#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006723
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006724
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006725#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006726PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006727"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006728Set the current process's effective user id.");
6729
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006730static PyObject *
6731posix_seteuid (PyObject *self, PyObject *args)
6732{
Victor Stinner8c62be82010-05-06 00:08:46 +00006733 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006734 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006735 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006736 if (seteuid(euid) < 0) {
6737 return posix_error();
6738 } else {
6739 Py_INCREF(Py_None);
6740 return Py_None;
6741 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006742}
6743#endif /* HAVE_SETEUID */
6744
6745#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006746PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006747"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006748Set the current process's effective group id.");
6749
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006750static PyObject *
6751posix_setegid (PyObject *self, PyObject *args)
6752{
Victor Stinner8c62be82010-05-06 00:08:46 +00006753 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006754 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006755 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006756 if (setegid(egid) < 0) {
6757 return posix_error();
6758 } else {
6759 Py_INCREF(Py_None);
6760 return Py_None;
6761 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006762}
6763#endif /* HAVE_SETEGID */
6764
6765#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006766PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006767"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006768Set the current process's real and effective user ids.");
6769
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006770static PyObject *
6771posix_setreuid (PyObject *self, PyObject *args)
6772{
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006774 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6775 _Py_Uid_Converter, &ruid,
6776 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 if (setreuid(ruid, euid) < 0) {
6779 return posix_error();
6780 } else {
6781 Py_INCREF(Py_None);
6782 return Py_None;
6783 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006784}
6785#endif /* HAVE_SETREUID */
6786
6787#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006788PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006789"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006790Set the current process's real and effective group ids.");
6791
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006792static PyObject *
6793posix_setregid (PyObject *self, PyObject *args)
6794{
Victor Stinner8c62be82010-05-06 00:08:46 +00006795 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006796 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6797 _Py_Gid_Converter, &rgid,
6798 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 if (setregid(rgid, egid) < 0) {
6801 return posix_error();
6802 } else {
6803 Py_INCREF(Py_None);
6804 return Py_None;
6805 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006806}
6807#endif /* HAVE_SETREGID */
6808
Guido van Rossumb6775db1994-08-01 11:34:53 +00006809#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006810PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006811"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006813
Barry Warsaw53699e91996-12-10 23:23:01 +00006814static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006815posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006816{
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006818 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 if (setgid(gid) < 0)
6821 return posix_error();
6822 Py_INCREF(Py_None);
6823 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006824}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006825#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006826
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006827#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006828PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006829"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006830Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006831
6832static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006833posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006834{
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 int i, len;
6836 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006837
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 if (!PySequence_Check(groups)) {
6839 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6840 return NULL;
6841 }
6842 len = PySequence_Size(groups);
6843 if (len > MAX_GROUPS) {
6844 PyErr_SetString(PyExc_ValueError, "too many groups");
6845 return NULL;
6846 }
6847 for(i = 0; i < len; i++) {
6848 PyObject *elem;
6849 elem = PySequence_GetItem(groups, i);
6850 if (!elem)
6851 return NULL;
6852 if (!PyLong_Check(elem)) {
6853 PyErr_SetString(PyExc_TypeError,
6854 "groups must be integers");
6855 Py_DECREF(elem);
6856 return NULL;
6857 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006858 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 Py_DECREF(elem);
6860 return NULL;
6861 }
6862 }
6863 Py_DECREF(elem);
6864 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006865
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 if (setgroups(len, grouplist) < 0)
6867 return posix_error();
6868 Py_INCREF(Py_None);
6869 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006870}
6871#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006872
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006873#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6874static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006875wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006876{
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 PyObject *result;
6878 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006879 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006880
Victor Stinner8c62be82010-05-06 00:08:46 +00006881 if (pid == -1)
6882 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006883
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 if (struct_rusage == NULL) {
6885 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6886 if (m == NULL)
6887 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006888 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 Py_DECREF(m);
6890 if (struct_rusage == NULL)
6891 return NULL;
6892 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006893
Victor Stinner8c62be82010-05-06 00:08:46 +00006894 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6895 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6896 if (!result)
6897 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006898
6899#ifndef doubletime
6900#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6901#endif
6902
Victor Stinner8c62be82010-05-06 00:08:46 +00006903 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006904 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006905 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006906 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006907#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6909 SET_INT(result, 2, ru->ru_maxrss);
6910 SET_INT(result, 3, ru->ru_ixrss);
6911 SET_INT(result, 4, ru->ru_idrss);
6912 SET_INT(result, 5, ru->ru_isrss);
6913 SET_INT(result, 6, ru->ru_minflt);
6914 SET_INT(result, 7, ru->ru_majflt);
6915 SET_INT(result, 8, ru->ru_nswap);
6916 SET_INT(result, 9, ru->ru_inblock);
6917 SET_INT(result, 10, ru->ru_oublock);
6918 SET_INT(result, 11, ru->ru_msgsnd);
6919 SET_INT(result, 12, ru->ru_msgrcv);
6920 SET_INT(result, 13, ru->ru_nsignals);
6921 SET_INT(result, 14, ru->ru_nvcsw);
6922 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006923#undef SET_INT
6924
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 if (PyErr_Occurred()) {
6926 Py_DECREF(result);
6927 return NULL;
6928 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006929
Victor Stinner8c62be82010-05-06 00:08:46 +00006930 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006931}
6932#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6933
6934#ifdef HAVE_WAIT3
6935PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006936"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006937Wait for completion of a child process.");
6938
6939static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006940posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006941{
Victor Stinner8c62be82010-05-06 00:08:46 +00006942 pid_t pid;
6943 int options;
6944 struct rusage ru;
6945 WAIT_TYPE status;
6946 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006947
Victor Stinner4195b5c2012-02-08 23:03:19 +01006948 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006950
Victor Stinner8c62be82010-05-06 00:08:46 +00006951 Py_BEGIN_ALLOW_THREADS
6952 pid = wait3(&status, options, &ru);
6953 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006954
Victor Stinner4195b5c2012-02-08 23:03:19 +01006955 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006956}
6957#endif /* HAVE_WAIT3 */
6958
6959#ifdef HAVE_WAIT4
6960PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006961"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006962Wait for completion of a given child process.");
6963
6964static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006965posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006966{
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 pid_t pid;
6968 int options;
6969 struct rusage ru;
6970 WAIT_TYPE status;
6971 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006972
Victor Stinner4195b5c2012-02-08 23:03:19 +01006973 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006975
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 Py_BEGIN_ALLOW_THREADS
6977 pid = wait4(pid, &status, options, &ru);
6978 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006979
Victor Stinner4195b5c2012-02-08 23:03:19 +01006980 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006981}
6982#endif /* HAVE_WAIT4 */
6983
Ross Lagerwall7807c352011-03-17 20:20:30 +02006984#if defined(HAVE_WAITID) && !defined(__APPLE__)
6985PyDoc_STRVAR(posix_waitid__doc__,
6986"waitid(idtype, id, options) -> waitid_result\n\n\
6987Wait for the completion of one or more child processes.\n\n\
6988idtype can be P_PID, P_PGID or P_ALL.\n\
6989id specifies the pid to wait on.\n\
6990options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6991or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6992Returns either waitid_result or None if WNOHANG is specified and there are\n\
6993no children in a waitable state.");
6994
6995static PyObject *
6996posix_waitid(PyObject *self, PyObject *args)
6997{
6998 PyObject *result;
6999 idtype_t idtype;
7000 id_t id;
7001 int options, res;
7002 siginfo_t si;
7003 si.si_pid = 0;
7004 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
7005 return NULL;
7006 Py_BEGIN_ALLOW_THREADS
7007 res = waitid(idtype, id, &si, options);
7008 Py_END_ALLOW_THREADS
7009 if (res == -1)
7010 return posix_error();
7011
7012 if (si.si_pid == 0)
7013 Py_RETURN_NONE;
7014
7015 result = PyStructSequence_New(&WaitidResultType);
7016 if (!result)
7017 return NULL;
7018
7019 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007020 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007021 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7022 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7023 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7024 if (PyErr_Occurred()) {
7025 Py_DECREF(result);
7026 return NULL;
7027 }
7028
7029 return result;
7030}
7031#endif
7032
Guido van Rossumb6775db1994-08-01 11:34:53 +00007033#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007034PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007035"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007036Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007037
Barry Warsaw53699e91996-12-10 23:23:01 +00007038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007039posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007040{
Victor Stinner8c62be82010-05-06 00:08:46 +00007041 pid_t pid;
7042 int options;
7043 WAIT_TYPE status;
7044 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007045
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7047 return NULL;
7048 Py_BEGIN_ALLOW_THREADS
7049 pid = waitpid(pid, &status, options);
7050 Py_END_ALLOW_THREADS
7051 if (pid == -1)
7052 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007053
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007055}
7056
Tim Petersab034fa2002-02-01 11:27:43 +00007057#elif defined(HAVE_CWAIT)
7058
7059/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007060PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007061"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007062"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007063
7064static PyObject *
7065posix_waitpid(PyObject *self, PyObject *args)
7066{
Victor Stinner8c62be82010-05-06 00:08:46 +00007067 Py_intptr_t pid;
7068 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007069
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007070 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007071 return NULL;
7072 Py_BEGIN_ALLOW_THREADS
7073 pid = _cwait(&status, pid, options);
7074 Py_END_ALLOW_THREADS
7075 if (pid == -1)
7076 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007077
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007079 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007080}
7081#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007082
Guido van Rossumad0ee831995-03-01 10:34:45 +00007083#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007084PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007085"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007086Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007087
Barry Warsaw53699e91996-12-10 23:23:01 +00007088static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007089posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007090{
Victor Stinner8c62be82010-05-06 00:08:46 +00007091 pid_t pid;
7092 WAIT_TYPE status;
7093 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007094
Victor Stinner8c62be82010-05-06 00:08:46 +00007095 Py_BEGIN_ALLOW_THREADS
7096 pid = wait(&status);
7097 Py_END_ALLOW_THREADS
7098 if (pid == -1)
7099 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007100
Victor Stinner8c62be82010-05-06 00:08:46 +00007101 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007102}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007103#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007104
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007105
Larry Hastings9cf065c2012-06-22 16:30:09 -07007106#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7107PyDoc_STRVAR(readlink__doc__,
7108"readlink(path, *, dir_fd=None) -> path\n\n\
7109Return a string representing the path to which the symbolic link points.\n\
7110\n\
7111If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7112 and path should be relative; path will then be relative to that directory.\n\
7113dir_fd may not be implemented on your platform.\n\
7114 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007115#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007116
Guido van Rossumb6775db1994-08-01 11:34:53 +00007117#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007118
Barry Warsaw53699e91996-12-10 23:23:01 +00007119static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007120posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007121{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122 path_t path;
7123 int dir_fd = DEFAULT_DIR_FD;
7124 char buffer[MAXPATHLEN];
7125 ssize_t length;
7126 PyObject *return_value = NULL;
7127 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007128
Larry Hastings9cf065c2012-06-22 16:30:09 -07007129 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007130 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007131 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7132 path_converter, &path,
7133#ifdef HAVE_READLINKAT
7134 dir_fd_converter, &dir_fd
7135#else
7136 dir_fd_unavailable, &dir_fd
7137#endif
7138 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007139 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007140
Victor Stinner8c62be82010-05-06 00:08:46 +00007141 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007142#ifdef HAVE_READLINKAT
7143 if (dir_fd != DEFAULT_DIR_FD)
7144 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007145 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007146#endif
7147 length = readlink(path.narrow, buffer, sizeof(buffer));
7148 Py_END_ALLOW_THREADS
7149
7150 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007151 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007152 goto exit;
7153 }
7154
7155 if (PyUnicode_Check(path.object))
7156 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7157 else
7158 return_value = PyBytes_FromStringAndSize(buffer, length);
7159exit:
7160 path_cleanup(&path);
7161 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007162}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007163
7164
Guido van Rossumb6775db1994-08-01 11:34:53 +00007165#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007166
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007167
Larry Hastings9cf065c2012-06-22 16:30:09 -07007168#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007169PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007170"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7171Create a symbolic link pointing to src named dst.\n\n\
7172target_is_directory is required on Windows if the target is to be\n\
7173 interpreted as a directory. (On Windows, symlink requires\n\
7174 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7175 target_is_directory is ignored on non-Windows platforms.\n\
7176\n\
7177If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7178 and path should be relative; path will then be relative to that directory.\n\
7179dir_fd may not be implemented on your platform.\n\
7180 If it is unavailable, using it will raise a NotImplementedError.");
7181
7182#if defined(MS_WINDOWS)
7183
7184/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7185static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7186static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007187
Larry Hastings9cf065c2012-06-22 16:30:09 -07007188static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007189check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007190{
7191 HINSTANCE hKernel32;
7192 /* only recheck */
7193 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7194 return 1;
7195 hKernel32 = GetModuleHandleW(L"KERNEL32");
7196 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7197 "CreateSymbolicLinkW");
7198 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7199 "CreateSymbolicLinkA");
7200 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7201}
7202
Victor Stinner31b3b922013-06-05 01:49:17 +02007203/* Remove the last portion of the path */
7204static void
7205_dirnameW(WCHAR *path)
7206{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007207 WCHAR *ptr;
7208
7209 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007210 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007211 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007212 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007213 }
7214 *ptr = 0;
7215}
7216
Victor Stinner31b3b922013-06-05 01:49:17 +02007217/* Remove the last portion of the path */
7218static void
7219_dirnameA(char *path)
7220{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007221 char *ptr;
7222
7223 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007224 for(ptr = path + strlen(path); ptr != path; ptr--) {
7225 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007226 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007227 }
7228 *ptr = 0;
7229}
7230
Victor Stinner31b3b922013-06-05 01:49:17 +02007231/* Is this path absolute? */
7232static int
7233_is_absW(const WCHAR *path)
7234{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007235 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7236
7237}
7238
Victor Stinner31b3b922013-06-05 01:49:17 +02007239/* Is this path absolute? */
7240static int
7241_is_absA(const char *path)
7242{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007243 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7244
7245}
7246
Victor Stinner31b3b922013-06-05 01:49:17 +02007247/* join root and rest with a backslash */
7248static void
7249_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7250{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007251 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007252
Victor Stinner31b3b922013-06-05 01:49:17 +02007253 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007254 wcscpy(dest_path, rest);
7255 return;
7256 }
7257
7258 root_len = wcslen(root);
7259
7260 wcscpy(dest_path, root);
7261 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007262 dest_path[root_len] = L'\\';
7263 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007264 }
7265 wcscpy(dest_path+root_len, rest);
7266}
7267
Victor Stinner31b3b922013-06-05 01:49:17 +02007268/* join root and rest with a backslash */
7269static void
7270_joinA(char *dest_path, const char *root, const char *rest)
7271{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007272 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007273
Victor Stinner31b3b922013-06-05 01:49:17 +02007274 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007275 strcpy(dest_path, rest);
7276 return;
7277 }
7278
7279 root_len = strlen(root);
7280
7281 strcpy(dest_path, root);
7282 if(root_len) {
7283 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007284 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007285 }
7286 strcpy(dest_path+root_len, rest);
7287}
7288
Victor Stinner31b3b922013-06-05 01:49:17 +02007289/* Return True if the path at src relative to dest is a directory */
7290static int
7291_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007292{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007293 WIN32_FILE_ATTRIBUTE_DATA src_info;
7294 WCHAR dest_parent[MAX_PATH];
7295 WCHAR src_resolved[MAX_PATH] = L"";
7296
7297 /* dest_parent = os.path.dirname(dest) */
7298 wcscpy(dest_parent, dest);
7299 _dirnameW(dest_parent);
7300 /* src_resolved = os.path.join(dest_parent, src) */
7301 _joinW(src_resolved, dest_parent, src);
7302 return (
7303 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7304 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7305 );
7306}
7307
Victor Stinner31b3b922013-06-05 01:49:17 +02007308/* Return True if the path at src relative to dest is a directory */
7309static int
7310_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007311{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007312 WIN32_FILE_ATTRIBUTE_DATA src_info;
7313 char dest_parent[MAX_PATH];
7314 char src_resolved[MAX_PATH] = "";
7315
7316 /* dest_parent = os.path.dirname(dest) */
7317 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007318 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007319 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007320 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007321 return (
7322 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7323 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7324 );
7325}
7326
Larry Hastings9cf065c2012-06-22 16:30:09 -07007327#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007328
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007329static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007330posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007331{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007332 path_t src;
7333 path_t dst;
7334 int dir_fd = DEFAULT_DIR_FD;
7335 int target_is_directory = 0;
7336 static char *keywords[] = {"src", "dst", "target_is_directory",
7337 "dir_fd", NULL};
7338 PyObject *return_value;
7339#ifdef MS_WINDOWS
7340 DWORD result;
7341#else
7342 int result;
7343#endif
7344
7345 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007346 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007347 src.argument_name = "src";
7348 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007349 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007350 dst.argument_name = "dst";
7351
7352#ifdef MS_WINDOWS
7353 if (!check_CreateSymbolicLink()) {
7354 PyErr_SetString(PyExc_NotImplementedError,
7355 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007356 return NULL;
7357 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007358 if (!win32_can_symlink) {
7359 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007360 return NULL;
7361 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007362#endif
7363
7364 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7365 keywords,
7366 path_converter, &src,
7367 path_converter, &dst,
7368 &target_is_directory,
7369#ifdef HAVE_SYMLINKAT
7370 dir_fd_converter, &dir_fd
7371#else
7372 dir_fd_unavailable, &dir_fd
7373#endif
7374 ))
7375 return NULL;
7376
7377 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7378 PyErr_SetString(PyExc_ValueError,
7379 "symlink: src and dst must be the same type");
7380 return_value = NULL;
7381 goto exit;
7382 }
7383
7384#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007385
Larry Hastings9cf065c2012-06-22 16:30:09 -07007386 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007387 if (dst.wide) {
7388 /* if src is a directory, ensure target_is_directory==1 */
7389 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007390 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7391 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007392 }
7393 else {
7394 /* if src is a directory, ensure target_is_directory==1 */
7395 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007396 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7397 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007398 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007399 Py_END_ALLOW_THREADS
7400
7401 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08007402 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007403 goto exit;
7404 }
7405
7406#else
7407
7408 Py_BEGIN_ALLOW_THREADS
7409#if HAVE_SYMLINKAT
7410 if (dir_fd != DEFAULT_DIR_FD)
7411 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7412 else
7413#endif
7414 result = symlink(src.narrow, dst.narrow);
7415 Py_END_ALLOW_THREADS
7416
7417 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08007418 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007419 goto exit;
7420 }
7421#endif
7422
7423 return_value = Py_None;
7424 Py_INCREF(Py_None);
7425 goto exit; /* silence "unused label" warning */
7426exit:
7427 path_cleanup(&src);
7428 path_cleanup(&dst);
7429 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007430}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007431
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007432#endif /* HAVE_SYMLINK */
7433
Larry Hastings9cf065c2012-06-22 16:30:09 -07007434
Brian Curtind40e6f72010-07-08 21:39:08 +00007435#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7436
Brian Curtind40e6f72010-07-08 21:39:08 +00007437static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007438win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007439{
7440 wchar_t *path;
7441 DWORD n_bytes_returned;
7442 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007443 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007444 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007445 HANDLE reparse_point_handle;
7446
7447 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7448 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7449 wchar_t *print_name;
7450
Larry Hastings9cf065c2012-06-22 16:30:09 -07007451 static char *keywords[] = {"path", "dir_fd", NULL};
7452
7453 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7454 &po,
7455 dir_fd_unavailable, &dir_fd
7456 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007457 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007458
Victor Stinnereb5657a2011-09-30 01:44:27 +02007459 path = PyUnicode_AsUnicode(po);
7460 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007461 return NULL;
7462
7463 /* First get a handle to the reparse point */
7464 Py_BEGIN_ALLOW_THREADS
7465 reparse_point_handle = CreateFileW(
7466 path,
7467 0,
7468 0,
7469 0,
7470 OPEN_EXISTING,
7471 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7472 0);
7473 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007474
Brian Curtind40e6f72010-07-08 21:39:08 +00007475 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007476 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007477
Brian Curtind40e6f72010-07-08 21:39:08 +00007478 Py_BEGIN_ALLOW_THREADS
7479 /* New call DeviceIoControl to read the reparse point */
7480 io_result = DeviceIoControl(
7481 reparse_point_handle,
7482 FSCTL_GET_REPARSE_POINT,
7483 0, 0, /* in buffer */
7484 target_buffer, sizeof(target_buffer),
7485 &n_bytes_returned,
7486 0 /* we're not using OVERLAPPED_IO */
7487 );
7488 CloseHandle(reparse_point_handle);
7489 Py_END_ALLOW_THREADS
7490
7491 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007492 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007493
7494 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7495 {
7496 PyErr_SetString(PyExc_ValueError,
7497 "not a symbolic link");
7498 return NULL;
7499 }
Brian Curtin74e45612010-07-09 15:58:59 +00007500 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7501 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7502
7503 result = PyUnicode_FromWideChar(print_name,
7504 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007505 return result;
7506}
7507
7508#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7509
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007510
Larry Hastings605a62d2012-06-24 04:33:36 -07007511static PyStructSequence_Field times_result_fields[] = {
7512 {"user", "user time"},
7513 {"system", "system time"},
7514 {"children_user", "user time of children"},
7515 {"children_system", "system time of children"},
7516 {"elapsed", "elapsed time since an arbitrary point in the past"},
7517 {NULL}
7518};
7519
7520PyDoc_STRVAR(times_result__doc__,
7521"times_result: Result from os.times().\n\n\
7522This object may be accessed either as a tuple of\n\
7523 (user, system, children_user, children_system, elapsed),\n\
7524or via the attributes user, system, children_user, children_system,\n\
7525and elapsed.\n\
7526\n\
7527See os.times for more information.");
7528
7529static PyStructSequence_Desc times_result_desc = {
7530 "times_result", /* name */
7531 times_result__doc__, /* doc */
7532 times_result_fields,
7533 5
7534};
7535
7536static PyTypeObject TimesResultType;
7537
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007538#ifdef MS_WINDOWS
7539#define HAVE_TIMES /* mandatory, for the method table */
7540#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007541
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007542#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007543
7544static PyObject *
7545build_times_result(double user, double system,
7546 double children_user, double children_system,
7547 double elapsed)
7548{
7549 PyObject *value = PyStructSequence_New(&TimesResultType);
7550 if (value == NULL)
7551 return NULL;
7552
7553#define SET(i, field) \
7554 { \
7555 PyObject *o = PyFloat_FromDouble(field); \
7556 if (!o) { \
7557 Py_DECREF(value); \
7558 return NULL; \
7559 } \
7560 PyStructSequence_SET_ITEM(value, i, o); \
7561 } \
7562
7563 SET(0, user);
7564 SET(1, system);
7565 SET(2, children_user);
7566 SET(3, children_system);
7567 SET(4, elapsed);
7568
7569#undef SET
7570
7571 return value;
7572}
7573
7574PyDoc_STRVAR(posix_times__doc__,
7575"times() -> times_result\n\n\
7576Return an object containing floating point numbers indicating process\n\
7577times. The object behaves like a named tuple with these fields:\n\
7578 (utime, stime, cutime, cstime, elapsed_time)");
7579
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007580#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007581static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007582posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007583{
Victor Stinner8c62be82010-05-06 00:08:46 +00007584 FILETIME create, exit, kernel, user;
7585 HANDLE hProc;
7586 hProc = GetCurrentProcess();
7587 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7588 /* The fields of a FILETIME structure are the hi and lo part
7589 of a 64-bit value expressed in 100 nanosecond units.
7590 1e7 is one second in such units; 1e-7 the inverse.
7591 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7592 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007593 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007594 (double)(user.dwHighDateTime*429.4967296 +
7595 user.dwLowDateTime*1e-7),
7596 (double)(kernel.dwHighDateTime*429.4967296 +
7597 kernel.dwLowDateTime*1e-7),
7598 (double)0,
7599 (double)0,
7600 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007601}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007602#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007603#define NEED_TICKS_PER_SECOND
7604static long ticks_per_second = -1;
7605static PyObject *
7606posix_times(PyObject *self, PyObject *noargs)
7607{
7608 struct tms t;
7609 clock_t c;
7610 errno = 0;
7611 c = times(&t);
7612 if (c == (clock_t) -1)
7613 return posix_error();
7614 return build_times_result(
7615 (double)t.tms_utime / ticks_per_second,
7616 (double)t.tms_stime / ticks_per_second,
7617 (double)t.tms_cutime / ticks_per_second,
7618 (double)t.tms_cstime / ticks_per_second,
7619 (double)c / ticks_per_second);
7620}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007621#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007622
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007623#endif /* HAVE_TIMES */
7624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007625
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007626#ifdef HAVE_GETSID
7627PyDoc_STRVAR(posix_getsid__doc__,
7628"getsid(pid) -> sid\n\n\
7629Call the system call getsid().");
7630
7631static PyObject *
7632posix_getsid(PyObject *self, PyObject *args)
7633{
Victor Stinner8c62be82010-05-06 00:08:46 +00007634 pid_t pid;
7635 int sid;
7636 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7637 return NULL;
7638 sid = getsid(pid);
7639 if (sid < 0)
7640 return posix_error();
7641 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007642}
7643#endif /* HAVE_GETSID */
7644
7645
Guido van Rossumb6775db1994-08-01 11:34:53 +00007646#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007647PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007648"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007649Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007650
Barry Warsaw53699e91996-12-10 23:23:01 +00007651static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007652posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007653{
Victor Stinner8c62be82010-05-06 00:08:46 +00007654 if (setsid() < 0)
7655 return posix_error();
7656 Py_INCREF(Py_None);
7657 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007658}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007659#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007660
Guido van Rossumb6775db1994-08-01 11:34:53 +00007661#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007662PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007663"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007664Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007665
Barry Warsaw53699e91996-12-10 23:23:01 +00007666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007667posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007668{
Victor Stinner8c62be82010-05-06 00:08:46 +00007669 pid_t pid;
7670 int pgrp;
7671 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7672 return NULL;
7673 if (setpgid(pid, pgrp) < 0)
7674 return posix_error();
7675 Py_INCREF(Py_None);
7676 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007677}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007678#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007679
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007680
Guido van Rossumb6775db1994-08-01 11:34:53 +00007681#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007682PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007683"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007684Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007685
Barry Warsaw53699e91996-12-10 23:23:01 +00007686static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007687posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007688{
Victor Stinner8c62be82010-05-06 00:08:46 +00007689 int fd;
7690 pid_t pgid;
7691 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7692 return NULL;
7693 pgid = tcgetpgrp(fd);
7694 if (pgid < 0)
7695 return posix_error();
7696 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007697}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007698#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007699
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007700
Guido van Rossumb6775db1994-08-01 11:34:53 +00007701#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007702PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007703"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007704Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007705
Barry Warsaw53699e91996-12-10 23:23:01 +00007706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007707posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007708{
Victor Stinner8c62be82010-05-06 00:08:46 +00007709 int fd;
7710 pid_t pgid;
7711 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7712 return NULL;
7713 if (tcsetpgrp(fd, pgid) < 0)
7714 return posix_error();
7715 Py_INCREF(Py_None);
7716 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007717}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007718#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007719
Guido van Rossum687dd131993-05-17 08:34:16 +00007720/* Functions acting on file descriptors */
7721
Victor Stinnerdaf45552013-08-28 00:53:59 +02007722#ifdef O_CLOEXEC
7723extern int _Py_open_cloexec_works;
7724#endif
7725
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007726PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007727"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7728Open a file for low level IO. Returns a file handle (integer).\n\
7729\n\
7730If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7731 and path should be relative; path will then be relative to that directory.\n\
7732dir_fd may not be implemented on your platform.\n\
7733 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007734
Barry Warsaw53699e91996-12-10 23:23:01 +00007735static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007736posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007737{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007738 path_t path;
7739 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007740 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007741 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007742 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007743 PyObject *return_value = NULL;
7744 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Victor Stinnerdaf45552013-08-28 00:53:59 +02007745#ifdef O_CLOEXEC
7746 int *atomic_flag_works = &_Py_open_cloexec_works;
7747#elif !defined(MS_WINDOWS)
7748 int *atomic_flag_works = NULL;
7749#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007750
Larry Hastings9cf065c2012-06-22 16:30:09 -07007751 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007752 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007753 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7754 path_converter, &path,
7755 &flags, &mode,
7756#ifdef HAVE_OPENAT
7757 dir_fd_converter, &dir_fd
7758#else
7759 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007760#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007761 ))
7762 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007763
Victor Stinnerdaf45552013-08-28 00:53:59 +02007764#ifdef MS_WINDOWS
7765 flags |= O_NOINHERIT;
7766#elif defined(O_CLOEXEC)
7767 flags |= O_CLOEXEC;
7768#endif
7769
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007771#ifdef MS_WINDOWS
7772 if (path.wide)
7773 fd = _wopen(path.wide, flags, mode);
7774 else
7775#endif
7776#ifdef HAVE_OPENAT
7777 if (dir_fd != DEFAULT_DIR_FD)
7778 fd = openat(dir_fd, path.narrow, flags, mode);
7779 else
7780#endif
7781 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007782 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007783
Larry Hastings9cf065c2012-06-22 16:30:09 -07007784 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007785 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007786 goto exit;
7787 }
7788
Victor Stinnerdaf45552013-08-28 00:53:59 +02007789#ifndef MS_WINDOWS
7790 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7791 close(fd);
7792 goto exit;
7793 }
7794#endif
7795
Larry Hastings9cf065c2012-06-22 16:30:09 -07007796 return_value = PyLong_FromLong((long)fd);
7797
7798exit:
7799 path_cleanup(&path);
7800 return return_value;
7801}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007802
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007803PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007804"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007805Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007806
Benjamin Peterson932bba32014-02-11 10:16:16 -05007807/*
7808The underscore at end of function name avoids a name clash with the libc
7809function posix_close.
7810*/
Barry Warsaw53699e91996-12-10 23:23:01 +00007811static PyObject *
Benjamin Peterson932bba32014-02-11 10:16:16 -05007812posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007813{
Victor Stinner8c62be82010-05-06 00:08:46 +00007814 int fd, res;
7815 if (!PyArg_ParseTuple(args, "i:close", &fd))
7816 return NULL;
7817 if (!_PyVerify_fd(fd))
7818 return posix_error();
7819 Py_BEGIN_ALLOW_THREADS
7820 res = close(fd);
7821 Py_END_ALLOW_THREADS
7822 if (res < 0)
7823 return posix_error();
7824 Py_INCREF(Py_None);
7825 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007826}
7827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007828
Victor Stinner8c62be82010-05-06 00:08:46 +00007829PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007830"closerange(fd_low, fd_high)\n\n\
7831Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7832
7833static PyObject *
7834posix_closerange(PyObject *self, PyObject *args)
7835{
Victor Stinner8c62be82010-05-06 00:08:46 +00007836 int fd_from, fd_to, i;
7837 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7838 return NULL;
7839 Py_BEGIN_ALLOW_THREADS
7840 for (i = fd_from; i < fd_to; i++)
7841 if (_PyVerify_fd(i))
7842 close(i);
7843 Py_END_ALLOW_THREADS
7844 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007845}
7846
7847
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007848PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007849"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007850Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007851
Barry Warsaw53699e91996-12-10 23:23:01 +00007852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007853posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007854{
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 int fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007856
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7858 return NULL;
Tim Golden23005082013-10-25 11:22:37 +01007859
Victor Stinnerdaf45552013-08-28 00:53:59 +02007860 fd = _Py_dup(fd);
7861 if (fd == -1)
7862 return NULL;
7863
Victor Stinner8c62be82010-05-06 00:08:46 +00007864 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007865}
7866
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007867
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007868PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007869"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007870Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007871
Barry Warsaw53699e91996-12-10 23:23:01 +00007872static PyObject *
Victor Stinnerdaf45552013-08-28 00:53:59 +02007873posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007874{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007875 static char *keywords[] = {"fd", "fd2", "inheritable", NULL};
7876 int fd, fd2;
7877 int inheritable = 1;
7878 int res;
7879#if defined(HAVE_DUP3) && \
7880 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7881 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7882 int dup3_works = -1;
7883#endif
7884
7885 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords,
7886 &fd, &fd2, &inheritable))
Victor Stinner8c62be82010-05-06 00:08:46 +00007887 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007888
Victor Stinner8c62be82010-05-06 00:08:46 +00007889 if (!_PyVerify_fd_dup2(fd, fd2))
7890 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007891
7892#ifdef MS_WINDOWS
7893 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007894 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007895 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007896 if (res < 0)
7897 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007898
7899 /* Character files like console cannot be make non-inheritable */
7900 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7901 close(fd2);
7902 return NULL;
7903 }
7904
7905#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7906 Py_BEGIN_ALLOW_THREADS
7907 if (!inheritable)
7908 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7909 else
7910 res = dup2(fd, fd2);
7911 Py_END_ALLOW_THREADS
7912 if (res < 0)
7913 return posix_error();
7914
7915#else
7916
7917#ifdef HAVE_DUP3
7918 if (!inheritable && dup3_works != 0) {
7919 Py_BEGIN_ALLOW_THREADS
7920 res = dup3(fd, fd2, O_CLOEXEC);
7921 Py_END_ALLOW_THREADS
7922 if (res < 0) {
7923 if (dup3_works == -1)
7924 dup3_works = (errno != ENOSYS);
7925 if (dup3_works)
7926 return posix_error();
7927 }
7928 }
7929
7930 if (inheritable || dup3_works == 0)
7931 {
7932#endif
7933 Py_BEGIN_ALLOW_THREADS
7934 res = dup2(fd, fd2);
7935 Py_END_ALLOW_THREADS
7936 if (res < 0)
7937 return posix_error();
7938
7939 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7940 close(fd2);
7941 return NULL;
7942 }
7943#ifdef HAVE_DUP3
7944 }
7945#endif
7946
7947#endif
7948
Victor Stinner8c62be82010-05-06 00:08:46 +00007949 Py_INCREF(Py_None);
7950 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007951}
7952
Ross Lagerwall7807c352011-03-17 20:20:30 +02007953#ifdef HAVE_LOCKF
7954PyDoc_STRVAR(posix_lockf__doc__,
7955"lockf(fd, cmd, len)\n\n\
7956Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7957fd is an open file descriptor.\n\
7958cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7959F_TEST.\n\
7960len specifies the section of the file to lock.");
7961
7962static PyObject *
7963posix_lockf(PyObject *self, PyObject *args)
7964{
7965 int fd, cmd, res;
7966 off_t len;
7967 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7968 &fd, &cmd, _parse_off_t, &len))
7969 return NULL;
7970
7971 Py_BEGIN_ALLOW_THREADS
7972 res = lockf(fd, cmd, len);
7973 Py_END_ALLOW_THREADS
7974
7975 if (res < 0)
7976 return posix_error();
7977
7978 Py_RETURN_NONE;
7979}
7980#endif
7981
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007982
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007983PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007984"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007985Set the current position of a file descriptor.\n\
7986Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007987
Barry Warsaw53699e91996-12-10 23:23:01 +00007988static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007989posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007990{
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007992#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007994#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007996#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007997 PyObject *posobj;
7998 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00008000#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008001 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8002 switch (how) {
8003 case 0: how = SEEK_SET; break;
8004 case 1: how = SEEK_CUR; break;
8005 case 2: how = SEEK_END; break;
8006 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008007#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008008
Ross Lagerwall8e749672011-03-17 21:54:07 +02008009#if !defined(HAVE_LARGEFILE_SUPPORT)
8010 pos = PyLong_AsLong(posobj);
8011#else
8012 pos = PyLong_AsLongLong(posobj);
8013#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 if (PyErr_Occurred())
8015 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008016
Victor Stinner8c62be82010-05-06 00:08:46 +00008017 if (!_PyVerify_fd(fd))
8018 return posix_error();
8019 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008020#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00008022#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008023 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00008024#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 Py_END_ALLOW_THREADS
8026 if (res < 0)
8027 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008028
8029#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008030 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008031#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008032 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008033#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008034}
8035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008036
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008037PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008038"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008039Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008040
Barry Warsaw53699e91996-12-10 23:23:01 +00008041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008042posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008043{
Victor Stinner8c62be82010-05-06 00:08:46 +00008044 int fd, size;
8045 Py_ssize_t n;
8046 PyObject *buffer;
8047 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
8048 return NULL;
8049 if (size < 0) {
8050 errno = EINVAL;
8051 return posix_error();
8052 }
8053 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8054 if (buffer == NULL)
8055 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00008056 if (!_PyVerify_fd(fd)) {
8057 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00008058 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00008059 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008060 Py_BEGIN_ALLOW_THREADS
8061 n = read(fd, PyBytes_AS_STRING(buffer), size);
8062 Py_END_ALLOW_THREADS
8063 if (n < 0) {
8064 Py_DECREF(buffer);
8065 return posix_error();
8066 }
8067 if (n != size)
8068 _PyBytes_Resize(&buffer, n);
8069 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008070}
8071
Ross Lagerwall7807c352011-03-17 20:20:30 +02008072#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8073 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008074static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008075iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8076{
8077 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008078 Py_ssize_t blen, total = 0;
8079
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008080 *iov = PyMem_New(struct iovec, cnt);
8081 if (*iov == NULL) {
8082 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008083 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008084 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008085
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008086 *buf = PyMem_New(Py_buffer, cnt);
8087 if (*buf == NULL) {
8088 PyMem_Del(*iov);
8089 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008090 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008091 }
8092
8093 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008094 PyObject *item = PySequence_GetItem(seq, i);
8095 if (item == NULL)
8096 goto fail;
8097 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8098 Py_DECREF(item);
8099 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008100 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008101 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008102 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008103 blen = (*buf)[i].len;
8104 (*iov)[i].iov_len = blen;
8105 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008106 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008107 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008108
8109fail:
8110 PyMem_Del(*iov);
8111 for (j = 0; j < i; j++) {
8112 PyBuffer_Release(&(*buf)[j]);
8113 }
8114 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008115 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008116}
8117
8118static void
8119iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8120{
8121 int i;
8122 PyMem_Del(iov);
8123 for (i = 0; i < cnt; i++) {
8124 PyBuffer_Release(&buf[i]);
8125 }
8126 PyMem_Del(buf);
8127}
8128#endif
8129
Ross Lagerwall7807c352011-03-17 20:20:30 +02008130#ifdef HAVE_READV
8131PyDoc_STRVAR(posix_readv__doc__,
8132"readv(fd, buffers) -> bytesread\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008133Read from a file descriptor fd into a number of mutable, bytes-like\n\
8134objects (\"buffers\"). readv will transfer data into each buffer\n\
8135until it is full and then move on to the next buffer in the sequence\n\
8136to hold the rest of the data.\n\n\
8137readv returns the total number of bytes read (which may be less than\n\
8138the total capacity of all the buffers.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008139
8140static PyObject *
8141posix_readv(PyObject *self, PyObject *args)
8142{
8143 int fd, cnt;
8144 Py_ssize_t n;
8145 PyObject *seq;
8146 struct iovec *iov;
8147 Py_buffer *buf;
8148
8149 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8150 return NULL;
8151 if (!PySequence_Check(seq)) {
8152 PyErr_SetString(PyExc_TypeError,
8153 "readv() arg 2 must be a sequence");
8154 return NULL;
8155 }
8156 cnt = PySequence_Size(seq);
8157
Victor Stinner57ddf782014-01-08 15:21:28 +01008158 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE) < 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008159 return NULL;
8160
8161 Py_BEGIN_ALLOW_THREADS
8162 n = readv(fd, iov, cnt);
8163 Py_END_ALLOW_THREADS
8164
8165 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008166 if (n < 0)
8167 return posix_error();
8168
Ross Lagerwall7807c352011-03-17 20:20:30 +02008169 return PyLong_FromSsize_t(n);
8170}
8171#endif
8172
8173#ifdef HAVE_PREAD
8174PyDoc_STRVAR(posix_pread__doc__,
8175"pread(fd, buffersize, offset) -> string\n\n\
8176Read from a file descriptor, fd, at a position of offset. It will read up\n\
8177to buffersize number of bytes. The file offset remains unchanged.");
8178
8179static PyObject *
8180posix_pread(PyObject *self, PyObject *args)
8181{
8182 int fd, size;
8183 off_t offset;
8184 Py_ssize_t n;
8185 PyObject *buffer;
8186 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8187 return NULL;
8188
8189 if (size < 0) {
8190 errno = EINVAL;
8191 return posix_error();
8192 }
8193 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8194 if (buffer == NULL)
8195 return NULL;
8196 if (!_PyVerify_fd(fd)) {
8197 Py_DECREF(buffer);
8198 return posix_error();
8199 }
8200 Py_BEGIN_ALLOW_THREADS
8201 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8202 Py_END_ALLOW_THREADS
8203 if (n < 0) {
8204 Py_DECREF(buffer);
8205 return posix_error();
8206 }
8207 if (n != size)
8208 _PyBytes_Resize(&buffer, n);
8209 return buffer;
8210}
8211#endif
8212
8213PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008214"write(fd, data) -> byteswritten\n\n\
8215Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008216
8217static PyObject *
8218posix_write(PyObject *self, PyObject *args)
8219{
8220 Py_buffer pbuf;
8221 int fd;
8222 Py_ssize_t size, len;
8223
8224 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8225 return NULL;
8226 if (!_PyVerify_fd(fd)) {
8227 PyBuffer_Release(&pbuf);
8228 return posix_error();
8229 }
8230 len = pbuf.len;
8231 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008232#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008233 if (len > INT_MAX)
8234 len = INT_MAX;
8235 size = write(fd, pbuf.buf, (int)len);
8236#else
8237 size = write(fd, pbuf.buf, len);
8238#endif
8239 Py_END_ALLOW_THREADS
8240 PyBuffer_Release(&pbuf);
8241 if (size < 0)
8242 return posix_error();
8243 return PyLong_FromSsize_t(size);
8244}
8245
8246#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008247PyDoc_STRVAR(posix_sendfile__doc__,
8248"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8249sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8250 -> byteswritten\n\
8251Copy nbytes bytes from file descriptor in to file descriptor out.");
8252
8253static PyObject *
8254posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8255{
8256 int in, out;
8257 Py_ssize_t ret;
8258 off_t offset;
8259
8260#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8261#ifndef __APPLE__
8262 Py_ssize_t len;
8263#endif
8264 PyObject *headers = NULL, *trailers = NULL;
8265 Py_buffer *hbuf, *tbuf;
8266 off_t sbytes;
8267 struct sf_hdtr sf;
8268 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008269 static char *keywords[] = {"out", "in",
8270 "offset", "count",
8271 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008272
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008273 sf.headers = NULL;
8274 sf.trailers = NULL;
8275
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008276#ifdef __APPLE__
8277 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008278 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008279#else
8280 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008281 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008282#endif
8283 &headers, &trailers, &flags))
8284 return NULL;
8285 if (headers != NULL) {
8286 if (!PySequence_Check(headers)) {
8287 PyErr_SetString(PyExc_TypeError,
8288 "sendfile() headers must be a sequence or None");
8289 return NULL;
8290 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008291 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008292 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008293 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008294 (i = iov_setup(&(sf.headers), &hbuf,
8295 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008296 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008297#ifdef __APPLE__
8298 sbytes += i;
8299#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008300 }
8301 }
8302 if (trailers != NULL) {
8303 if (!PySequence_Check(trailers)) {
8304 PyErr_SetString(PyExc_TypeError,
8305 "sendfile() trailers must be a sequence or None");
8306 return NULL;
8307 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008308 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008309 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008310 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008311 (i = iov_setup(&(sf.trailers), &tbuf,
8312 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008313 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008314#ifdef __APPLE__
8315 sbytes += i;
8316#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008317 }
8318 }
8319
8320 Py_BEGIN_ALLOW_THREADS
8321#ifdef __APPLE__
8322 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8323#else
8324 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8325#endif
8326 Py_END_ALLOW_THREADS
8327
8328 if (sf.headers != NULL)
8329 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8330 if (sf.trailers != NULL)
8331 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8332
8333 if (ret < 0) {
8334 if ((errno == EAGAIN) || (errno == EBUSY)) {
8335 if (sbytes != 0) {
8336 // some data has been sent
8337 goto done;
8338 }
8339 else {
8340 // no data has been sent; upper application is supposed
8341 // to retry on EAGAIN or EBUSY
8342 return posix_error();
8343 }
8344 }
8345 return posix_error();
8346 }
8347 goto done;
8348
8349done:
8350 #if !defined(HAVE_LARGEFILE_SUPPORT)
8351 return Py_BuildValue("l", sbytes);
8352 #else
8353 return Py_BuildValue("L", sbytes);
8354 #endif
8355
8356#else
8357 Py_ssize_t count;
8358 PyObject *offobj;
8359 static char *keywords[] = {"out", "in",
8360 "offset", "count", NULL};
8361 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8362 keywords, &out, &in, &offobj, &count))
8363 return NULL;
8364#ifdef linux
8365 if (offobj == Py_None) {
8366 Py_BEGIN_ALLOW_THREADS
8367 ret = sendfile(out, in, NULL, count);
8368 Py_END_ALLOW_THREADS
8369 if (ret < 0)
8370 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008371 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008372 }
8373#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008374 if (!_parse_off_t(offobj, &offset))
8375 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008376 Py_BEGIN_ALLOW_THREADS
8377 ret = sendfile(out, in, &offset, count);
8378 Py_END_ALLOW_THREADS
8379 if (ret < 0)
8380 return posix_error();
8381 return Py_BuildValue("n", ret);
8382#endif
8383}
8384#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008385
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008386PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008387"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008388Like stat(), but for an open file descriptor.\n\
8389Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008390
Barry Warsaw53699e91996-12-10 23:23:01 +00008391static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008392posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008393{
Victor Stinner8c62be82010-05-06 00:08:46 +00008394 int fd;
8395 STRUCT_STAT st;
8396 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008397 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008398 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008399 Py_BEGIN_ALLOW_THREADS
8400 res = FSTAT(fd, &st);
8401 Py_END_ALLOW_THREADS
8402 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008403#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008404 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008405#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008406 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008407#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008408 }
Tim Peters5aa91602002-01-30 05:46:57 +00008409
Victor Stinner4195b5c2012-02-08 23:03:19 +01008410 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008411}
8412
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008413PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008414"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008415Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008416connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008417
8418static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008419posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008420{
Victor Stinner8c62be82010-05-06 00:08:46 +00008421 int fd;
8422 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8423 return NULL;
8424 if (!_PyVerify_fd(fd))
8425 return PyBool_FromLong(0);
8426 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008427}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008428
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008429#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008430PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008431"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008432Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008433
Barry Warsaw53699e91996-12-10 23:23:01 +00008434static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008435posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008436{
Victor Stinner8c62be82010-05-06 00:08:46 +00008437 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008438#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008439 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008440 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008441 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008442#else
8443 int res;
8444#endif
8445
8446#ifdef MS_WINDOWS
8447 attr.nLength = sizeof(attr);
8448 attr.lpSecurityDescriptor = NULL;
8449 attr.bInheritHandle = FALSE;
8450
8451 Py_BEGIN_ALLOW_THREADS
8452 ok = CreatePipe(&read, &write, &attr, 0);
8453 if (ok) {
8454 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8455 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8456 if (fds[0] == -1 || fds[1] == -1) {
8457 CloseHandle(read);
8458 CloseHandle(write);
8459 ok = 0;
8460 }
8461 }
8462 Py_END_ALLOW_THREADS
8463
Victor Stinner8c62be82010-05-06 00:08:46 +00008464 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008465 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008466#else
8467
8468#ifdef HAVE_PIPE2
8469 Py_BEGIN_ALLOW_THREADS
8470 res = pipe2(fds, O_CLOEXEC);
8471 Py_END_ALLOW_THREADS
8472
8473 if (res != 0 && errno == ENOSYS)
8474 {
8475#endif
8476 Py_BEGIN_ALLOW_THREADS
8477 res = pipe(fds);
8478 Py_END_ALLOW_THREADS
8479
8480 if (res == 0) {
8481 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8482 close(fds[0]);
8483 close(fds[1]);
8484 return NULL;
8485 }
8486 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8487 close(fds[0]);
8488 close(fds[1]);
8489 return NULL;
8490 }
8491 }
8492#ifdef HAVE_PIPE2
8493 }
8494#endif
8495
8496 if (res != 0)
8497 return PyErr_SetFromErrno(PyExc_OSError);
8498#endif /* !MS_WINDOWS */
8499 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008500}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008501#endif /* HAVE_PIPE */
8502
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008503#ifdef HAVE_PIPE2
8504PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008505"pipe2(flags) -> (read_end, write_end)\n\n\
8506Create a pipe with flags set atomically.\n\
8507flags can be constructed by ORing together one or more of these values:\n\
8508O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008509");
8510
8511static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008512posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008513{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008514 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008515 int fds[2];
8516 int res;
8517
Serhiy Storchaka78980432013-01-15 01:12:17 +02008518 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008519 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008520 return NULL;
8521
8522 res = pipe2(fds, flags);
8523 if (res != 0)
8524 return posix_error();
8525 return Py_BuildValue("(ii)", fds[0], fds[1]);
8526}
8527#endif /* HAVE_PIPE2 */
8528
Ross Lagerwall7807c352011-03-17 20:20:30 +02008529#ifdef HAVE_WRITEV
8530PyDoc_STRVAR(posix_writev__doc__,
8531"writev(fd, buffers) -> byteswritten\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008532Write the contents of *buffers* to file descriptor *fd*. *buffers*\n\
8533must be a sequence of bytes-like objects.\n\n\
8534writev writes the contents of each object to the file descriptor\n\
8535and returns the total number of bytes written.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008536
8537static PyObject *
8538posix_writev(PyObject *self, PyObject *args)
8539{
8540 int fd, cnt;
8541 Py_ssize_t res;
8542 PyObject *seq;
8543 struct iovec *iov;
8544 Py_buffer *buf;
8545 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8546 return NULL;
8547 if (!PySequence_Check(seq)) {
8548 PyErr_SetString(PyExc_TypeError,
8549 "writev() arg 2 must be a sequence");
8550 return NULL;
8551 }
8552 cnt = PySequence_Size(seq);
8553
Victor Stinner57ddf782014-01-08 15:21:28 +01008554 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008555 return NULL;
8556 }
8557
8558 Py_BEGIN_ALLOW_THREADS
8559 res = writev(fd, iov, cnt);
8560 Py_END_ALLOW_THREADS
8561
8562 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008563 if (res < 0)
8564 return posix_error();
8565
Ross Lagerwall7807c352011-03-17 20:20:30 +02008566 return PyLong_FromSsize_t(res);
8567}
8568#endif
8569
8570#ifdef HAVE_PWRITE
8571PyDoc_STRVAR(posix_pwrite__doc__,
8572"pwrite(fd, string, offset) -> byteswritten\n\n\
8573Write string to a file descriptor, fd, from offset, leaving the file\n\
8574offset unchanged.");
8575
8576static PyObject *
8577posix_pwrite(PyObject *self, PyObject *args)
8578{
8579 Py_buffer pbuf;
8580 int fd;
8581 off_t offset;
8582 Py_ssize_t size;
8583
8584 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8585 return NULL;
8586
8587 if (!_PyVerify_fd(fd)) {
8588 PyBuffer_Release(&pbuf);
8589 return posix_error();
8590 }
8591 Py_BEGIN_ALLOW_THREADS
8592 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8593 Py_END_ALLOW_THREADS
8594 PyBuffer_Release(&pbuf);
8595 if (size < 0)
8596 return posix_error();
8597 return PyLong_FromSsize_t(size);
8598}
8599#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008600
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008601#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008602PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008603"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8604Create a FIFO (a POSIX named pipe).\n\
8605\n\
8606If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8607 and path should be relative; path will then be relative to that directory.\n\
8608dir_fd may not be implemented on your platform.\n\
8609 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008610
Barry Warsaw53699e91996-12-10 23:23:01 +00008611static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008612posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008613{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008614 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008615 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008616 int dir_fd = DEFAULT_DIR_FD;
8617 int result;
8618 PyObject *return_value = NULL;
8619 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8620
8621 memset(&path, 0, sizeof(path));
8622 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8623 path_converter, &path,
8624 &mode,
8625#ifdef HAVE_MKFIFOAT
8626 dir_fd_converter, &dir_fd
8627#else
8628 dir_fd_unavailable, &dir_fd
8629#endif
8630 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008631 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008632
Victor Stinner8c62be82010-05-06 00:08:46 +00008633 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008634#ifdef HAVE_MKFIFOAT
8635 if (dir_fd != DEFAULT_DIR_FD)
8636 result = mkfifoat(dir_fd, path.narrow, mode);
8637 else
8638#endif
8639 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008640 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008641
8642 if (result < 0) {
8643 return_value = posix_error();
8644 goto exit;
8645 }
8646
8647 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008648 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008649
8650exit:
8651 path_cleanup(&path);
8652 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008653}
8654#endif
8655
Neal Norwitz11690112002-07-30 01:08:28 +00008656#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008657PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008658"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008659Create a filesystem node (file, device special file or named pipe)\n\
8660named filename. mode specifies both the permissions to use and the\n\
8661type of node to be created, being combined (bitwise OR) with one of\n\
8662S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008663device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008664os.makedev()), otherwise it is ignored.\n\
8665\n\
8666If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8667 and path should be relative; path will then be relative to that directory.\n\
8668dir_fd may not be implemented on your platform.\n\
8669 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008670
8671
8672static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008673posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008674{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008675 path_t path;
8676 int mode = 0666;
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008677 dev_t device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008678 int dir_fd = DEFAULT_DIR_FD;
8679 int result;
8680 PyObject *return_value = NULL;
8681 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8682
8683 memset(&path, 0, sizeof(path));
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008684 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|iO&$O&:mknod", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008685 path_converter, &path,
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008686 &mode, _Py_Dev_Converter, &device,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008687#ifdef HAVE_MKNODAT
8688 dir_fd_converter, &dir_fd
8689#else
8690 dir_fd_unavailable, &dir_fd
8691#endif
8692 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008693 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008694
Victor Stinner8c62be82010-05-06 00:08:46 +00008695 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008696#ifdef HAVE_MKNODAT
8697 if (dir_fd != DEFAULT_DIR_FD)
8698 result = mknodat(dir_fd, path.narrow, mode, device);
8699 else
8700#endif
8701 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008702 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008703
8704 if (result < 0) {
8705 return_value = posix_error();
8706 goto exit;
8707 }
8708
8709 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008710 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008711
Larry Hastings9cf065c2012-06-22 16:30:09 -07008712exit:
8713 path_cleanup(&path);
8714 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008715}
8716#endif
8717
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008718#ifdef HAVE_DEVICE_MACROS
8719PyDoc_STRVAR(posix_major__doc__,
8720"major(device) -> major number\n\
8721Extracts a device major number from a raw device number.");
8722
8723static PyObject *
8724posix_major(PyObject *self, PyObject *args)
8725{
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008726 dev_t device;
8727 if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00008728 return NULL;
8729 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008730}
8731
8732PyDoc_STRVAR(posix_minor__doc__,
8733"minor(device) -> minor number\n\
8734Extracts a device minor number from a raw device number.");
8735
8736static PyObject *
8737posix_minor(PyObject *self, PyObject *args)
8738{
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008739 dev_t device;
8740 if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00008741 return NULL;
8742 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008743}
8744
8745PyDoc_STRVAR(posix_makedev__doc__,
8746"makedev(major, minor) -> device number\n\
8747Composes a raw device number from the major and minor device numbers.");
8748
8749static PyObject *
8750posix_makedev(PyObject *self, PyObject *args)
8751{
Victor Stinner8c62be82010-05-06 00:08:46 +00008752 int major, minor;
8753 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8754 return NULL;
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008755 return _PyLong_FromDev(makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008756}
8757#endif /* device macros */
8758
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008759
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008760#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008761PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008762"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008763Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008764
Barry Warsaw53699e91996-12-10 23:23:01 +00008765static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008766posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008767{
Victor Stinner8c62be82010-05-06 00:08:46 +00008768 int fd;
8769 off_t length;
8770 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008771
Ross Lagerwall7807c352011-03-17 20:20:30 +02008772 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008773 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008774
Victor Stinner8c62be82010-05-06 00:08:46 +00008775 Py_BEGIN_ALLOW_THREADS
8776 res = ftruncate(fd, length);
8777 Py_END_ALLOW_THREADS
8778 if (res < 0)
8779 return posix_error();
8780 Py_INCREF(Py_None);
8781 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008782}
8783#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008784
Ross Lagerwall7807c352011-03-17 20:20:30 +02008785#ifdef HAVE_TRUNCATE
8786PyDoc_STRVAR(posix_truncate__doc__,
8787"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008788Truncate the file given by path to length bytes.\n\
8789On some platforms, path may also be specified as an open file descriptor.\n\
8790 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008791
8792static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008793posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008794{
Georg Brandl306336b2012-06-24 12:55:33 +02008795 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008796 off_t length;
8797 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008798 PyObject *result = NULL;
8799 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008800
Georg Brandl306336b2012-06-24 12:55:33 +02008801 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008802 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008803#ifdef HAVE_FTRUNCATE
8804 path.allow_fd = 1;
8805#endif
8806 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8807 path_converter, &path,
8808 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008809 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008810
8811 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008812#ifdef HAVE_FTRUNCATE
8813 if (path.fd != -1)
8814 res = ftruncate(path.fd, length);
8815 else
8816#endif
8817 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008818 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008819 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008820 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008821 else {
8822 Py_INCREF(Py_None);
8823 result = Py_None;
8824 }
8825 path_cleanup(&path);
8826 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008827}
8828#endif
8829
Victor Stinnerd6b17692014-09-30 12:20:05 +02008830/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8831 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8832 defined, which is the case in Python on AIX. AIX bug report:
8833 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8834#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8835# define POSIX_FADVISE_AIX_BUG
8836#endif
8837
8838#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008839PyDoc_STRVAR(posix_posix_fallocate__doc__,
8840"posix_fallocate(fd, offset, len)\n\n\
8841Ensures that enough disk space is allocated for the file specified by fd\n\
8842starting from offset and continuing for len bytes.");
8843
8844static PyObject *
8845posix_posix_fallocate(PyObject *self, PyObject *args)
8846{
8847 off_t len, offset;
8848 int res, fd;
8849
8850 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8851 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8852 return NULL;
8853
8854 Py_BEGIN_ALLOW_THREADS
8855 res = posix_fallocate(fd, offset, len);
8856 Py_END_ALLOW_THREADS
8857 if (res != 0) {
8858 errno = res;
8859 return posix_error();
8860 }
8861 Py_RETURN_NONE;
8862}
8863#endif
8864
Victor Stinnerd6b17692014-09-30 12:20:05 +02008865#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008866PyDoc_STRVAR(posix_posix_fadvise__doc__,
8867"posix_fadvise(fd, offset, len, advice)\n\n\
8868Announces an intention to access data in a specific pattern thus allowing\n\
8869the kernel to make optimizations.\n\
8870The advice applies to the region of the file specified by fd starting at\n\
8871offset and continuing for len bytes.\n\
8872advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8873POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8874POSIX_FADV_DONTNEED.");
8875
8876static PyObject *
8877posix_posix_fadvise(PyObject *self, PyObject *args)
8878{
8879 off_t len, offset;
8880 int res, fd, advice;
8881
8882 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8883 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8884 return NULL;
8885
8886 Py_BEGIN_ALLOW_THREADS
8887 res = posix_fadvise(fd, offset, len, advice);
8888 Py_END_ALLOW_THREADS
8889 if (res != 0) {
8890 errno = res;
8891 return posix_error();
8892 }
8893 Py_RETURN_NONE;
8894}
8895#endif
8896
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008897#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008898PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008899"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008900Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008901
Fred Drake762e2061999-08-26 17:23:54 +00008902/* Save putenv() parameters as values here, so we can collect them when they
8903 * get re-set with another call for the same key. */
8904static PyObject *posix_putenv_garbage;
8905
Tim Peters5aa91602002-01-30 05:46:57 +00008906static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008907posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008908{
Victor Stinner84ae1182010-05-06 22:05:07 +00008909 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008910#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008911 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008912 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008913
Victor Stinner8c62be82010-05-06 00:08:46 +00008914 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008915 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008916 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008917 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008918
Victor Stinner65170952011-11-22 22:16:17 +01008919 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008920 if (newstr == NULL) {
8921 PyErr_NoMemory();
8922 goto error;
8923 }
Victor Stinner65170952011-11-22 22:16:17 +01008924 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8925 PyErr_Format(PyExc_ValueError,
8926 "the environment variable is longer than %u characters",
8927 _MAX_ENV);
8928 goto error;
8929 }
8930
Victor Stinner8c62be82010-05-06 00:08:46 +00008931 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008932 if (newenv == NULL)
8933 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008934 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008936 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008937 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008938#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008939 PyObject *os1, *os2;
8940 char *s1, *s2;
8941 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008942
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008943 if (!PyArg_ParseTuple(args,
8944 "O&O&:putenv",
8945 PyUnicode_FSConverter, &os1,
8946 PyUnicode_FSConverter, &os2))
8947 return NULL;
8948 s1 = PyBytes_AsString(os1);
8949 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008950
Victor Stinner65170952011-11-22 22:16:17 +01008951 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008952 if (newstr == NULL) {
8953 PyErr_NoMemory();
8954 goto error;
8955 }
8956
Victor Stinner8c62be82010-05-06 00:08:46 +00008957 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008958 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008959 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008960 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008961 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008962#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008963
Victor Stinner8c62be82010-05-06 00:08:46 +00008964 /* Install the first arg and newstr in posix_putenv_garbage;
8965 * this will cause previous value to be collected. This has to
8966 * happen after the real putenv() call because the old value
8967 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008968 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008969 /* really not much we can do; just leak */
8970 PyErr_Clear();
8971 }
8972 else {
8973 Py_DECREF(newstr);
8974 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008975
Martin v. Löwis011e8422009-05-05 04:43:17 +00008976#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008977 Py_DECREF(os1);
8978 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008979#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008980 Py_RETURN_NONE;
8981
8982error:
8983#ifndef MS_WINDOWS
8984 Py_DECREF(os1);
8985 Py_DECREF(os2);
8986#endif
8987 Py_XDECREF(newstr);
8988 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008989}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008990#endif /* putenv */
8991
Guido van Rossumc524d952001-10-19 01:31:59 +00008992#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008993PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008994"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008995Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008996
8997static PyObject *
8998posix_unsetenv(PyObject *self, PyObject *args)
8999{
Victor Stinner65170952011-11-22 22:16:17 +01009000 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01009001#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009002 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009003#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009004
9005 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00009006
Victor Stinner65170952011-11-22 22:16:17 +01009007 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00009008 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00009009
Victor Stinner984890f2011-11-24 13:53:38 +01009010#ifdef HAVE_BROKEN_UNSETENV
9011 unsetenv(PyBytes_AS_STRING(name));
9012#else
Victor Stinner65170952011-11-22 22:16:17 +01009013 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06009014 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06009015 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01009016 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06009017 }
Victor Stinner984890f2011-11-24 13:53:38 +01009018#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009019
Victor Stinner8c62be82010-05-06 00:08:46 +00009020 /* Remove the key from posix_putenv_garbage;
9021 * this will cause it to be collected. This has to
9022 * happen after the real unsetenv() call because the
9023 * old value was still accessible until then.
9024 */
Victor Stinner65170952011-11-22 22:16:17 +01009025 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009026 /* really not much we can do; just leak */
9027 PyErr_Clear();
9028 }
Victor Stinner65170952011-11-22 22:16:17 +01009029 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00009030 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009031}
9032#endif /* unsetenv */
9033
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009034PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009035"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009036Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009037
Guido van Rossumf68d8e52001-04-14 17:55:09 +00009038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009039posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00009040{
Victor Stinner8c62be82010-05-06 00:08:46 +00009041 int code;
9042 char *message;
9043 if (!PyArg_ParseTuple(args, "i:strerror", &code))
9044 return NULL;
9045 message = strerror(code);
9046 if (message == NULL) {
9047 PyErr_SetString(PyExc_ValueError,
9048 "strerror() argument out of range");
9049 return NULL;
9050 }
Victor Stinner1b579672011-12-17 05:47:23 +01009051 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009052}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009053
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009054
Guido van Rossumc9641791998-08-04 15:26:23 +00009055#ifdef HAVE_SYS_WAIT_H
9056
Fred Drake106c1a02002-04-23 15:58:02 +00009057#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009058PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009059"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009060Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00009061
9062static PyObject *
9063posix_WCOREDUMP(PyObject *self, PyObject *args)
9064{
Victor Stinner8c62be82010-05-06 00:08:46 +00009065 WAIT_TYPE status;
9066 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009067
Victor Stinner8c62be82010-05-06 00:08:46 +00009068 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
9069 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009070
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009072}
9073#endif /* WCOREDUMP */
9074
9075#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009076PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009077"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00009078Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009079job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00009080
9081static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009082posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00009083{
Victor Stinner8c62be82010-05-06 00:08:46 +00009084 WAIT_TYPE status;
9085 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009086
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
9088 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009089
Victor Stinner8c62be82010-05-06 00:08:46 +00009090 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009091}
9092#endif /* WIFCONTINUED */
9093
Guido van Rossumc9641791998-08-04 15:26:23 +00009094#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009095PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009096"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009097Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009098
9099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009100posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009101{
Victor Stinner8c62be82010-05-06 00:08:46 +00009102 WAIT_TYPE status;
9103 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009104
Victor Stinner8c62be82010-05-06 00:08:46 +00009105 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
9106 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009107
Victor Stinner8c62be82010-05-06 00:08:46 +00009108 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009109}
9110#endif /* WIFSTOPPED */
9111
9112#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009113PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009114"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009115Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009116
9117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009118posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009119{
Victor Stinner8c62be82010-05-06 00:08:46 +00009120 WAIT_TYPE status;
9121 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009122
Victor Stinner8c62be82010-05-06 00:08:46 +00009123 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9124 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009125
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009127}
9128#endif /* WIFSIGNALED */
9129
9130#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009131PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009132"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009133Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009134system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009135
9136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009137posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009138{
Victor Stinner8c62be82010-05-06 00:08:46 +00009139 WAIT_TYPE status;
9140 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009141
Victor Stinner8c62be82010-05-06 00:08:46 +00009142 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9143 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009144
Victor Stinner8c62be82010-05-06 00:08:46 +00009145 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009146}
9147#endif /* WIFEXITED */
9148
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009149#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009150PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009151"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009152Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009153
9154static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009155posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009156{
Victor Stinner8c62be82010-05-06 00:08:46 +00009157 WAIT_TYPE status;
9158 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009159
Victor Stinner8c62be82010-05-06 00:08:46 +00009160 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9161 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009162
Victor Stinner8c62be82010-05-06 00:08:46 +00009163 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009164}
9165#endif /* WEXITSTATUS */
9166
9167#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009168PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009169"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009170Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009171value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009172
9173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009174posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009175{
Victor Stinner8c62be82010-05-06 00:08:46 +00009176 WAIT_TYPE status;
9177 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009178
Victor Stinner8c62be82010-05-06 00:08:46 +00009179 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9180 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009181
Victor Stinner8c62be82010-05-06 00:08:46 +00009182 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009183}
9184#endif /* WTERMSIG */
9185
9186#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009187PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009188"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009189Return the signal that stopped the process that provided\n\
9190the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009191
9192static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009193posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009194{
Victor Stinner8c62be82010-05-06 00:08:46 +00009195 WAIT_TYPE status;
9196 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009197
Victor Stinner8c62be82010-05-06 00:08:46 +00009198 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9199 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009200
Victor Stinner8c62be82010-05-06 00:08:46 +00009201 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009202}
9203#endif /* WSTOPSIG */
9204
9205#endif /* HAVE_SYS_WAIT_H */
9206
9207
Thomas Wouters477c8d52006-05-27 19:21:47 +00009208#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009209#ifdef _SCO_DS
9210/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9211 needed definitions in sys/statvfs.h */
9212#define _SVID3
9213#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009214#include <sys/statvfs.h>
9215
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009216static PyObject*
9217_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009218 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9219 if (v == NULL)
9220 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009221
9222#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009223 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9224 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9225 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9226 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9227 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9228 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9229 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9230 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9231 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9232 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009233#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009234 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9235 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9236 PyStructSequence_SET_ITEM(v, 2,
9237 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9238 PyStructSequence_SET_ITEM(v, 3,
9239 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9240 PyStructSequence_SET_ITEM(v, 4,
9241 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9242 PyStructSequence_SET_ITEM(v, 5,
9243 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9244 PyStructSequence_SET_ITEM(v, 6,
9245 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9246 PyStructSequence_SET_ITEM(v, 7,
9247 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9248 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9249 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009250#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009251 if (PyErr_Occurred()) {
9252 Py_DECREF(v);
9253 return NULL;
9254 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009255
Victor Stinner8c62be82010-05-06 00:08:46 +00009256 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009257}
9258
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009259PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009260"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009261Perform an fstatvfs system call on the given fd.\n\
9262Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009263
9264static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009265posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009266{
Victor Stinner8c62be82010-05-06 00:08:46 +00009267 int fd, res;
9268 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009269
Victor Stinner8c62be82010-05-06 00:08:46 +00009270 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9271 return NULL;
9272 Py_BEGIN_ALLOW_THREADS
9273 res = fstatvfs(fd, &st);
9274 Py_END_ALLOW_THREADS
9275 if (res != 0)
9276 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009277
Victor Stinner8c62be82010-05-06 00:08:46 +00009278 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009279}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009280#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009281
9282
Thomas Wouters477c8d52006-05-27 19:21:47 +00009283#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009284#include <sys/statvfs.h>
9285
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009286PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009287"statvfs(path)\n\n\
9288Perform a statvfs system call on the given path.\n\
9289\n\
9290path may always be specified as a string.\n\
9291On some platforms, path may also be specified as an open file descriptor.\n\
9292 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009293
9294static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009295posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009296{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009297 static char *keywords[] = {"path", NULL};
9298 path_t path;
9299 int result;
9300 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009301 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009302
Larry Hastings9cf065c2012-06-22 16:30:09 -07009303 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009304 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009305#ifdef HAVE_FSTATVFS
9306 path.allow_fd = 1;
9307#endif
9308 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9309 path_converter, &path
9310 ))
9311 return NULL;
9312
9313 Py_BEGIN_ALLOW_THREADS
9314#ifdef HAVE_FSTATVFS
9315 if (path.fd != -1) {
9316#ifdef __APPLE__
9317 /* handle weak-linking on Mac OS X 10.3 */
9318 if (fstatvfs == NULL) {
9319 fd_specified("statvfs", path.fd);
9320 goto exit;
9321 }
9322#endif
9323 result = fstatvfs(path.fd, &st);
9324 }
9325 else
9326#endif
9327 result = statvfs(path.narrow, &st);
9328 Py_END_ALLOW_THREADS
9329
9330 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009331 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009332 goto exit;
9333 }
9334
9335 return_value = _pystatvfs_fromstructstatvfs(st);
9336
9337exit:
9338 path_cleanup(&path);
9339 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009340}
9341#endif /* HAVE_STATVFS */
9342
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009343#ifdef MS_WINDOWS
9344PyDoc_STRVAR(win32__getdiskusage__doc__,
9345"_getdiskusage(path) -> (total, free)\n\n\
9346Return disk usage statistics about the given path as (total, free) tuple.");
9347
9348static PyObject *
9349win32__getdiskusage(PyObject *self, PyObject *args)
9350{
9351 BOOL retval;
9352 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009353 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009354
Victor Stinner6139c1b2011-11-09 22:14:14 +01009355 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009356 return NULL;
9357
9358 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009359 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009360 Py_END_ALLOW_THREADS
9361 if (retval == 0)
9362 return PyErr_SetFromWindowsErr(0);
9363
9364 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9365}
9366#endif
9367
9368
Fred Drakec9680921999-12-13 16:37:25 +00009369/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9370 * It maps strings representing configuration variable names to
9371 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009372 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009373 * rarely-used constants. There are three separate tables that use
9374 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009375 *
9376 * This code is always included, even if none of the interfaces that
9377 * need it are included. The #if hackery needed to avoid it would be
9378 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009379 */
9380struct constdef {
9381 char *name;
9382 long value;
9383};
9384
Fred Drake12c6e2d1999-12-14 21:25:03 +00009385static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009386conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009387 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009388{
Christian Heimes217cfd12007-12-02 14:31:20 +00009389 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009390 *valuep = PyLong_AS_LONG(arg);
9391 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009392 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009393 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009394 /* look up the value in the table using a binary search */
9395 size_t lo = 0;
9396 size_t mid;
9397 size_t hi = tablesize;
9398 int cmp;
9399 const char *confname;
9400 if (!PyUnicode_Check(arg)) {
9401 PyErr_SetString(PyExc_TypeError,
9402 "configuration names must be strings or integers");
9403 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009404 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009405 confname = _PyUnicode_AsString(arg);
9406 if (confname == NULL)
9407 return 0;
9408 while (lo < hi) {
9409 mid = (lo + hi) / 2;
9410 cmp = strcmp(confname, table[mid].name);
9411 if (cmp < 0)
9412 hi = mid;
9413 else if (cmp > 0)
9414 lo = mid + 1;
9415 else {
9416 *valuep = table[mid].value;
9417 return 1;
9418 }
9419 }
9420 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9421 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009422 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009423}
9424
9425
9426#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9427static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009428#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009429 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009430#endif
9431#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009432 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009433#endif
Fred Drakec9680921999-12-13 16:37:25 +00009434#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009435 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009436#endif
9437#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009438 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009439#endif
9440#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009441 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009442#endif
9443#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009444 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009445#endif
9446#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009447 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009448#endif
9449#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009450 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009451#endif
9452#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009453 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009454#endif
9455#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009456 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009457#endif
9458#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009459 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009460#endif
9461#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009462 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009463#endif
9464#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009465 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009466#endif
9467#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009468 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009469#endif
9470#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009471 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009472#endif
9473#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009474 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009475#endif
9476#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009477 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009478#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009479#ifdef _PC_ACL_ENABLED
9480 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9481#endif
9482#ifdef _PC_MIN_HOLE_SIZE
9483 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9484#endif
9485#ifdef _PC_ALLOC_SIZE_MIN
9486 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9487#endif
9488#ifdef _PC_REC_INCR_XFER_SIZE
9489 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9490#endif
9491#ifdef _PC_REC_MAX_XFER_SIZE
9492 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9493#endif
9494#ifdef _PC_REC_MIN_XFER_SIZE
9495 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9496#endif
9497#ifdef _PC_REC_XFER_ALIGN
9498 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9499#endif
9500#ifdef _PC_SYMLINK_MAX
9501 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9502#endif
9503#ifdef _PC_XATTR_ENABLED
9504 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9505#endif
9506#ifdef _PC_XATTR_EXISTS
9507 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9508#endif
9509#ifdef _PC_TIMESTAMP_RESOLUTION
9510 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9511#endif
Fred Drakec9680921999-12-13 16:37:25 +00009512};
9513
Fred Drakec9680921999-12-13 16:37:25 +00009514static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009515conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009516{
9517 return conv_confname(arg, valuep, posix_constants_pathconf,
9518 sizeof(posix_constants_pathconf)
9519 / sizeof(struct constdef));
9520}
9521#endif
9522
9523#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009524PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009525"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009526Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009527If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009528
9529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009530posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009531{
9532 PyObject *result = NULL;
9533 int name, fd;
9534
Fred Drake12c6e2d1999-12-14 21:25:03 +00009535 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9536 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009537 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009538
Stefan Krah0e803b32010-11-26 16:16:47 +00009539 errno = 0;
9540 limit = fpathconf(fd, name);
9541 if (limit == -1 && errno != 0)
9542 posix_error();
9543 else
9544 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009545 }
9546 return result;
9547}
9548#endif
9549
9550
9551#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009552PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009553"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009554Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009555If there is no limit, return -1.\n\
9556On some platforms, path may also be specified as an open file descriptor.\n\
9557 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009558
9559static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009560posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009561{
Georg Brandl306336b2012-06-24 12:55:33 +02009562 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009563 PyObject *result = NULL;
9564 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009565 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009566
Georg Brandl306336b2012-06-24 12:55:33 +02009567 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009568 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009569#ifdef HAVE_FPATHCONF
9570 path.allow_fd = 1;
9571#endif
9572 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9573 path_converter, &path,
9574 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009576
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009578#ifdef HAVE_FPATHCONF
9579 if (path.fd != -1)
9580 limit = fpathconf(path.fd, name);
9581 else
9582#endif
9583 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 if (limit == -1 && errno != 0) {
9585 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009586 /* could be a path or name problem */
9587 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009588 else
Victor Stinner292c8352012-10-30 02:17:38 +01009589 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 }
9591 else
9592 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009593 }
Georg Brandl306336b2012-06-24 12:55:33 +02009594 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009595 return result;
9596}
9597#endif
9598
9599#ifdef HAVE_CONFSTR
9600static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009601#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009602 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009603#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009604#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009605 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009606#endif
9607#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009608 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009609#endif
Fred Draked86ed291999-12-15 15:34:33 +00009610#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009611 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009612#endif
9613#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009614 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009615#endif
9616#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009617 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009618#endif
9619#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009620 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009621#endif
Fred Drakec9680921999-12-13 16:37:25 +00009622#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009623 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009624#endif
9625#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009626 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009627#endif
9628#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009629 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009630#endif
9631#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009633#endif
9634#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009635 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009636#endif
9637#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009638 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009639#endif
9640#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009642#endif
9643#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009644 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009645#endif
Fred Draked86ed291999-12-15 15:34:33 +00009646#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009647 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009648#endif
Fred Drakec9680921999-12-13 16:37:25 +00009649#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009651#endif
Fred Draked86ed291999-12-15 15:34:33 +00009652#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009654#endif
9655#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009656 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009657#endif
9658#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009660#endif
9661#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009662 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009663#endif
Fred Drakec9680921999-12-13 16:37:25 +00009664#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009665 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009666#endif
9667#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009669#endif
9670#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009671 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009672#endif
9673#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009674 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009675#endif
9676#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009678#endif
9679#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009680 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009681#endif
9682#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009683 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009684#endif
9685#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009686 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009687#endif
9688#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009689 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009690#endif
9691#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009692 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009693#endif
9694#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009695 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009696#endif
9697#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009698 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009699#endif
9700#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009701 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009702#endif
9703#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009704 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009705#endif
9706#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009707 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009708#endif
9709#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009711#endif
Fred Draked86ed291999-12-15 15:34:33 +00009712#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009713 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009714#endif
9715#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009717#endif
9718#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009719 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009720#endif
9721#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009722 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009723#endif
9724#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009726#endif
9727#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009729#endif
9730#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009732#endif
9733#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009735#endif
9736#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009738#endif
9739#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009741#endif
9742#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009744#endif
9745#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009747#endif
9748#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009750#endif
Fred Drakec9680921999-12-13 16:37:25 +00009751};
9752
9753static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009754conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009755{
9756 return conv_confname(arg, valuep, posix_constants_confstr,
9757 sizeof(posix_constants_confstr)
9758 / sizeof(struct constdef));
9759}
9760
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009761PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009762"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009763Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009764
9765static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009766posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009767{
9768 PyObject *result = NULL;
9769 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009770 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009771 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009772
Victor Stinnercb043522010-09-10 23:49:04 +00009773 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9774 return NULL;
9775
9776 errno = 0;
9777 len = confstr(name, buffer, sizeof(buffer));
9778 if (len == 0) {
9779 if (errno) {
9780 posix_error();
9781 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009782 }
9783 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009784 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009785 }
9786 }
Victor Stinnercb043522010-09-10 23:49:04 +00009787
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009788 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009789 char *buf = PyMem_Malloc(len);
9790 if (buf == NULL)
9791 return PyErr_NoMemory();
9792 confstr(name, buf, len);
9793 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9794 PyMem_Free(buf);
9795 }
9796 else
9797 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009798 return result;
9799}
9800#endif
9801
9802
9803#ifdef HAVE_SYSCONF
9804static struct constdef posix_constants_sysconf[] = {
9805#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009807#endif
9808#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009810#endif
9811#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009813#endif
9814#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009816#endif
9817#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009819#endif
9820#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009822#endif
9823#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009825#endif
9826#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009828#endif
9829#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009831#endif
9832#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009834#endif
Fred Draked86ed291999-12-15 15:34:33 +00009835#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009837#endif
9838#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009840#endif
Fred Drakec9680921999-12-13 16:37:25 +00009841#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009843#endif
Fred Drakec9680921999-12-13 16:37:25 +00009844#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009846#endif
9847#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009849#endif
9850#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009852#endif
9853#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009854 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009855#endif
9856#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009857 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009858#endif
Fred Draked86ed291999-12-15 15:34:33 +00009859#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009861#endif
Fred Drakec9680921999-12-13 16:37:25 +00009862#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009863 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009864#endif
9865#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009867#endif
9868#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009869 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009870#endif
9871#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009872 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009873#endif
9874#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009875 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009876#endif
Fred Draked86ed291999-12-15 15:34:33 +00009877#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009878 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009879#endif
Fred Drakec9680921999-12-13 16:37:25 +00009880#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009881 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009882#endif
9883#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009885#endif
9886#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009887 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009888#endif
9889#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009890 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009891#endif
9892#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009894#endif
9895#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009896 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009897#endif
9898#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009900#endif
9901#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009902 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009903#endif
9904#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009905 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009906#endif
9907#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009909#endif
9910#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009912#endif
9913#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009915#endif
9916#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
9937#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
9940#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
9943#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
9946#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
Fred Draked86ed291999-12-15 15:34:33 +00009949#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009951#endif
Fred Drakec9680921999-12-13 16:37:25 +00009952#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
9955#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
Fred Draked86ed291999-12-15 15:34:33 +00009961#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009963#endif
Fred Drakec9680921999-12-13 16:37:25 +00009964#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
Fred Draked86ed291999-12-15 15:34:33 +00009967#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009969#endif
9970#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009972#endif
Fred Drakec9680921999-12-13 16:37:25 +00009973#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
9979#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009981#endif
9982#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
Fred Draked86ed291999-12-15 15:34:33 +00009985#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009987#endif
Fred Drakec9680921999-12-13 16:37:25 +00009988#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
9991#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
9997#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009999#endif
10000#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
Fred Draked86ed291999-12-15 15:34:33 +000010009#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010011#endif
Fred Drakec9680921999-12-13 16:37:25 +000010012#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
Fred Draked86ed291999-12-15 15:34:33 +000010018#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010020#endif
Fred Drakec9680921999-12-13 16:37:25 +000010021#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010023#endif
10024#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010026#endif
10027#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
10033#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
10036#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
10039#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010041#endif
10042#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010044#endif
10045#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
Fred Draked86ed291999-12-15 15:34:33 +000010048#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010050#endif
10051#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010053#endif
Fred Drakec9680921999-12-13 16:37:25 +000010054#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
10057#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010059#endif
10060#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
10063#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010065#endif
10066#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
10069#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010071#endif
10072#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010074#endif
10075#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010077#endif
10078#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010080#endif
10081#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010083#endif
10084#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010086#endif
10087#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010089#endif
10090#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010092#endif
10093#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010095#endif
10096#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
10105#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010107#endif
10108#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
10111#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
10114#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
10117#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
10120#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
10123#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
10126#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
10129#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
10153#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
10156#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010158#endif
Fred Draked86ed291999-12-15 15:34:33 +000010159#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010161#endif
Fred Drakec9680921999-12-13 16:37:25 +000010162#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
10168#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
10234#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
10258#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010260#endif
10261#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010263#endif
10264#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010266#endif
10267#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010269#endif
10270#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010272#endif
10273#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010275#endif
10276#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010278#endif
10279#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010281#endif
10282#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010284#endif
10285#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010287#endif
10288#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010290#endif
10291#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010293#endif
10294#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010296#endif
10297};
10298
10299static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010300conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010301{
10302 return conv_confname(arg, valuep, posix_constants_sysconf,
10303 sizeof(posix_constants_sysconf)
10304 / sizeof(struct constdef));
10305}
10306
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010307PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010308"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010309Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010310
10311static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010312posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010313{
10314 PyObject *result = NULL;
10315 int name;
10316
10317 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +020010318 long value;
Fred Drakec9680921999-12-13 16:37:25 +000010319
10320 errno = 0;
10321 value = sysconf(name);
10322 if (value == -1 && errno != 0)
10323 posix_error();
10324 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010325 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010326 }
10327 return result;
10328}
10329#endif
10330
10331
Fred Drakebec628d1999-12-15 18:31:10 +000010332/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010333 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010334 * the exported dictionaries that are used to publish information about the
10335 * names available on the host platform.
10336 *
10337 * Sorting the table at runtime ensures that the table is properly ordered
10338 * when used, even for platforms we're not able to test on. It also makes
10339 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010340 */
Fred Drakebec628d1999-12-15 18:31:10 +000010341
10342static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010343cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010344{
10345 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010347 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010349
10350 return strcmp(c1->name, c2->name);
10351}
10352
10353static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010354setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010356{
Fred Drakebec628d1999-12-15 18:31:10 +000010357 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010358 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010359
10360 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10361 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010362 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010363 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010364
Barry Warsaw3155db32000-04-13 15:20:40 +000010365 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010366 PyObject *o = PyLong_FromLong(table[i].value);
10367 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10368 Py_XDECREF(o);
10369 Py_DECREF(d);
10370 return -1;
10371 }
10372 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010373 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010374 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010375}
10376
Fred Drakebec628d1999-12-15 18:31:10 +000010377/* Return -1 on failure, 0 on success. */
10378static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010379setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010380{
10381#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010382 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010383 sizeof(posix_constants_pathconf)
10384 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010385 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010386 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010387#endif
10388#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010389 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010390 sizeof(posix_constants_confstr)
10391 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010392 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010393 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010394#endif
10395#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010396 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010397 sizeof(posix_constants_sysconf)
10398 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010399 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010400 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010401#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010402 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010403}
Fred Draked86ed291999-12-15 15:34:33 +000010404
10405
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010406PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010407"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010408Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010409in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010410
10411static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010412posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010413{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010414 abort();
10415 /*NOTREACHED*/
10416 Py_FatalError("abort() called from Python code didn't abort!");
10417 return NULL;
10418}
Fred Drakebec628d1999-12-15 18:31:10 +000010419
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010420#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010421PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010422"startfile(filepath [, operation]) - Start a file with its associated\n\
10423application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010424\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010425When \"operation\" is not specified or \"open\", this acts like\n\
10426double-clicking the file in Explorer, or giving the file name as an\n\
10427argument to the DOS \"start\" command: the file is opened with whatever\n\
10428application (if any) its extension is associated.\n\
10429When another \"operation\" is given, it specifies what should be done with\n\
10430the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010431\n\
10432startfile returns as soon as the associated application is launched.\n\
10433There is no option to wait for the application to close, and no way\n\
10434to retrieve the application's exit status.\n\
10435\n\
10436The filepath is relative to the current directory. If you want to use\n\
10437an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010438the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010439
10440static PyObject *
10441win32_startfile(PyObject *self, PyObject *args)
10442{
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 PyObject *ofilepath;
10444 char *filepath;
10445 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010446 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010447 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010448
Victor Stinnereb5657a2011-09-30 01:44:27 +020010449 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010450 if (!PyArg_ParseTuple(args, "U|s:startfile",
10451 &unipath, &operation)) {
10452 PyErr_Clear();
10453 goto normal;
10454 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010455
Victor Stinner8c62be82010-05-06 00:08:46 +000010456 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010457 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010459 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 PyErr_Clear();
10461 operation = NULL;
10462 goto normal;
10463 }
10464 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010465
Victor Stinnereb5657a2011-09-30 01:44:27 +020010466 wpath = PyUnicode_AsUnicode(unipath);
10467 if (wpath == NULL)
10468 goto normal;
10469 if (uoperation) {
10470 woperation = PyUnicode_AsUnicode(uoperation);
10471 if (woperation == NULL)
10472 goto normal;
10473 }
10474 else
10475 woperation = NULL;
10476
Victor Stinner8c62be82010-05-06 00:08:46 +000010477 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010478 rc = ShellExecuteW((HWND)0, woperation, wpath,
10479 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010480 Py_END_ALLOW_THREADS
10481
Victor Stinnereb5657a2011-09-30 01:44:27 +020010482 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010483 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010484 win32_error_object("startfile", unipath);
10485 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 }
10487 Py_INCREF(Py_None);
10488 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010489
10490normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10492 PyUnicode_FSConverter, &ofilepath,
10493 &operation))
10494 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010495 if (win32_warn_bytes_api()) {
10496 Py_DECREF(ofilepath);
10497 return NULL;
10498 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 filepath = PyBytes_AsString(ofilepath);
10500 Py_BEGIN_ALLOW_THREADS
10501 rc = ShellExecute((HWND)0, operation, filepath,
10502 NULL, NULL, SW_SHOWNORMAL);
10503 Py_END_ALLOW_THREADS
10504 if (rc <= (HINSTANCE)32) {
10505 PyObject *errval = win32_error("startfile", filepath);
10506 Py_DECREF(ofilepath);
10507 return errval;
10508 }
10509 Py_DECREF(ofilepath);
10510 Py_INCREF(Py_None);
10511 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010512}
10513#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010514
Martin v. Löwis438b5342002-12-27 10:16:42 +000010515#ifdef HAVE_GETLOADAVG
10516PyDoc_STRVAR(posix_getloadavg__doc__,
10517"getloadavg() -> (float, float, float)\n\n\
10518Return the number of processes in the system run queue averaged over\n\
10519the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10520was unobtainable");
10521
10522static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010523posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010524{
10525 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010526 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010527 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10528 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010529 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010530 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010531}
10532#endif
10533
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010534PyDoc_STRVAR(device_encoding__doc__,
10535"device_encoding(fd) -> str\n\n\
10536Return a string describing the encoding of the device\n\
10537if the output is a terminal; else return None.");
10538
10539static PyObject *
10540device_encoding(PyObject *self, PyObject *args)
10541{
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010543
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10545 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010546
10547 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010548}
10549
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010550#ifdef HAVE_SETRESUID
10551PyDoc_STRVAR(posix_setresuid__doc__,
10552"setresuid(ruid, euid, suid)\n\n\
10553Set the current process's real, effective, and saved user ids.");
10554
10555static PyObject*
10556posix_setresuid (PyObject *self, PyObject *args)
10557{
Victor Stinner8c62be82010-05-06 00:08:46 +000010558 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010559 uid_t ruid, euid, suid;
10560 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10561 _Py_Uid_Converter, &ruid,
10562 _Py_Uid_Converter, &euid,
10563 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010564 return NULL;
10565 if (setresuid(ruid, euid, suid) < 0)
10566 return posix_error();
10567 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010568}
10569#endif
10570
10571#ifdef HAVE_SETRESGID
10572PyDoc_STRVAR(posix_setresgid__doc__,
10573"setresgid(rgid, egid, sgid)\n\n\
10574Set the current process's real, effective, and saved group ids.");
10575
10576static PyObject*
10577posix_setresgid (PyObject *self, PyObject *args)
10578{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010579 gid_t rgid, egid, sgid;
10580 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10581 _Py_Gid_Converter, &rgid,
10582 _Py_Gid_Converter, &egid,
10583 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 return NULL;
10585 if (setresgid(rgid, egid, sgid) < 0)
10586 return posix_error();
10587 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010588}
10589#endif
10590
10591#ifdef HAVE_GETRESUID
10592PyDoc_STRVAR(posix_getresuid__doc__,
10593"getresuid() -> (ruid, euid, suid)\n\n\
10594Get tuple of the current process's real, effective, and saved user ids.");
10595
10596static PyObject*
10597posix_getresuid (PyObject *self, PyObject *noargs)
10598{
Victor Stinner8c62be82010-05-06 00:08:46 +000010599 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010600 if (getresuid(&ruid, &euid, &suid) < 0)
10601 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010602 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10603 _PyLong_FromUid(euid),
10604 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010605}
10606#endif
10607
10608#ifdef HAVE_GETRESGID
10609PyDoc_STRVAR(posix_getresgid__doc__,
10610"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010611Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010612
10613static PyObject*
10614posix_getresgid (PyObject *self, PyObject *noargs)
10615{
Victor Stinner8c62be82010-05-06 00:08:46 +000010616 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010617 if (getresgid(&rgid, &egid, &sgid) < 0)
10618 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010619 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10620 _PyLong_FromGid(egid),
10621 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010622}
10623#endif
10624
Benjamin Peterson9428d532011-09-14 11:45:52 -040010625#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010626
Benjamin Peterson799bd802011-08-31 22:15:17 -040010627PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010628"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10629Return the value of extended attribute attribute on path.\n\
10630\n\
10631path may be either a string or an open file descriptor.\n\
10632If follow_symlinks is False, and the last element of the path is a symbolic\n\
10633 link, getxattr will examine the symbolic link itself instead of the file\n\
10634 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010635
10636static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010637posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010638{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010639 path_t path;
10640 path_t attribute;
10641 int follow_symlinks = 1;
10642 PyObject *buffer = NULL;
10643 int i;
10644 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010645
Larry Hastings9cf065c2012-06-22 16:30:09 -070010646 memset(&path, 0, sizeof(path));
10647 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010648 path.function_name = "getxattr";
10649 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010650 path.allow_fd = 1;
10651 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10652 path_converter, &path,
10653 path_converter, &attribute,
10654 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010655 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010656
Larry Hastings9cf065c2012-06-22 16:30:09 -070010657 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10658 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010659
Larry Hastings9cf065c2012-06-22 16:30:09 -070010660 for (i = 0; ; i++) {
10661 void *ptr;
10662 ssize_t result;
10663 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10664 Py_ssize_t buffer_size = buffer_sizes[i];
10665 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010666 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010667 goto exit;
10668 }
10669 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10670 if (!buffer)
10671 goto exit;
10672 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010673
Larry Hastings9cf065c2012-06-22 16:30:09 -070010674 Py_BEGIN_ALLOW_THREADS;
10675 if (path.fd >= 0)
10676 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10677 else if (follow_symlinks)
10678 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10679 else
10680 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10681 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010682
Larry Hastings9cf065c2012-06-22 16:30:09 -070010683 if (result < 0) {
10684 Py_DECREF(buffer);
10685 buffer = NULL;
10686 if (errno == ERANGE)
10687 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010688 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010689 goto exit;
10690 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010691
Larry Hastings9cf065c2012-06-22 16:30:09 -070010692 if (result != buffer_size) {
10693 /* Can only shrink. */
10694 _PyBytes_Resize(&buffer, result);
10695 }
10696 break;
10697 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010698
Larry Hastings9cf065c2012-06-22 16:30:09 -070010699exit:
10700 path_cleanup(&path);
10701 path_cleanup(&attribute);
10702 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010703}
10704
10705PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010706"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10707Set extended attribute attribute on path to value.\n\
10708path may be either a string or an open file descriptor.\n\
10709If follow_symlinks is False, and the last element of the path is a symbolic\n\
10710 link, setxattr will modify the symbolic link itself instead of the file\n\
10711 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010712
10713static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010714posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010715{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010716 path_t path;
10717 path_t attribute;
10718 Py_buffer value;
10719 int flags = 0;
10720 int follow_symlinks = 1;
10721 int result;
10722 PyObject *return_value = NULL;
10723 static char *keywords[] = {"path", "attribute", "value",
10724 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010725
Larry Hastings9cf065c2012-06-22 16:30:09 -070010726 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010727 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010728 path.allow_fd = 1;
10729 memset(&attribute, 0, sizeof(attribute));
10730 memset(&value, 0, sizeof(value));
10731 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10732 keywords,
10733 path_converter, &path,
10734 path_converter, &attribute,
10735 &value, &flags,
10736 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010737 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010738
10739 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10740 goto exit;
10741
Benjamin Peterson799bd802011-08-31 22:15:17 -040010742 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010743 if (path.fd > -1)
10744 result = fsetxattr(path.fd, attribute.narrow,
10745 value.buf, value.len, flags);
10746 else if (follow_symlinks)
10747 result = setxattr(path.narrow, attribute.narrow,
10748 value.buf, value.len, flags);
10749 else
10750 result = lsetxattr(path.narrow, attribute.narrow,
10751 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010752 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010753
Larry Hastings9cf065c2012-06-22 16:30:09 -070010754 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010755 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010756 goto exit;
10757 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010758
Larry Hastings9cf065c2012-06-22 16:30:09 -070010759 return_value = Py_None;
10760 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010761
Larry Hastings9cf065c2012-06-22 16:30:09 -070010762exit:
10763 path_cleanup(&path);
10764 path_cleanup(&attribute);
10765 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010766
Larry Hastings9cf065c2012-06-22 16:30:09 -070010767 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010768}
10769
10770PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010771"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10772Remove extended attribute attribute on path.\n\
10773path may be either a string or an open file descriptor.\n\
10774If follow_symlinks is False, and the last element of the path is a symbolic\n\
10775 link, removexattr will modify the symbolic link itself instead of the file\n\
10776 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010777
10778static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010779posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010780{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010781 path_t path;
10782 path_t attribute;
10783 int follow_symlinks = 1;
10784 int result;
10785 PyObject *return_value = NULL;
10786 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010787
Larry Hastings9cf065c2012-06-22 16:30:09 -070010788 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010789 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010790 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010791 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010792 path.allow_fd = 1;
10793 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10794 keywords,
10795 path_converter, &path,
10796 path_converter, &attribute,
10797 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010798 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010799
10800 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10801 goto exit;
10802
Benjamin Peterson799bd802011-08-31 22:15:17 -040010803 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010804 if (path.fd > -1)
10805 result = fremovexattr(path.fd, attribute.narrow);
10806 else if (follow_symlinks)
10807 result = removexattr(path.narrow, attribute.narrow);
10808 else
10809 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010810 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010811
Larry Hastings9cf065c2012-06-22 16:30:09 -070010812 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010813 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010814 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010815 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010816
Larry Hastings9cf065c2012-06-22 16:30:09 -070010817 return_value = Py_None;
10818 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010819
Larry Hastings9cf065c2012-06-22 16:30:09 -070010820exit:
10821 path_cleanup(&path);
10822 path_cleanup(&attribute);
10823
10824 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010825}
10826
10827PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010828"listxattr(path='.', *, follow_symlinks=True)\n\n\
10829Return a list of extended attributes on path.\n\
10830\n\
10831path may be either None, a string, or an open file descriptor.\n\
10832if path is None, listxattr will examine the current directory.\n\
10833If follow_symlinks is False, and the last element of the path is a symbolic\n\
10834 link, listxattr will examine the symbolic link itself instead of the file\n\
10835 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010836
10837static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010838posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010839{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010840 path_t path;
10841 int follow_symlinks = 1;
10842 Py_ssize_t i;
10843 PyObject *result = NULL;
10844 char *buffer = NULL;
10845 char *name;
10846 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010847
Larry Hastings9cf065c2012-06-22 16:30:09 -070010848 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010849 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010850 path.allow_fd = 1;
10851 path.fd = -1;
10852 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10853 path_converter, &path,
10854 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010855 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010856
Larry Hastings9cf065c2012-06-22 16:30:09 -070010857 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10858 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010859
Larry Hastings9cf065c2012-06-22 16:30:09 -070010860 name = path.narrow ? path.narrow : ".";
10861 for (i = 0; ; i++) {
10862 char *start, *trace, *end;
10863 ssize_t length;
10864 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10865 Py_ssize_t buffer_size = buffer_sizes[i];
10866 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010867 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010868 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010869 break;
10870 }
10871 buffer = PyMem_MALLOC(buffer_size);
10872 if (!buffer) {
10873 PyErr_NoMemory();
10874 break;
10875 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010876
Larry Hastings9cf065c2012-06-22 16:30:09 -070010877 Py_BEGIN_ALLOW_THREADS;
10878 if (path.fd > -1)
10879 length = flistxattr(path.fd, buffer, buffer_size);
10880 else if (follow_symlinks)
10881 length = listxattr(name, buffer, buffer_size);
10882 else
10883 length = llistxattr(name, buffer, buffer_size);
10884 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010885
Larry Hastings9cf065c2012-06-22 16:30:09 -070010886 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010887 if (errno == ERANGE) {
10888 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010889 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010890 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010891 }
Victor Stinner292c8352012-10-30 02:17:38 +010010892 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010893 break;
10894 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010895
Larry Hastings9cf065c2012-06-22 16:30:09 -070010896 result = PyList_New(0);
10897 if (!result) {
10898 goto exit;
10899 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010900
Larry Hastings9cf065c2012-06-22 16:30:09 -070010901 end = buffer + length;
10902 for (trace = start = buffer; trace != end; trace++) {
10903 if (!*trace) {
10904 int error;
10905 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10906 trace - start);
10907 if (!attribute) {
10908 Py_DECREF(result);
10909 result = NULL;
10910 goto exit;
10911 }
10912 error = PyList_Append(result, attribute);
10913 Py_DECREF(attribute);
10914 if (error) {
10915 Py_DECREF(result);
10916 result = NULL;
10917 goto exit;
10918 }
10919 start = trace + 1;
10920 }
10921 }
10922 break;
10923 }
10924exit:
10925 path_cleanup(&path);
10926 if (buffer)
10927 PyMem_FREE(buffer);
10928 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010929}
10930
Benjamin Peterson9428d532011-09-14 11:45:52 -040010931#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010932
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010933
Georg Brandl2fb477c2012-02-21 00:33:36 +010010934PyDoc_STRVAR(posix_urandom__doc__,
10935"urandom(n) -> str\n\n\
10936Return n random bytes suitable for cryptographic use.");
10937
10938static PyObject *
10939posix_urandom(PyObject *self, PyObject *args)
10940{
10941 Py_ssize_t size;
10942 PyObject *result;
10943 int ret;
10944
10945 /* Read arguments */
10946 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10947 return NULL;
10948 if (size < 0)
10949 return PyErr_Format(PyExc_ValueError,
10950 "negative argument not allowed");
10951 result = PyBytes_FromStringAndSize(NULL, size);
10952 if (result == NULL)
10953 return NULL;
10954
10955 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10956 PyBytes_GET_SIZE(result));
10957 if (ret == -1) {
10958 Py_DECREF(result);
10959 return NULL;
10960 }
10961 return result;
10962}
10963
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010964/* Terminal size querying */
10965
10966static PyTypeObject TerminalSizeType;
10967
10968PyDoc_STRVAR(TerminalSize_docstring,
10969 "A tuple of (columns, lines) for holding terminal window size");
10970
10971static PyStructSequence_Field TerminalSize_fields[] = {
10972 {"columns", "width of the terminal window in characters"},
10973 {"lines", "height of the terminal window in characters"},
10974 {NULL, NULL}
10975};
10976
10977static PyStructSequence_Desc TerminalSize_desc = {
10978 "os.terminal_size",
10979 TerminalSize_docstring,
10980 TerminalSize_fields,
10981 2,
10982};
10983
10984#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10985PyDoc_STRVAR(termsize__doc__,
10986 "Return the size of the terminal window as (columns, lines).\n" \
10987 "\n" \
10988 "The optional argument fd (default standard output) specifies\n" \
10989 "which file descriptor should be queried.\n" \
10990 "\n" \
10991 "If the file descriptor is not connected to a terminal, an OSError\n" \
10992 "is thrown.\n" \
10993 "\n" \
10994 "This function will only be defined if an implementation is\n" \
10995 "available for this system.\n" \
10996 "\n" \
10997 "shutil.get_terminal_size is the high-level function which should \n" \
10998 "normally be used, os.get_terminal_size is the low-level implementation.");
10999
11000static PyObject*
11001get_terminal_size(PyObject *self, PyObject *args)
11002{
11003 int columns, lines;
11004 PyObject *termsize;
11005
11006 int fd = fileno(stdout);
11007 /* Under some conditions stdout may not be connected and
11008 * fileno(stdout) may point to an invalid file descriptor. For example
11009 * GUI apps don't have valid standard streams by default.
11010 *
11011 * If this happens, and the optional fd argument is not present,
11012 * the ioctl below will fail returning EBADF. This is what we want.
11013 */
11014
11015 if (!PyArg_ParseTuple(args, "|i", &fd))
11016 return NULL;
11017
11018#ifdef TERMSIZE_USE_IOCTL
11019 {
11020 struct winsize w;
11021 if (ioctl(fd, TIOCGWINSZ, &w))
11022 return PyErr_SetFromErrno(PyExc_OSError);
11023 columns = w.ws_col;
11024 lines = w.ws_row;
11025 }
11026#endif /* TERMSIZE_USE_IOCTL */
11027
11028#ifdef TERMSIZE_USE_CONIO
11029 {
11030 DWORD nhandle;
11031 HANDLE handle;
11032 CONSOLE_SCREEN_BUFFER_INFO csbi;
11033 switch (fd) {
11034 case 0: nhandle = STD_INPUT_HANDLE;
11035 break;
11036 case 1: nhandle = STD_OUTPUT_HANDLE;
11037 break;
11038 case 2: nhandle = STD_ERROR_HANDLE;
11039 break;
11040 default:
11041 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11042 }
11043 handle = GetStdHandle(nhandle);
11044 if (handle == NULL)
11045 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11046 if (handle == INVALID_HANDLE_VALUE)
11047 return PyErr_SetFromWindowsErr(0);
11048
11049 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11050 return PyErr_SetFromWindowsErr(0);
11051
11052 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11053 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11054 }
11055#endif /* TERMSIZE_USE_CONIO */
11056
11057 termsize = PyStructSequence_New(&TerminalSizeType);
11058 if (termsize == NULL)
11059 return NULL;
11060 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11061 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11062 if (PyErr_Occurred()) {
11063 Py_DECREF(termsize);
11064 return NULL;
11065 }
11066 return termsize;
11067}
11068#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11069
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011070PyDoc_STRVAR(posix_cpu_count__doc__,
11071"cpu_count() -> integer\n\n\
11072Return the number of CPUs in the system, or None if this value cannot be\n\
11073established.");
11074
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011075static PyObject *
11076posix_cpu_count(PyObject *self)
11077{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011078 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011079#ifdef MS_WINDOWS
11080 SYSTEM_INFO sysinfo;
11081 GetSystemInfo(&sysinfo);
11082 ncpu = sysinfo.dwNumberOfProcessors;
11083#elif defined(__hpux)
11084 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11085#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11086 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011087#elif defined(__DragonFly__) || \
11088 defined(__OpenBSD__) || \
11089 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011090 defined(__NetBSD__) || \
11091 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011092 int mib[2];
11093 size_t len = sizeof(ncpu);
11094 mib[0] = CTL_HW;
11095 mib[1] = HW_NCPU;
11096 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11097 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011098#endif
11099 if (ncpu >= 1)
11100 return PyLong_FromLong(ncpu);
11101 else
11102 Py_RETURN_NONE;
11103}
11104
Victor Stinnerdaf45552013-08-28 00:53:59 +020011105PyDoc_STRVAR(get_inheritable__doc__,
11106 "get_inheritable(fd) -> bool\n" \
11107 "\n" \
11108 "Get the close-on-exe flag of the specified file descriptor.");
11109
11110static PyObject*
11111posix_get_inheritable(PyObject *self, PyObject *args)
11112{
11113 int fd;
11114 int inheritable;
11115
11116 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd))
11117 return NULL;
11118
11119 if (!_PyVerify_fd(fd))
11120 return posix_error();
11121
11122 inheritable = _Py_get_inheritable(fd);
11123 if (inheritable < 0)
11124 return NULL;
11125 return PyBool_FromLong(inheritable);
11126}
11127
11128PyDoc_STRVAR(set_inheritable__doc__,
11129 "set_inheritable(fd, inheritable)\n" \
11130 "\n" \
11131 "Set the inheritable flag of the specified file descriptor.");
11132
11133static PyObject*
11134posix_set_inheritable(PyObject *self, PyObject *args)
11135{
11136 int fd, inheritable;
11137
11138 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable))
11139 return NULL;
11140
11141 if (!_PyVerify_fd(fd))
11142 return posix_error();
11143
11144 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
11145 return NULL;
11146 Py_RETURN_NONE;
11147}
11148
11149
11150#ifdef MS_WINDOWS
11151PyDoc_STRVAR(get_handle_inheritable__doc__,
11152 "get_handle_inheritable(fd) -> bool\n" \
11153 "\n" \
11154 "Get the close-on-exe flag of the specified file descriptor.");
11155
11156static PyObject*
11157posix_get_handle_inheritable(PyObject *self, PyObject *args)
11158{
11159 Py_intptr_t handle;
11160 DWORD flags;
11161
11162 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle))
11163 return NULL;
11164
11165 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11166 PyErr_SetFromWindowsErr(0);
11167 return NULL;
11168 }
11169
11170 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT);
11171}
11172
11173PyDoc_STRVAR(set_handle_inheritable__doc__,
11174 "set_handle_inheritable(fd, inheritable)\n" \
11175 "\n" \
11176 "Set the inheritable flag of the specified handle.");
11177
11178static PyObject*
11179posix_set_handle_inheritable(PyObject *self, PyObject *args)
11180{
11181 int inheritable = 1;
11182 Py_intptr_t handle;
11183 DWORD flags;
11184
11185 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable",
11186 &handle, &inheritable))
11187 return NULL;
11188
11189 if (inheritable)
11190 flags = HANDLE_FLAG_INHERIT;
11191 else
11192 flags = 0;
11193 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11194 PyErr_SetFromWindowsErr(0);
11195 return NULL;
11196 }
11197 Py_RETURN_NONE;
11198}
11199#endif /* MS_WINDOWS */
11200
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011201
Larry Hastings7726ac92014-01-31 22:03:12 -080011202/*[clinic input]
11203dump buffer
11204[clinic start generated code]*/
11205
11206#ifndef OS_TTYNAME_METHODDEF
11207 #define OS_TTYNAME_METHODDEF
11208#endif /* !defined(OS_TTYNAME_METHODDEF) */
11209/*[clinic end generated code: output=5d071bbc8f49ea12 input=524ce2e021e4eba6]*/
11210
Larry Hastings31826802013-10-19 00:09:25 -070011211
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011212static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070011213
11214 OS_STAT_METHODDEF
11215 OS_ACCESS_METHODDEF
11216 OS_TTYNAME_METHODDEF
11217
Larry Hastings9cf065c2012-06-22 16:30:09 -070011218 {"chdir", (PyCFunction)posix_chdir,
11219 METH_VARARGS | METH_KEYWORDS,
11220 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011221#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011222 {"chflags", (PyCFunction)posix_chflags,
11223 METH_VARARGS | METH_KEYWORDS,
11224 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011225#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011226 {"chmod", (PyCFunction)posix_chmod,
11227 METH_VARARGS | METH_KEYWORDS,
11228 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011229#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011230 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011231#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011232#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070011233 {"chown", (PyCFunction)posix_chown,
11234 METH_VARARGS | METH_KEYWORDS,
11235 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011236#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000011237#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011239#endif /* HAVE_LCHMOD */
11240#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011242#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000011243#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011245#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011246#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011248#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000011249#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000011250 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000011251#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011252#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011254#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011255 {"getcwd", (PyCFunction)posix_getcwd_unicode,
11256 METH_NOARGS, posix_getcwd__doc__},
11257 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
11258 METH_NOARGS, posix_getcwdb__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011259#if defined(HAVE_LINK) || defined(MS_WINDOWS)
11260 {"link", (PyCFunction)posix_link,
11261 METH_VARARGS | METH_KEYWORDS,
11262 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011263#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011264 {"listdir", (PyCFunction)posix_listdir,
11265 METH_VARARGS | METH_KEYWORDS,
11266 posix_listdir__doc__},
11267 {"lstat", (PyCFunction)posix_lstat,
11268 METH_VARARGS | METH_KEYWORDS,
11269 posix_lstat__doc__},
11270 {"mkdir", (PyCFunction)posix_mkdir,
11271 METH_VARARGS | METH_KEYWORDS,
11272 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011273#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011274 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011275#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011276#ifdef HAVE_GETPRIORITY
11277 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11278#endif /* HAVE_GETPRIORITY */
11279#ifdef HAVE_SETPRIORITY
11280 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11281#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011282#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011283 {"readlink", (PyCFunction)posix_readlink,
11284 METH_VARARGS | METH_KEYWORDS,
11285 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011286#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011287#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011288 {"readlink", (PyCFunction)win_readlink,
11289 METH_VARARGS | METH_KEYWORDS,
11290 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011291#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011292 {"rename", (PyCFunction)posix_rename,
11293 METH_VARARGS | METH_KEYWORDS,
11294 posix_rename__doc__},
11295 {"replace", (PyCFunction)posix_replace,
11296 METH_VARARGS | METH_KEYWORDS,
11297 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011298 {"rmdir", (PyCFunction)posix_rmdir,
11299 METH_VARARGS | METH_KEYWORDS,
11300 posix_rmdir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011302#if defined(HAVE_SYMLINK)
11303 {"symlink", (PyCFunction)posix_symlink,
11304 METH_VARARGS | METH_KEYWORDS,
11305 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011306#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011307#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011308 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011309#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011311#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011313#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011314 {"unlink", (PyCFunction)posix_unlink,
11315 METH_VARARGS | METH_KEYWORDS,
11316 posix_unlink__doc__},
11317 {"remove", (PyCFunction)posix_unlink,
11318 METH_VARARGS | METH_KEYWORDS,
11319 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011320 {"utime", (PyCFunction)posix_utime,
11321 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011322#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011323 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011324#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011326#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011327 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011328 {"execve", (PyCFunction)posix_execve,
11329 METH_VARARGS | METH_KEYWORDS,
11330 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011331#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011332#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011333 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11334 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000011335#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011336#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011338#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011339#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011340 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011341#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011342#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011343#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011344 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11345 {"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 +020011346#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011347#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011348 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011349#endif
11350#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011351 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011352#endif
11353#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011354 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011355#endif
11356#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011357 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011358#endif
11359#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011360 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011361#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011362 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011363#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011364 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11365 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11366#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011367#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011368#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011369 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011370#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011371#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011372 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011373#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011374#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011376#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011377#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011378 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011379#endif /* HAVE_GETEUID */
11380#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011382#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011383#ifdef HAVE_GETGROUPLIST
11384 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11385#endif
Fred Drakec9680921999-12-13 16:37:25 +000011386#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011388#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011389 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011390#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011392#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011393#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011394 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011395#endif /* HAVE_GETPPID */
11396#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011397 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011398#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011399#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011400 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011401#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011402#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011403 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011404#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011405#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011406 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011407#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011408#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011409 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011410#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011411#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011412 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11413 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011414#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011415#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011416 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011417#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011418#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011419 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011420#endif /* HAVE_SETEUID */
11421#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011422 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011423#endif /* HAVE_SETEGID */
11424#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011425 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011426#endif /* HAVE_SETREUID */
11427#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011428 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011429#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011430#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011431 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011432#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011433#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011434 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011435#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011436#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011437 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011438#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011439#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011440 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011441#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011442#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011443 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011444#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011445#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011446 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011447#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011448#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011449 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011450#endif /* HAVE_WAIT3 */
11451#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011452 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011453#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011454#if defined(HAVE_WAITID) && !defined(__APPLE__)
11455 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11456#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011457#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011458 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011459#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011460#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011461 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011462#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011463#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011464 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011465#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011466#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011467 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011468#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011469#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011470 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011471#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011472#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011473 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011474#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011475 {"open", (PyCFunction)posix_open,\
11476 METH_VARARGS | METH_KEYWORDS,
11477 posix_open__doc__},
Benjamin Peterson932bba32014-02-11 10:16:16 -050011478 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011479 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11480 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11481 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011482 {"dup2", (PyCFunction)posix_dup2,
11483 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011484#ifdef HAVE_LOCKF
11485 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11486#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011487 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11488 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011489#ifdef HAVE_READV
11490 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11491#endif
11492#ifdef HAVE_PREAD
11493 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11494#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011495 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011496#ifdef HAVE_WRITEV
11497 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11498#endif
11499#ifdef HAVE_PWRITE
11500 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11501#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011502#ifdef HAVE_SENDFILE
11503 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11504 posix_sendfile__doc__},
11505#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011506 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011507 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011508#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011509 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011510#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011511#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011512 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011513#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011514#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011515 {"mkfifo", (PyCFunction)posix_mkfifo,
11516 METH_VARARGS | METH_KEYWORDS,
11517 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011518#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011519#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011520 {"mknod", (PyCFunction)posix_mknod,
11521 METH_VARARGS | METH_KEYWORDS,
11522 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011523#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011524#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011525 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11526 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11527 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011528#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011529#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011530 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011531#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011532#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011533 {"truncate", (PyCFunction)posix_truncate,
11534 METH_VARARGS | METH_KEYWORDS,
11535 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011536#endif
Victor Stinnerd6b17692014-09-30 12:20:05 +020011537#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011538 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11539#endif
Victor Stinnerd6b17692014-09-30 12:20:05 +020011540#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011541 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11542#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011543#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011544 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011545#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011546#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011547 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011548#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011549 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011550#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011551 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011552#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011553#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011554 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011555#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011556#ifdef HAVE_SYNC
11557 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11558#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011559#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011560 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011561#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011562#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011563#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011564 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011565#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011566#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011567 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011568#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011569#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011570 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011571#endif /* WIFSTOPPED */
11572#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011573 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011574#endif /* WIFSIGNALED */
11575#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011576 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011577#endif /* WIFEXITED */
11578#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011579 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011580#endif /* WEXITSTATUS */
11581#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011582 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011583#endif /* WTERMSIG */
11584#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011585 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011586#endif /* WSTOPSIG */
11587#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011588#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011589 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011590#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011591#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011592 {"statvfs", (PyCFunction)posix_statvfs,
11593 METH_VARARGS | METH_KEYWORDS,
11594 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011595#endif
Fred Drakec9680921999-12-13 16:37:25 +000011596#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011597 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011598#endif
11599#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011600 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011601#endif
11602#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011603 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011604#endif
11605#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011606 {"pathconf", (PyCFunction)posix_pathconf,
11607 METH_VARARGS | METH_KEYWORDS,
11608 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011609#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011610 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011611#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011612 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011613 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011614 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011615 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011616 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011617#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011618#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011619 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011620#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011621 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011622#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011623 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011624#endif
11625#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011626 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011627#endif
11628#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011629 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011630#endif
11631#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011632 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011633#endif
11634
Benjamin Peterson9428d532011-09-14 11:45:52 -040011635#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011636 {"setxattr", (PyCFunction)posix_setxattr,
11637 METH_VARARGS | METH_KEYWORDS,
11638 posix_setxattr__doc__},
11639 {"getxattr", (PyCFunction)posix_getxattr,
11640 METH_VARARGS | METH_KEYWORDS,
11641 posix_getxattr__doc__},
11642 {"removexattr", (PyCFunction)posix_removexattr,
11643 METH_VARARGS | METH_KEYWORDS,
11644 posix_removexattr__doc__},
11645 {"listxattr", (PyCFunction)posix_listxattr,
11646 METH_VARARGS | METH_KEYWORDS,
11647 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011648#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011649#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11650 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11651#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011652 {"cpu_count", (PyCFunction)posix_cpu_count,
11653 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011654 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__},
11655 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__},
11656#ifdef MS_WINDOWS
11657 {"get_handle_inheritable", posix_get_handle_inheritable,
11658 METH_VARARGS, get_handle_inheritable__doc__},
11659 {"set_handle_inheritable", posix_set_handle_inheritable,
11660 METH_VARARGS, set_handle_inheritable__doc__},
11661#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011662 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011663};
11664
11665
Brian Curtin52173d42010-12-02 18:29:18 +000011666#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011667static int
Brian Curtin52173d42010-12-02 18:29:18 +000011668enable_symlink()
11669{
11670 HANDLE tok;
11671 TOKEN_PRIVILEGES tok_priv;
11672 LUID luid;
11673 int meth_idx = 0;
11674
11675 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011676 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011677
11678 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011679 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011680
11681 tok_priv.PrivilegeCount = 1;
11682 tok_priv.Privileges[0].Luid = luid;
11683 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11684
11685 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11686 sizeof(TOKEN_PRIVILEGES),
11687 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011688 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011689
Brian Curtin3b4499c2010-12-28 14:31:47 +000011690 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11691 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011692}
11693#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11694
Barry Warsaw4a342091996-12-19 23:50:02 +000011695static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011696all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011697{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011698#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011699 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011700#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011701#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011702 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011703#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011704#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011705 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011706#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011707#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011708 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011709#endif
Fred Drakec9680921999-12-13 16:37:25 +000011710#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011711 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011712#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011713#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011714 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011715#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011716#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011717 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011718#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011719#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011720 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011721#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011722#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011723 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011724#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011725#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011726 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011727#endif
11728#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011729 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011730#endif
11731#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011732 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011733#endif
11734#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011735 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011736#endif
11737#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011738 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011739#endif
11740#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011741 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011742#endif
11743#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011744 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011745#endif
11746#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011747 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011748#endif
11749#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011750 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011751#endif
11752#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011753 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011754#endif
11755#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011756 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011757#endif
11758#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011759 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011760#endif
11761#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011762 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011763#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011764#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011765 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011766#endif
11767#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011768 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011769#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011770#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011771 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011772#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011773#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011774 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011775#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011776#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011777 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011778#endif
11779#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011780 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011781#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011782#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011783 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011784#endif
11785#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011786 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011787#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011788#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011789 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011790#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011791#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011792 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011793#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011794#ifdef O_TMPFILE
11795 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11796#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011797#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011798 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011799#endif
11800#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011801 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011802#endif
11803#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011804 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011805#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011806#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011807 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011808#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011809#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011810 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011811#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011812
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011813
Jesus Cea94363612012-06-22 18:32:07 +020011814#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011815 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011816#endif
11817#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011818 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011819#endif
11820
Tim Peters5aa91602002-01-30 05:46:57 +000011821/* MS Windows */
11822#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011823 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011824 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011825#endif
11826#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011827 /* Optimize for short life (keep in memory). */
11828 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011829 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011830#endif
11831#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011832 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011833 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011834#endif
11835#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011836 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011837 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011838#endif
11839#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011840 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011841 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011842#endif
11843
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011844/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011845#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011846 /* Send a SIGIO signal whenever input or output
11847 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011848 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011849#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011850#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011851 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011852 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011853#endif
11854#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011855 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011856 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011857#endif
11858#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011859 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011860 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011861#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011862#ifdef O_NOLINKS
11863 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011864 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011865#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011866#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011867 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011868 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011869#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011870
Victor Stinner8c62be82010-05-06 00:08:46 +000011871 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011872#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011873 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011874#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011875#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011876 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011877#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011878#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011879 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011880#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011881#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011882 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011883#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011884#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011885 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011886#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011887#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011888 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011889#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011890#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011891 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011892#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011893#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011894 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011895#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011896#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011897 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011898#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011899#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011900 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011901#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011902#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011903 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011904#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011905#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011906 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011907#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011908#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011909 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011910#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011911#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011912 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011913#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011914#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011915 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011916#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011917#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011918 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011919#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011920#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011921 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011922#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011923
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011924 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011925#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011926 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011927#endif /* ST_RDONLY */
11928#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011929 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011930#endif /* ST_NOSUID */
11931
doko@ubuntu.comca616a22013-12-08 15:23:07 +010011932 /* GNU extensions */
11933#ifdef ST_NODEV
11934 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
11935#endif /* ST_NODEV */
11936#ifdef ST_NOEXEC
11937 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
11938#endif /* ST_NOEXEC */
11939#ifdef ST_SYNCHRONOUS
11940 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
11941#endif /* ST_SYNCHRONOUS */
11942#ifdef ST_MANDLOCK
11943 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
11944#endif /* ST_MANDLOCK */
11945#ifdef ST_WRITE
11946 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
11947#endif /* ST_WRITE */
11948#ifdef ST_APPEND
11949 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
11950#endif /* ST_APPEND */
11951#ifdef ST_NOATIME
11952 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
11953#endif /* ST_NOATIME */
11954#ifdef ST_NODIRATIME
11955 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
11956#endif /* ST_NODIRATIME */
11957#ifdef ST_RELATIME
11958 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
11959#endif /* ST_RELATIME */
11960
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011961 /* FreeBSD sendfile() constants */
11962#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011963 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011964#endif
11965#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011966 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011967#endif
11968#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011969 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011970#endif
11971
Ross Lagerwall7807c352011-03-17 20:20:30 +020011972 /* constants for posix_fadvise */
11973#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011974 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011975#endif
11976#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011977 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011978#endif
11979#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011980 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011981#endif
11982#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011983 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011984#endif
11985#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011986 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011987#endif
11988#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011989 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011990#endif
11991
11992 /* constants for waitid */
11993#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011994 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11995 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
11996 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011997#endif
11998#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011999 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012000#endif
12001#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012002 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012003#endif
12004#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012005 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012006#endif
12007#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012008 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012009#endif
12010#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012011 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012012#endif
12013#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012014 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012015#endif
12016#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012017 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012018#endif
12019
12020 /* constants for lockf */
12021#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012022 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012023#endif
12024#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012025 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012026#endif
12027#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012028 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012029#endif
12030#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012031 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012032#endif
12033
Guido van Rossum246bc171999-02-01 23:54:31 +000012034#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012035 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12036 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12037 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12038 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12039 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012040#endif
12041
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012042#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012043 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12044 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12045 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012046#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012047 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012048#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012049#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012050 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012051#endif
12052#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012053 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012054#endif
12055#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012056 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012057#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012058#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012059 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012060#endif
12061#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012062 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012063#endif
12064#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012065 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012066#endif
12067#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012068 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012069#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012070#endif
12071
Benjamin Peterson9428d532011-09-14 11:45:52 -040012072#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012073 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12074 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12075 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012076#endif
12077
Victor Stinner8b905bd2011-10-25 13:34:04 +020012078#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012079 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012080#endif
12081#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012082 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012083#endif
12084#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012085 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012086#endif
12087#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012088 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012089#endif
12090#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012091 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012092#endif
12093#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012094 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012095#endif
12096#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012097 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012098#endif
12099
Victor Stinner8c62be82010-05-06 00:08:46 +000012100 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012101}
12102
12103
Tim Peters5aa91602002-01-30 05:46:57 +000012104#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000012105#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012106#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000012107
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000012108#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000012109#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012110#define MODNAME "posix"
12111#endif
12112
Martin v. Löwis1a214512008-06-11 05:26:20 +000012113static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012114 PyModuleDef_HEAD_INIT,
12115 MODNAME,
12116 posix__doc__,
12117 -1,
12118 posix_methods,
12119 NULL,
12120 NULL,
12121 NULL,
12122 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012123};
12124
12125
Larry Hastings9cf065c2012-06-22 16:30:09 -070012126static char *have_functions[] = {
12127
12128#ifdef HAVE_FACCESSAT
12129 "HAVE_FACCESSAT",
12130#endif
12131
12132#ifdef HAVE_FCHDIR
12133 "HAVE_FCHDIR",
12134#endif
12135
12136#ifdef HAVE_FCHMOD
12137 "HAVE_FCHMOD",
12138#endif
12139
12140#ifdef HAVE_FCHMODAT
12141 "HAVE_FCHMODAT",
12142#endif
12143
12144#ifdef HAVE_FCHOWN
12145 "HAVE_FCHOWN",
12146#endif
12147
Larry Hastings00964ed2013-08-12 13:49:30 -040012148#ifdef HAVE_FCHOWNAT
12149 "HAVE_FCHOWNAT",
12150#endif
12151
Larry Hastings9cf065c2012-06-22 16:30:09 -070012152#ifdef HAVE_FEXECVE
12153 "HAVE_FEXECVE",
12154#endif
12155
12156#ifdef HAVE_FDOPENDIR
12157 "HAVE_FDOPENDIR",
12158#endif
12159
Georg Brandl306336b2012-06-24 12:55:33 +020012160#ifdef HAVE_FPATHCONF
12161 "HAVE_FPATHCONF",
12162#endif
12163
Larry Hastings9cf065c2012-06-22 16:30:09 -070012164#ifdef HAVE_FSTATAT
12165 "HAVE_FSTATAT",
12166#endif
12167
12168#ifdef HAVE_FSTATVFS
12169 "HAVE_FSTATVFS",
12170#endif
12171
Georg Brandl306336b2012-06-24 12:55:33 +020012172#ifdef HAVE_FTRUNCATE
12173 "HAVE_FTRUNCATE",
12174#endif
12175
Larry Hastings9cf065c2012-06-22 16:30:09 -070012176#ifdef HAVE_FUTIMENS
12177 "HAVE_FUTIMENS",
12178#endif
12179
12180#ifdef HAVE_FUTIMES
12181 "HAVE_FUTIMES",
12182#endif
12183
12184#ifdef HAVE_FUTIMESAT
12185 "HAVE_FUTIMESAT",
12186#endif
12187
12188#ifdef HAVE_LINKAT
12189 "HAVE_LINKAT",
12190#endif
12191
12192#ifdef HAVE_LCHFLAGS
12193 "HAVE_LCHFLAGS",
12194#endif
12195
12196#ifdef HAVE_LCHMOD
12197 "HAVE_LCHMOD",
12198#endif
12199
12200#ifdef HAVE_LCHOWN
12201 "HAVE_LCHOWN",
12202#endif
12203
12204#ifdef HAVE_LSTAT
12205 "HAVE_LSTAT",
12206#endif
12207
12208#ifdef HAVE_LUTIMES
12209 "HAVE_LUTIMES",
12210#endif
12211
12212#ifdef HAVE_MKDIRAT
12213 "HAVE_MKDIRAT",
12214#endif
12215
12216#ifdef HAVE_MKFIFOAT
12217 "HAVE_MKFIFOAT",
12218#endif
12219
12220#ifdef HAVE_MKNODAT
12221 "HAVE_MKNODAT",
12222#endif
12223
12224#ifdef HAVE_OPENAT
12225 "HAVE_OPENAT",
12226#endif
12227
12228#ifdef HAVE_READLINKAT
12229 "HAVE_READLINKAT",
12230#endif
12231
12232#ifdef HAVE_RENAMEAT
12233 "HAVE_RENAMEAT",
12234#endif
12235
12236#ifdef HAVE_SYMLINKAT
12237 "HAVE_SYMLINKAT",
12238#endif
12239
12240#ifdef HAVE_UNLINKAT
12241 "HAVE_UNLINKAT",
12242#endif
12243
12244#ifdef HAVE_UTIMENSAT
12245 "HAVE_UTIMENSAT",
12246#endif
12247
12248#ifdef MS_WINDOWS
12249 "MS_WINDOWS",
12250#endif
12251
12252 NULL
12253};
12254
12255
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012256PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012257INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012258{
Victor Stinner8c62be82010-05-06 00:08:46 +000012259 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012260 PyObject *list;
12261 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012262
Brian Curtin52173d42010-12-02 18:29:18 +000012263#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012264 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012265#endif
12266
Victor Stinner8c62be82010-05-06 00:08:46 +000012267 m = PyModule_Create(&posixmodule);
12268 if (m == NULL)
12269 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012270
Victor Stinner8c62be82010-05-06 00:08:46 +000012271 /* Initialize environ dictionary */
12272 v = convertenviron();
12273 Py_XINCREF(v);
12274 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12275 return NULL;
12276 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012277
Victor Stinner8c62be82010-05-06 00:08:46 +000012278 if (all_ins(m))
12279 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012280
Victor Stinner8c62be82010-05-06 00:08:46 +000012281 if (setup_confname_tables(m))
12282 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012283
Victor Stinner8c62be82010-05-06 00:08:46 +000012284 Py_INCREF(PyExc_OSError);
12285 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012286
Guido van Rossumb3d39562000-01-31 18:41:26 +000012287#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012288 if (posix_putenv_garbage == NULL)
12289 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012290#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012291
Victor Stinner8c62be82010-05-06 00:08:46 +000012292 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012293#if defined(HAVE_WAITID) && !defined(__APPLE__)
12294 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012295 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12296 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012297#endif
12298
Christian Heimes25827622013-10-12 01:27:08 +020012299 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012300 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12301 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12302 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012303 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12304 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012305 structseq_new = StatResultType.tp_new;
12306 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012307
Christian Heimes25827622013-10-12 01:27:08 +020012308 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012309 if (PyStructSequence_InitType2(&StatVFSResultType,
12310 &statvfs_result_desc) < 0)
12311 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012312#ifdef NEED_TICKS_PER_SECOND
12313# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012314 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012315# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012316 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012317# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012318 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012319# endif
12320#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012321
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012322#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012323 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012324 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12325 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012326 SchedParamType.tp_new = sched_param_new;
12327#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012328
12329 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012330 if (PyStructSequence_InitType2(&TerminalSizeType,
12331 &TerminalSize_desc) < 0)
12332 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012333 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012334#if defined(HAVE_WAITID) && !defined(__APPLE__)
12335 Py_INCREF((PyObject*) &WaitidResultType);
12336 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12337#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012338 Py_INCREF((PyObject*) &StatResultType);
12339 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12340 Py_INCREF((PyObject*) &StatVFSResultType);
12341 PyModule_AddObject(m, "statvfs_result",
12342 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012343
12344#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012345 Py_INCREF(&SchedParamType);
12346 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012347#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012348
Larry Hastings605a62d2012-06-24 04:33:36 -070012349 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012350 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12351 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012352 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12353
12354 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012355 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12356 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012357 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12358
Thomas Wouters477c8d52006-05-27 19:21:47 +000012359#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012360 /*
12361 * Step 2 of weak-linking support on Mac OS X.
12362 *
12363 * The code below removes functions that are not available on the
12364 * currently active platform.
12365 *
12366 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012367 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012368 * OSX 10.4.
12369 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012370#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012371 if (fstatvfs == NULL) {
12372 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12373 return NULL;
12374 }
12375 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012376#endif /* HAVE_FSTATVFS */
12377
12378#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012379 if (statvfs == NULL) {
12380 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12381 return NULL;
12382 }
12383 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012384#endif /* HAVE_STATVFS */
12385
12386# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012387 if (lchown == NULL) {
12388 if (PyObject_DelAttrString(m, "lchown") == -1) {
12389 return NULL;
12390 }
12391 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012392#endif /* HAVE_LCHOWN */
12393
12394
12395#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012396
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012397 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012398 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12399
Larry Hastings6fe20b32012-04-19 15:07:49 -070012400 billion = PyLong_FromLong(1000000000);
12401 if (!billion)
12402 return NULL;
12403
Larry Hastings9cf065c2012-06-22 16:30:09 -070012404 /* suppress "function not used" warnings */
12405 {
12406 int ignored;
12407 fd_specified("", -1);
12408 follow_symlinks_specified("", 1);
12409 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12410 dir_fd_converter(Py_None, &ignored);
12411 dir_fd_unavailable(Py_None, &ignored);
12412 }
12413
12414 /*
12415 * provide list of locally available functions
12416 * so os.py can populate support_* lists
12417 */
12418 list = PyList_New(0);
12419 if (!list)
12420 return NULL;
12421 for (trace = have_functions; *trace; trace++) {
12422 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12423 if (!unicode)
12424 return NULL;
12425 if (PyList_Append(list, unicode))
12426 return NULL;
12427 Py_DECREF(unicode);
12428 }
12429 PyModule_AddObject(m, "_have_functions", list);
12430
12431 initialized = 1;
12432
Victor Stinner8c62be82010-05-06 00:08:46 +000012433 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000012434}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012435
12436#ifdef __cplusplus
12437}
12438#endif