blob: e2d9b5c9e226f9a16aba2cd5f62ed06753d3064c [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
Larry Hastings9cf065c2012-06-22 16:30:09 -0700626#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400627/*
628 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
629 * without the int cast, the value gets interpreted as uint (4291925331),
630 * which doesn't play nicely with all the initializer lines in this file that
631 * look like this:
632 * int dir_fd = DEFAULT_DIR_FD;
633 */
634#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700635#else
636#define DEFAULT_DIR_FD (-100)
637#endif
638
639static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200640_fd_converter(PyObject *o, int *p, const char *allowed)
641{
642 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700643 long long_value;
644
645 PyObject *index = PyNumber_Index(o);
646 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200647 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700648 "argument should be %s, not %.200s",
649 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700650 return 0;
651 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700652
653 long_value = PyLong_AsLongAndOverflow(index, &overflow);
654 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200655 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700656 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700657 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700658 return 0;
659 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200660 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700661 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700662 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700663 return 0;
664 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700665
Larry Hastings9cf065c2012-06-22 16:30:09 -0700666 *p = (int)long_value;
667 return 1;
668}
669
670static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200671dir_fd_converter(PyObject *o, void *p)
672{
673 if (o == Py_None) {
674 *(int *)p = DEFAULT_DIR_FD;
675 return 1;
676 }
677 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700678}
679
680
681
682/*
683 * A PyArg_ParseTuple "converter" function
684 * that handles filesystem paths in the manner
685 * preferred by the os module.
686 *
687 * path_converter accepts (Unicode) strings and their
688 * subclasses, and bytes and their subclasses. What
689 * it does with the argument depends on the platform:
690 *
691 * * On Windows, if we get a (Unicode) string we
692 * extract the wchar_t * and return it; if we get
693 * bytes we extract the char * and return that.
694 *
695 * * On all other platforms, strings are encoded
696 * to bytes using PyUnicode_FSConverter, then we
697 * extract the char * from the bytes object and
698 * return that.
699 *
700 * path_converter also optionally accepts signed
701 * integers (representing open file descriptors) instead
702 * of path strings.
703 *
704 * Input fields:
705 * path.nullable
706 * If nonzero, the path is permitted to be None.
707 * path.allow_fd
708 * If nonzero, the path is permitted to be a file handle
709 * (a signed int) instead of a string.
710 * path.function_name
711 * If non-NULL, path_converter will use that as the name
712 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700713 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700714 * path.argument_name
715 * If non-NULL, path_converter will use that as the name
716 * of the parameter in error messages.
717 * (If path.argument_name is NULL it uses "path".)
718 *
719 * Output fields:
720 * path.wide
721 * Points to the path if it was expressed as Unicode
722 * and was not encoded. (Only used on Windows.)
723 * path.narrow
724 * Points to the path if it was expressed as bytes,
725 * or it was Unicode and was encoded to bytes.
726 * path.fd
727 * Contains a file descriptor if path.accept_fd was true
728 * and the caller provided a signed integer instead of any
729 * sort of string.
730 *
731 * WARNING: if your "path" parameter is optional, and is
732 * unspecified, path_converter will never get called.
733 * So if you set allow_fd, you *MUST* initialize path.fd = -1
734 * yourself!
735 * path.length
736 * The length of the path in characters, if specified as
737 * a string.
738 * path.object
739 * The original object passed in.
740 * path.cleanup
741 * For internal use only. May point to a temporary object.
742 * (Pay no attention to the man behind the curtain.)
743 *
744 * At most one of path.wide or path.narrow will be non-NULL.
745 * If path was None and path.nullable was set,
746 * or if path was an integer and path.allow_fd was set,
747 * both path.wide and path.narrow will be NULL
748 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200749 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700750 * path_converter takes care to not write to the path_t
751 * unless it's successful. However it must reset the
752 * "cleanup" field each time it's called.
753 *
754 * Use as follows:
755 * path_t path;
756 * memset(&path, 0, sizeof(path));
757 * PyArg_ParseTuple(args, "O&", path_converter, &path);
758 * // ... use values from path ...
759 * path_cleanup(&path);
760 *
761 * (Note that if PyArg_Parse fails you don't need to call
762 * path_cleanup(). However it is safe to do so.)
763 */
764typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100765 const char *function_name;
766 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700767 int nullable;
768 int allow_fd;
769 wchar_t *wide;
770 char *narrow;
771 int fd;
772 Py_ssize_t length;
773 PyObject *object;
774 PyObject *cleanup;
775} path_t;
776
Larry Hastings31826802013-10-19 00:09:25 -0700777#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \
778 {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL}
779
Larry Hastings9cf065c2012-06-22 16:30:09 -0700780static void
781path_cleanup(path_t *path) {
782 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200783 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700784 }
785}
786
787static int
788path_converter(PyObject *o, void *p) {
789 path_t *path = (path_t *)p;
790 PyObject *unicode, *bytes;
791 Py_ssize_t length;
792 char *narrow;
793
794#define FORMAT_EXCEPTION(exc, fmt) \
795 PyErr_Format(exc, "%s%s" fmt, \
796 path->function_name ? path->function_name : "", \
797 path->function_name ? ": " : "", \
798 path->argument_name ? path->argument_name : "path")
799
800 /* Py_CLEANUP_SUPPORTED support */
801 if (o == NULL) {
802 path_cleanup(path);
803 return 1;
804 }
805
806 /* ensure it's always safe to call path_cleanup() */
807 path->cleanup = NULL;
808
809 if (o == Py_None) {
810 if (!path->nullable) {
811 FORMAT_EXCEPTION(PyExc_TypeError,
812 "can't specify None for %s argument");
813 return 0;
814 }
815 path->wide = NULL;
816 path->narrow = NULL;
817 path->length = 0;
818 path->object = o;
819 path->fd = -1;
820 return 1;
821 }
822
823 unicode = PyUnicode_FromObject(o);
824 if (unicode) {
825#ifdef MS_WINDOWS
826 wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100827
828 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
829 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700830 Py_DECREF(unicode);
831 return 0;
832 }
Victor Stinner59799a82013-11-13 14:17:30 +0100833 if (length > 32767) {
834 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700835 Py_DECREF(unicode);
836 return 0;
837 }
838
839 path->wide = wide;
840 path->narrow = NULL;
841 path->length = length;
842 path->object = o;
843 path->fd = -1;
844 path->cleanup = unicode;
845 return Py_CLEANUP_SUPPORTED;
846#else
847 int converted = PyUnicode_FSConverter(unicode, &bytes);
848 Py_DECREF(unicode);
849 if (!converted)
850 bytes = NULL;
851#endif
852 }
853 else {
854 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200855 if (PyObject_CheckBuffer(o))
856 bytes = PyBytes_FromObject(o);
857 else
858 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700859 if (!bytes) {
860 PyErr_Clear();
861 if (path->allow_fd) {
862 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200863 int result = _fd_converter(o, &fd,
864 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700865 if (result) {
866 path->wide = NULL;
867 path->narrow = NULL;
868 path->length = 0;
869 path->object = o;
870 path->fd = fd;
871 return result;
872 }
873 }
874 }
875 }
876
877 if (!bytes) {
878 if (!PyErr_Occurred())
879 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
880 return 0;
881 }
882
883#ifdef MS_WINDOWS
884 if (win32_warn_bytes_api()) {
885 Py_DECREF(bytes);
886 return 0;
887 }
888#endif
889
890 length = PyBytes_GET_SIZE(bytes);
891#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100892 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700893 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
894 Py_DECREF(bytes);
895 return 0;
896 }
897#endif
898
899 narrow = PyBytes_AS_STRING(bytes);
900 if (length != strlen(narrow)) {
901 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
902 Py_DECREF(bytes);
903 return 0;
904 }
905
906 path->wide = NULL;
907 path->narrow = narrow;
908 path->length = length;
909 path->object = o;
910 path->fd = -1;
911 path->cleanup = bytes;
912 return Py_CLEANUP_SUPPORTED;
913}
914
915static void
916argument_unavailable_error(char *function_name, char *argument_name) {
917 PyErr_Format(PyExc_NotImplementedError,
918 "%s%s%s unavailable on this platform",
919 (function_name != NULL) ? function_name : "",
920 (function_name != NULL) ? ": ": "",
921 argument_name);
922}
923
924static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200925dir_fd_unavailable(PyObject *o, void *p)
926{
927 int dir_fd;
928 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700929 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200930 if (dir_fd != DEFAULT_DIR_FD) {
931 argument_unavailable_error(NULL, "dir_fd");
932 return 0;
933 }
934 *(int *)p = dir_fd;
935 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700936}
937
938static int
939fd_specified(char *function_name, int fd) {
940 if (fd == -1)
941 return 0;
942
943 argument_unavailable_error(function_name, "fd");
944 return 1;
945}
946
947static int
948follow_symlinks_specified(char *function_name, int follow_symlinks) {
949 if (follow_symlinks)
950 return 0;
951
952 argument_unavailable_error(function_name, "follow_symlinks");
953 return 1;
954}
955
956static int
957path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
958 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
959 PyErr_Format(PyExc_ValueError,
960 "%s: can't specify dir_fd without matching path",
961 function_name);
962 return 1;
963 }
964 return 0;
965}
966
967static int
968dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
969 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
970 PyErr_Format(PyExc_ValueError,
971 "%s: can't specify both dir_fd and fd",
972 function_name);
973 return 1;
974 }
975 return 0;
976}
977
978static int
979fd_and_follow_symlinks_invalid(char *function_name, int fd,
980 int follow_symlinks) {
981 if ((fd > 0) && (!follow_symlinks)) {
982 PyErr_Format(PyExc_ValueError,
983 "%s: cannot use fd and follow_symlinks together",
984 function_name);
985 return 1;
986 }
987 return 0;
988}
989
990static int
991dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
992 int follow_symlinks) {
993 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
994 PyErr_Format(PyExc_ValueError,
995 "%s: cannot use dir_fd and follow_symlinks together",
996 function_name);
997 return 1;
998 }
999 return 0;
1000}
1001
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001002/* A helper used by a number of POSIX-only functions */
1003#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +00001004static int
1005_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001006{
1007#if !defined(HAVE_LARGEFILE_SUPPORT)
1008 *((off_t*)addr) = PyLong_AsLong(arg);
1009#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +00001010 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001011#endif
1012 if (PyErr_Occurred())
1013 return 0;
1014 return 1;
1015}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001016#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001017
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001018#if defined _MSC_VER && _MSC_VER >= 1400
1019/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +02001020 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001021 * Normally, an invalid fd is likely to be a C program error and therefore
1022 * an assertion can be useful, but it does contradict the POSIX standard
1023 * which for write(2) states:
1024 * "Otherwise, -1 shall be returned and errno set to indicate the error."
1025 * "[EBADF] The fildes argument is not a valid file descriptor open for
1026 * writing."
1027 * Furthermore, python allows the user to enter any old integer
1028 * as a fd and should merely raise a python exception on error.
1029 * The Microsoft CRT doesn't provide an official way to check for the
1030 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +00001031 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001032 * internal structures involved.
1033 * The structures below must be updated for each version of visual studio
1034 * according to the file internal.h in the CRT source, until MS comes
1035 * up with a less hacky way to do this.
1036 * (all of this is to avoid globally modifying the CRT behaviour using
1037 * _set_invalid_parameter_handler() and _CrtSetReportMode())
1038 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001039/* The actual size of the structure is determined at runtime.
1040 * Only the first items must be present.
1041 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001042typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +00001043 intptr_t osfhnd;
1044 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001045} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001046
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001047extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001048#define IOINFO_L2E 5
1049#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
1050#define IOINFO_ARRAYS 64
1051#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
1052#define FOPEN 0x01
1053#define _NO_CONSOLE_FILENO (intptr_t)-2
1054
1055/* This function emulates what the windows CRT does to validate file handles */
1056int
1057_PyVerify_fd(int fd)
1058{
Victor Stinner8c62be82010-05-06 00:08:46 +00001059 const int i1 = fd >> IOINFO_L2E;
1060 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001061
Antoine Pitrou22e41552010-08-15 18:07:50 +00001062 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001063
Victor Stinner8c62be82010-05-06 00:08:46 +00001064 /* Determine the actual size of the ioinfo structure,
1065 * as used by the CRT loaded in memory
1066 */
1067 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
1068 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
1069 }
1070 if (sizeof_ioinfo == 0) {
1071 /* This should not happen... */
1072 goto fail;
1073 }
1074
1075 /* See that it isn't a special CLEAR fileno */
1076 if (fd != _NO_CONSOLE_FILENO) {
1077 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
1078 * we check pointer validity and other info
1079 */
1080 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
1081 /* finally, check that the file is open */
1082 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
1083 if (info->osfile & FOPEN) {
1084 return 1;
1085 }
1086 }
1087 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001088 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001089 errno = EBADF;
1090 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001091}
1092
1093/* the special case of checking dup2. The target fd must be in a sensible range */
1094static int
1095_PyVerify_fd_dup2(int fd1, int fd2)
1096{
Victor Stinner8c62be82010-05-06 00:08:46 +00001097 if (!_PyVerify_fd(fd1))
1098 return 0;
1099 if (fd2 == _NO_CONSOLE_FILENO)
1100 return 0;
1101 if ((unsigned)fd2 < _NHANDLE_)
1102 return 1;
1103 else
1104 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001105}
1106#else
1107/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1108#define _PyVerify_fd_dup2(A, B) (1)
1109#endif
1110
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001111#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001112/* The following structure was copied from
1113 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1114 include doesn't seem to be present in the Windows SDK (at least as included
1115 with Visual Studio Express). */
1116typedef struct _REPARSE_DATA_BUFFER {
1117 ULONG ReparseTag;
1118 USHORT ReparseDataLength;
1119 USHORT Reserved;
1120 union {
1121 struct {
1122 USHORT SubstituteNameOffset;
1123 USHORT SubstituteNameLength;
1124 USHORT PrintNameOffset;
1125 USHORT PrintNameLength;
1126 ULONG Flags;
1127 WCHAR PathBuffer[1];
1128 } SymbolicLinkReparseBuffer;
1129
1130 struct {
1131 USHORT SubstituteNameOffset;
1132 USHORT SubstituteNameLength;
1133 USHORT PrintNameOffset;
1134 USHORT PrintNameLength;
1135 WCHAR PathBuffer[1];
1136 } MountPointReparseBuffer;
1137
1138 struct {
1139 UCHAR DataBuffer[1];
1140 } GenericReparseBuffer;
1141 };
1142} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1143
1144#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1145 GenericReparseBuffer)
1146#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1147
1148static int
Brian Curtind25aef52011-06-13 15:16:04 -05001149win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001150{
1151 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1152 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1153 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001154
1155 if (0 == DeviceIoControl(
1156 reparse_point_handle,
1157 FSCTL_GET_REPARSE_POINT,
1158 NULL, 0, /* in buffer */
1159 target_buffer, sizeof(target_buffer),
1160 &n_bytes_returned,
1161 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001162 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001163
1164 if (reparse_tag)
1165 *reparse_tag = rdb->ReparseTag;
1166
Brian Curtind25aef52011-06-13 15:16:04 -05001167 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001168}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001169
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001170#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001171
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001172/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001173#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001174/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001175** environ directly, we must obtain it with _NSGetEnviron(). See also
1176** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001177*/
1178#include <crt_externs.h>
1179static char **environ;
1180#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001181extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001182#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001183
Barry Warsaw53699e91996-12-10 23:23:01 +00001184static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001185convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001186{
Victor Stinner8c62be82010-05-06 00:08:46 +00001187 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001188#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001189 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001190#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001191 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001192#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001193
Victor Stinner8c62be82010-05-06 00:08:46 +00001194 d = PyDict_New();
1195 if (d == NULL)
1196 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001197#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001198 if (environ == NULL)
1199 environ = *_NSGetEnviron();
1200#endif
1201#ifdef MS_WINDOWS
1202 /* _wenviron must be initialized in this way if the program is started
1203 through main() instead of wmain(). */
1204 _wgetenv(L"");
1205 if (_wenviron == NULL)
1206 return d;
1207 /* This part ignores errors */
1208 for (e = _wenviron; *e != NULL; e++) {
1209 PyObject *k;
1210 PyObject *v;
1211 wchar_t *p = wcschr(*e, L'=');
1212 if (p == NULL)
1213 continue;
1214 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1215 if (k == NULL) {
1216 PyErr_Clear();
1217 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001218 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001219 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1220 if (v == NULL) {
1221 PyErr_Clear();
1222 Py_DECREF(k);
1223 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001224 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001225 if (PyDict_GetItem(d, k) == NULL) {
1226 if (PyDict_SetItem(d, k, v) != 0)
1227 PyErr_Clear();
1228 }
1229 Py_DECREF(k);
1230 Py_DECREF(v);
1231 }
1232#else
1233 if (environ == NULL)
1234 return d;
1235 /* This part ignores errors */
1236 for (e = environ; *e != NULL; e++) {
1237 PyObject *k;
1238 PyObject *v;
1239 char *p = strchr(*e, '=');
1240 if (p == NULL)
1241 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001242 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001243 if (k == NULL) {
1244 PyErr_Clear();
1245 continue;
1246 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001247 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001248 if (v == NULL) {
1249 PyErr_Clear();
1250 Py_DECREF(k);
1251 continue;
1252 }
1253 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);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001259 }
1260#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001261 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001262}
1263
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001264/* Set a POSIX-specific error from errno, and return NULL */
1265
Barry Warsawd58d7641998-07-23 16:14:40 +00001266static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001267posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001268{
Victor Stinner8c62be82010-05-06 00:08:46 +00001269 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001270}
Mark Hammondef8b6542001-05-13 08:04:26 +00001271
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001272#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001273static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001274win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001275{
Victor Stinner8c62be82010-05-06 00:08:46 +00001276 /* XXX We should pass the function name along in the future.
1277 (winreg.c also wants to pass the function name.)
1278 This would however require an additional param to the
1279 Windows error object, which is non-trivial.
1280 */
1281 errno = GetLastError();
1282 if (filename)
1283 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1284 else
1285 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001286}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001287
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001288static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001289win32_error_object(char* function, PyObject* filename)
1290{
1291 /* XXX - see win32_error for comments on 'function' */
1292 errno = GetLastError();
1293 if (filename)
1294 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001295 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001296 errno,
1297 filename);
1298 else
1299 return PyErr_SetFromWindowsErr(errno);
1300}
1301
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001302#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303
Larry Hastings9cf065c2012-06-22 16:30:09 -07001304static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001305path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001306{
1307#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001308 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1309 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001310#else
Victor Stinner292c8352012-10-30 02:17:38 +01001311 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001312#endif
1313}
1314
Larry Hastings31826802013-10-19 00:09:25 -07001315
Larry Hastingsb0827312014-02-09 22:05:19 -08001316static PyObject *
1317path_error2(path_t *path, path_t *path2)
1318{
1319#ifdef MS_WINDOWS
1320 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1321 0, path->object, path2->object);
1322#else
1323 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1324 path->object, path2->object);
1325#endif
1326}
1327
1328
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001329/* POSIX generic methods */
1330
Barry Warsaw53699e91996-12-10 23:23:01 +00001331static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001332posix_fildes(PyObject *fdobj, int (*func)(int))
1333{
Victor Stinner8c62be82010-05-06 00:08:46 +00001334 int fd;
1335 int res;
1336 fd = PyObject_AsFileDescriptor(fdobj);
1337 if (fd < 0)
1338 return NULL;
1339 if (!_PyVerify_fd(fd))
1340 return posix_error();
1341 Py_BEGIN_ALLOW_THREADS
1342 res = (*func)(fd);
1343 Py_END_ALLOW_THREADS
1344 if (res < 0)
1345 return posix_error();
1346 Py_INCREF(Py_None);
1347 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001348}
Guido van Rossum21142a01999-01-08 21:05:37 +00001349
1350static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001351posix_1str(const char *func_name, PyObject *args, char *format,
1352 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001353{
Victor Stinner292c8352012-10-30 02:17:38 +01001354 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001355 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001356 memset(&path, 0, sizeof(path));
1357 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001358 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001359 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001360 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001361 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001362 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001364 if (res < 0) {
1365 path_error(&path);
1366 path_cleanup(&path);
1367 return NULL;
1368 }
1369 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001370 Py_INCREF(Py_None);
1371 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001372}
1373
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001374
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001375#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001376/* This is a reimplementation of the C library's chdir function,
1377 but one that produces Win32 errors instead of DOS error codes.
1378 chdir is essentially a wrapper around SetCurrentDirectory; however,
1379 it also needs to set "magic" environment variables indicating
1380 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001381static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001382win32_chdir(LPCSTR path)
1383{
Victor Stinner75875072013-11-24 19:23:25 +01001384 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001385 int result;
1386 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001387
Victor Stinner8c62be82010-05-06 00:08:46 +00001388 if(!SetCurrentDirectoryA(path))
1389 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001390 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001391 if (!result)
1392 return FALSE;
1393 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001394 than MAX_PATH-1 (not including the final null character). */
1395 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001396 if (strncmp(new_path, "\\\\", 2) == 0 ||
1397 strncmp(new_path, "//", 2) == 0)
1398 /* UNC path, nothing to do. */
1399 return TRUE;
1400 env[1] = new_path[0];
1401 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001402}
1403
1404/* The Unicode version differs from the ANSI version
1405 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001406static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001407win32_wchdir(LPCWSTR path)
1408{
Victor Stinner75875072013-11-24 19:23:25 +01001409 wchar_t _new_path[MAX_PATH], *new_path = _new_path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001410 int result;
1411 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001412
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 if(!SetCurrentDirectoryW(path))
1414 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001415 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001416 if (!result)
1417 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001418 if (result > Py_ARRAY_LENGTH(new_path)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001419 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 if (!new_path) {
1421 SetLastError(ERROR_OUTOFMEMORY);
1422 return FALSE;
1423 }
1424 result = GetCurrentDirectoryW(result, new_path);
1425 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001426 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001427 return FALSE;
1428 }
1429 }
1430 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1431 wcsncmp(new_path, L"//", 2) == 0)
1432 /* UNC path, nothing to do. */
1433 return TRUE;
1434 env[1] = new_path[0];
1435 result = SetEnvironmentVariableW(env, new_path);
1436 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001437 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001438 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001439}
1440#endif
1441
Martin v. Löwis14694662006-02-03 12:54:16 +00001442#ifdef MS_WINDOWS
1443/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1444 - time stamps are restricted to second resolution
1445 - file modification times suffer from forth-and-back conversions between
1446 UTC and local time
1447 Therefore, we implement our own stat, based on the Win32 API directly.
1448*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001449#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001450
1451struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001452 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001453 __int64 st_ino;
1454 unsigned short st_mode;
1455 int st_nlink;
1456 int st_uid;
1457 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001458 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001459 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001460 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001461 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001462 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001463 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001464 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001465 int st_ctime_nsec;
1466};
1467
1468static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1469
1470static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001471FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001472{
Victor Stinner8c62be82010-05-06 00:08:46 +00001473 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1474 /* Cannot simply cast and dereference in_ptr,
1475 since it might not be aligned properly */
1476 __int64 in;
1477 memcpy(&in, in_ptr, sizeof(in));
1478 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001479 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001480}
1481
Thomas Wouters477c8d52006-05-27 19:21:47 +00001482static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001483time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001484{
Victor Stinner8c62be82010-05-06 00:08:46 +00001485 /* XXX endianness */
1486 __int64 out;
1487 out = time_in + secs_between_epochs;
1488 out = out * 10000000 + nsec_in / 100;
1489 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001490}
1491
Martin v. Löwis14694662006-02-03 12:54:16 +00001492/* Below, we *know* that ugo+r is 0444 */
1493#if _S_IREAD != 0400
1494#error Unsupported C library
1495#endif
1496static int
1497attributes_to_mode(DWORD attr)
1498{
Victor Stinner8c62be82010-05-06 00:08:46 +00001499 int m = 0;
1500 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1501 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1502 else
1503 m |= _S_IFREG;
1504 if (attr & FILE_ATTRIBUTE_READONLY)
1505 m |= 0444;
1506 else
1507 m |= 0666;
1508 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001509}
1510
1511static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001512attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001513{
Victor Stinner8c62be82010-05-06 00:08:46 +00001514 memset(result, 0, sizeof(*result));
1515 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1516 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001517 result->st_dev = info->dwVolumeSerialNumber;
1518 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001519 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1520 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1521 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001522 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001523 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001524 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1525 /* first clear the S_IFMT bits */
Christian Heimes99d61352013-06-23 23:56:05 +02001526 result->st_mode ^= (result->st_mode & S_IFMT);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001527 /* now set the bits that make this a symlink */
Christian Heimes99d61352013-06-23 23:56:05 +02001528 result->st_mode |= S_IFLNK;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001529 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001530
Victor Stinner8c62be82010-05-06 00:08:46 +00001531 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001532}
1533
Guido van Rossumd8faa362007-04-27 19:54:29 +00001534static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001535attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001536{
Victor Stinner8c62be82010-05-06 00:08:46 +00001537 HANDLE hFindFile;
1538 WIN32_FIND_DATAA FileData;
1539 hFindFile = FindFirstFileA(pszFile, &FileData);
1540 if (hFindFile == INVALID_HANDLE_VALUE)
1541 return FALSE;
1542 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001543 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001544 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001545 info->dwFileAttributes = FileData.dwFileAttributes;
1546 info->ftCreationTime = FileData.ftCreationTime;
1547 info->ftLastAccessTime = FileData.ftLastAccessTime;
1548 info->ftLastWriteTime = FileData.ftLastWriteTime;
1549 info->nFileSizeHigh = FileData.nFileSizeHigh;
1550 info->nFileSizeLow = FileData.nFileSizeLow;
1551/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001552 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1553 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001554 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001555}
1556
1557static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001558attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001559{
Victor Stinner8c62be82010-05-06 00:08:46 +00001560 HANDLE hFindFile;
1561 WIN32_FIND_DATAW FileData;
1562 hFindFile = FindFirstFileW(pszFile, &FileData);
1563 if (hFindFile == INVALID_HANDLE_VALUE)
1564 return FALSE;
1565 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001566 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001567 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001568 info->dwFileAttributes = FileData.dwFileAttributes;
1569 info->ftCreationTime = FileData.ftCreationTime;
1570 info->ftLastAccessTime = FileData.ftLastAccessTime;
1571 info->ftLastWriteTime = FileData.ftLastWriteTime;
1572 info->nFileSizeHigh = FileData.nFileSizeHigh;
1573 info->nFileSizeLow = FileData.nFileSizeLow;
1574/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001575 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1576 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001577 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001578}
1579
Brian Curtind25aef52011-06-13 15:16:04 -05001580/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001581static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001582static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1583 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001584static int
Brian Curtind25aef52011-06-13 15:16:04 -05001585check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001586{
Brian Curtind25aef52011-06-13 15:16:04 -05001587 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001588 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1589 DWORD);
1590
Brian Curtind25aef52011-06-13 15:16:04 -05001591 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001592 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001593 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001594 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001595 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1596 "GetFinalPathNameByHandleA");
1597 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1598 "GetFinalPathNameByHandleW");
1599 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1600 Py_GetFinalPathNameByHandleW;
1601 }
1602 return has_GetFinalPathNameByHandle;
1603}
1604
1605static BOOL
1606get_target_path(HANDLE hdl, wchar_t **target_path)
1607{
1608 int buf_size, result_length;
1609 wchar_t *buf;
1610
1611 /* We have a good handle to the target, use it to determine
1612 the target path name (then we'll call lstat on it). */
1613 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1614 VOLUME_NAME_DOS);
1615 if(!buf_size)
1616 return FALSE;
1617
Victor Stinnerb6404912013-07-07 16:21:41 +02001618 buf = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001619 if (!buf) {
1620 SetLastError(ERROR_OUTOFMEMORY);
1621 return FALSE;
1622 }
1623
Brian Curtind25aef52011-06-13 15:16:04 -05001624 result_length = Py_GetFinalPathNameByHandleW(hdl,
1625 buf, buf_size, VOLUME_NAME_DOS);
1626
1627 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001628 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001629 return FALSE;
1630 }
1631
1632 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001633 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001634 return FALSE;
1635 }
1636
1637 buf[result_length] = 0;
1638
1639 *target_path = buf;
1640 return TRUE;
1641}
1642
1643static int
1644win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1645 BOOL traverse);
1646static int
1647win32_xstat_impl(const char *path, struct win32_stat *result,
1648 BOOL traverse)
1649{
Victor Stinner26de69d2011-06-17 15:15:38 +02001650 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001651 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001652 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001653 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001654 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001655 const char *dot;
1656
Brian Curtind25aef52011-06-13 15:16:04 -05001657 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001658 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1659 traverse reparse point. */
1660 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001661 }
1662
Brian Curtinf5e76d02010-11-24 13:14:05 +00001663 hFile = CreateFileA(
1664 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001665 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001666 0, /* share mode */
1667 NULL, /* security attributes */
1668 OPEN_EXISTING,
1669 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001670 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1671 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001672 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001673 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1674 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001675 NULL);
1676
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001677 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001678 /* Either the target doesn't exist, or we don't have access to
1679 get a handle to it. If the former, we need to return an error.
1680 If the latter, we can use attributes_from_dir. */
1681 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001682 return -1;
1683 /* Could not get attributes on open file. Fall back to
1684 reading the directory. */
1685 if (!attributes_from_dir(path, &info, &reparse_tag))
1686 /* Very strange. This should not fail now */
1687 return -1;
1688 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1689 if (traverse) {
1690 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001691 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001692 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001693 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001694 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001695 } else {
1696 if (!GetFileInformationByHandle(hFile, &info)) {
1697 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001698 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001699 }
1700 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001701 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1702 return -1;
1703
1704 /* Close the outer open file handle now that we're about to
1705 reopen it with different flags. */
1706 if (!CloseHandle(hFile))
1707 return -1;
1708
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001710 /* In order to call GetFinalPathNameByHandle we need to open
1711 the file without the reparse handling flag set. */
1712 hFile2 = CreateFileA(
1713 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1714 NULL, OPEN_EXISTING,
1715 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1716 NULL);
1717 if (hFile2 == INVALID_HANDLE_VALUE)
1718 return -1;
1719
1720 if (!get_target_path(hFile2, &target_path))
1721 return -1;
1722
1723 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001724 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001725 return code;
1726 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001727 } else
1728 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001729 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001730 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001731
1732 /* Set S_IEXEC if it is an .exe, .bat, ... */
1733 dot = strrchr(path, '.');
1734 if (dot) {
1735 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1736 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1737 result->st_mode |= 0111;
1738 }
1739 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001740}
1741
1742static int
Brian Curtind25aef52011-06-13 15:16:04 -05001743win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1744 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001745{
1746 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001747 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001748 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001749 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001750 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001751 const wchar_t *dot;
1752
Brian Curtind25aef52011-06-13 15:16:04 -05001753 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001754 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1755 traverse reparse point. */
1756 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001757 }
1758
Brian Curtinf5e76d02010-11-24 13:14:05 +00001759 hFile = CreateFileW(
1760 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001761 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001762 0, /* share mode */
1763 NULL, /* security attributes */
1764 OPEN_EXISTING,
1765 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001766 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1767 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001768 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001769 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001770 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001771 NULL);
1772
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001773 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001774 /* Either the target doesn't exist, or we don't have access to
1775 get a handle to it. If the former, we need to return an error.
1776 If the latter, we can use attributes_from_dir. */
1777 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001778 return -1;
1779 /* Could not get attributes on open file. Fall back to
1780 reading the directory. */
1781 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1782 /* Very strange. This should not fail now */
1783 return -1;
1784 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1785 if (traverse) {
1786 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001787 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001788 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001789 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001790 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001791 } else {
1792 if (!GetFileInformationByHandle(hFile, &info)) {
1793 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001794 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001795 }
1796 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001797 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1798 return -1;
1799
1800 /* Close the outer open file handle now that we're about to
1801 reopen it with different flags. */
1802 if (!CloseHandle(hFile))
1803 return -1;
1804
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001805 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001806 /* In order to call GetFinalPathNameByHandle we need to open
1807 the file without the reparse handling flag set. */
1808 hFile2 = CreateFileW(
1809 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1810 NULL, OPEN_EXISTING,
1811 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1812 NULL);
1813 if (hFile2 == INVALID_HANDLE_VALUE)
1814 return -1;
1815
1816 if (!get_target_path(hFile2, &target_path))
1817 return -1;
1818
1819 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001820 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001821 return code;
1822 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001823 } else
1824 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001825 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001826 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001827
1828 /* Set S_IEXEC if it is an .exe, .bat, ... */
1829 dot = wcsrchr(path, '.');
1830 if (dot) {
1831 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1832 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1833 result->st_mode |= 0111;
1834 }
1835 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001836}
1837
1838static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001839win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001840{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001841 /* Protocol violation: we explicitly clear errno, instead of
1842 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001843 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001844 errno = 0;
1845 return code;
1846}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001847
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001848static int
1849win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1850{
1851 /* Protocol violation: we explicitly clear errno, instead of
1852 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001853 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001854 errno = 0;
1855 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001856}
Brian Curtind25aef52011-06-13 15:16:04 -05001857/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001858
1859 In Posix, stat automatically traverses symlinks and returns the stat
1860 structure for the target. In Windows, the equivalent GetFileAttributes by
1861 default does not traverse symlinks and instead returns attributes for
1862 the symlink.
1863
1864 Therefore, win32_lstat will get the attributes traditionally, and
1865 win32_stat will first explicitly resolve the symlink target and then will
1866 call win32_lstat on that result.
1867
Ezio Melotti4969f702011-03-15 05:59:46 +02001868 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001869
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001870static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001871win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001872{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001873 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001874}
1875
Victor Stinner8c62be82010-05-06 00:08:46 +00001876static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001877win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001878{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001879 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001880}
1881
1882static int
1883win32_stat(const char* path, struct win32_stat *result)
1884{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001885 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001886}
1887
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001888static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001889win32_stat_w(const wchar_t* path, struct win32_stat *result)
1890{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001891 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001892}
1893
1894static int
1895win32_fstat(int file_number, struct win32_stat *result)
1896{
Victor Stinner8c62be82010-05-06 00:08:46 +00001897 BY_HANDLE_FILE_INFORMATION info;
1898 HANDLE h;
1899 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001900
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001901 if (!_PyVerify_fd(file_number))
1902 h = INVALID_HANDLE_VALUE;
1903 else
1904 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001905
Victor Stinner8c62be82010-05-06 00:08:46 +00001906 /* Protocol violation: we explicitly clear errno, instead of
1907 setting it to a POSIX error. Callers should use GetLastError. */
1908 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001909
Victor Stinner8c62be82010-05-06 00:08:46 +00001910 if (h == INVALID_HANDLE_VALUE) {
1911 /* This is really a C library error (invalid file handle).
1912 We set the Win32 error to the closes one matching. */
1913 SetLastError(ERROR_INVALID_HANDLE);
1914 return -1;
1915 }
1916 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001917
Victor Stinner8c62be82010-05-06 00:08:46 +00001918 type = GetFileType(h);
1919 if (type == FILE_TYPE_UNKNOWN) {
1920 DWORD error = GetLastError();
1921 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001922 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001923 }
1924 /* else: valid but unknown file */
1925 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001926
Victor Stinner8c62be82010-05-06 00:08:46 +00001927 if (type != FILE_TYPE_DISK) {
1928 if (type == FILE_TYPE_CHAR)
1929 result->st_mode = _S_IFCHR;
1930 else if (type == FILE_TYPE_PIPE)
1931 result->st_mode = _S_IFIFO;
1932 return 0;
1933 }
1934
1935 if (!GetFileInformationByHandle(h, &info)) {
1936 return -1;
1937 }
1938
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001939 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001940 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001941 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1942 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001943}
1944
1945#endif /* MS_WINDOWS */
1946
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001947PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001948"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001949This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001950 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001951or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1952\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001953Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1954or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001955\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001956See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001957
1958static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001959 {"st_mode", "protection bits"},
1960 {"st_ino", "inode"},
1961 {"st_dev", "device"},
1962 {"st_nlink", "number of hard links"},
1963 {"st_uid", "user ID of owner"},
1964 {"st_gid", "group ID of owner"},
1965 {"st_size", "total size, in bytes"},
1966 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1967 {NULL, "integer time of last access"},
1968 {NULL, "integer time of last modification"},
1969 {NULL, "integer time of last change"},
1970 {"st_atime", "time of last access"},
1971 {"st_mtime", "time of last modification"},
1972 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001973 {"st_atime_ns", "time of last access in nanoseconds"},
1974 {"st_mtime_ns", "time of last modification in nanoseconds"},
1975 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001976#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001978#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001979#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001980 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001981#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001982#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001983 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001984#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001985#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001986 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001987#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001988#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001989 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001990#endif
1991#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001992 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001993#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001994 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001995};
1996
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001997#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001998#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001999#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002000#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002001#endif
2002
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002003#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002004#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2005#else
2006#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2007#endif
2008
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002009#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002010#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2011#else
2012#define ST_RDEV_IDX ST_BLOCKS_IDX
2013#endif
2014
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002015#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2016#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2017#else
2018#define ST_FLAGS_IDX ST_RDEV_IDX
2019#endif
2020
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002021#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002022#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002023#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002024#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002025#endif
2026
2027#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2028#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2029#else
2030#define ST_BIRTHTIME_IDX ST_GEN_IDX
2031#endif
2032
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002033static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 "stat_result", /* name */
2035 stat_result__doc__, /* doc */
2036 stat_result_fields,
2037 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002038};
2039
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002040PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002041"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2042This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002043 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002044or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002045\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002046See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002047
2048static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002049 {"f_bsize", },
2050 {"f_frsize", },
2051 {"f_blocks", },
2052 {"f_bfree", },
2053 {"f_bavail", },
2054 {"f_files", },
2055 {"f_ffree", },
2056 {"f_favail", },
2057 {"f_flag", },
2058 {"f_namemax",},
2059 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002060};
2061
2062static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002063 "statvfs_result", /* name */
2064 statvfs_result__doc__, /* doc */
2065 statvfs_result_fields,
2066 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002067};
2068
Ross Lagerwall7807c352011-03-17 20:20:30 +02002069#if defined(HAVE_WAITID) && !defined(__APPLE__)
2070PyDoc_STRVAR(waitid_result__doc__,
2071"waitid_result: Result from waitid.\n\n\
2072This object may be accessed either as a tuple of\n\
2073 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2074or via the attributes si_pid, si_uid, and so on.\n\
2075\n\
2076See os.waitid for more information.");
2077
2078static PyStructSequence_Field waitid_result_fields[] = {
2079 {"si_pid", },
2080 {"si_uid", },
2081 {"si_signo", },
2082 {"si_status", },
2083 {"si_code", },
2084 {0}
2085};
2086
2087static PyStructSequence_Desc waitid_result_desc = {
2088 "waitid_result", /* name */
2089 waitid_result__doc__, /* doc */
2090 waitid_result_fields,
2091 5
2092};
2093static PyTypeObject WaitidResultType;
2094#endif
2095
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002096static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002097static PyTypeObject StatResultType;
2098static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002099#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002100static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002101#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002102static newfunc structseq_new;
2103
2104static PyObject *
2105statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2106{
Victor Stinner8c62be82010-05-06 00:08:46 +00002107 PyStructSequence *result;
2108 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002109
Victor Stinner8c62be82010-05-06 00:08:46 +00002110 result = (PyStructSequence*)structseq_new(type, args, kwds);
2111 if (!result)
2112 return NULL;
2113 /* If we have been initialized from a tuple,
2114 st_?time might be set to None. Initialize it
2115 from the int slots. */
2116 for (i = 7; i <= 9; i++) {
2117 if (result->ob_item[i+3] == Py_None) {
2118 Py_DECREF(Py_None);
2119 Py_INCREF(result->ob_item[i]);
2120 result->ob_item[i+3] = result->ob_item[i];
2121 }
2122 }
2123 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002124}
2125
2126
2127
2128/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002129static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002130
2131PyDoc_STRVAR(stat_float_times__doc__,
2132"stat_float_times([newval]) -> oldval\n\n\
2133Determine whether os.[lf]stat represents time stamps as float objects.\n\
2134If newval is True, future calls to stat() return floats, if it is False,\n\
2135future calls return ints. \n\
2136If newval is omitted, return the current setting.\n");
2137
2138static PyObject*
2139stat_float_times(PyObject* self, PyObject *args)
2140{
Victor Stinner8c62be82010-05-06 00:08:46 +00002141 int newval = -1;
2142 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2143 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002144 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2145 "stat_float_times() is deprecated",
2146 1))
2147 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002148 if (newval == -1)
2149 /* Return old value */
2150 return PyBool_FromLong(_stat_float_times);
2151 _stat_float_times = newval;
2152 Py_INCREF(Py_None);
2153 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002154}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002155
Larry Hastings6fe20b32012-04-19 15:07:49 -07002156static PyObject *billion = NULL;
2157
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002158static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002159fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002160{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002161 PyObject *s = _PyLong_FromTime_t(sec);
2162 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2163 PyObject *s_in_ns = NULL;
2164 PyObject *ns_total = NULL;
2165 PyObject *float_s = NULL;
2166
2167 if (!(s && ns_fractional))
2168 goto exit;
2169
2170 s_in_ns = PyNumber_Multiply(s, billion);
2171 if (!s_in_ns)
2172 goto exit;
2173
2174 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2175 if (!ns_total)
2176 goto exit;
2177
Victor Stinner4195b5c2012-02-08 23:03:19 +01002178 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002179 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2180 if (!float_s)
2181 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002182 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002183 else {
2184 float_s = s;
2185 Py_INCREF(float_s);
2186 }
2187
2188 PyStructSequence_SET_ITEM(v, index, s);
2189 PyStructSequence_SET_ITEM(v, index+3, float_s);
2190 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2191 s = NULL;
2192 float_s = NULL;
2193 ns_total = NULL;
2194exit:
2195 Py_XDECREF(s);
2196 Py_XDECREF(ns_fractional);
2197 Py_XDECREF(s_in_ns);
2198 Py_XDECREF(ns_total);
2199 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002200}
2201
Tim Peters5aa91602002-01-30 05:46:57 +00002202/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002203 (used by posix_stat() and posix_fstat()) */
2204static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002205_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002206{
Victor Stinner8c62be82010-05-06 00:08:46 +00002207 unsigned long ansec, mnsec, cnsec;
2208 PyObject *v = PyStructSequence_New(&StatResultType);
2209 if (v == NULL)
2210 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002211
Victor Stinner8c62be82010-05-06 00:08:46 +00002212 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002213#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002214 PyStructSequence_SET_ITEM(v, 1,
2215 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002216#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002217 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002218#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002219#ifdef MS_WINDOWS
2220 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
2221#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00002222 PyStructSequence_SET_ITEM(v, 2,
2223 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002224#else
Brian Curtin9cc43212013-01-01 12:31:06 -06002225 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002226#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002227 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002228#if defined(MS_WINDOWS)
2229 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2230 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2231#else
2232 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2233 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2234#endif
Fred Drake699f3522000-06-29 21:12:41 +00002235#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002236 PyStructSequence_SET_ITEM(v, 6,
2237 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002238#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002239 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002240#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002241
Martin v. Löwis14694662006-02-03 12:54:16 +00002242#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002243 ansec = st->st_atim.tv_nsec;
2244 mnsec = st->st_mtim.tv_nsec;
2245 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002246#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002247 ansec = st->st_atimespec.tv_nsec;
2248 mnsec = st->st_mtimespec.tv_nsec;
2249 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002250#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002251 ansec = st->st_atime_nsec;
2252 mnsec = st->st_mtime_nsec;
2253 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002254#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002255 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002256#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002257 fill_time(v, 7, st->st_atime, ansec);
2258 fill_time(v, 8, st->st_mtime, mnsec);
2259 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002260
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002261#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002262 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2263 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002264#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002265#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002266 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2267 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002268#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002269#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002270 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2271 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002272#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002273#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002274 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2275 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002276#endif
2277#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002278 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002279 PyObject *val;
2280 unsigned long bsec,bnsec;
2281 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002282#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002283 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002284#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002285 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002286#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002287 if (_stat_float_times) {
2288 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2289 } else {
2290 val = PyLong_FromLong((long)bsec);
2291 }
2292 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2293 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002294 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002295#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002296#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002297 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2298 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002299#endif
Fred Drake699f3522000-06-29 21:12:41 +00002300
Victor Stinner8c62be82010-05-06 00:08:46 +00002301 if (PyErr_Occurred()) {
2302 Py_DECREF(v);
2303 return NULL;
2304 }
Fred Drake699f3522000-06-29 21:12:41 +00002305
Victor Stinner8c62be82010-05-06 00:08:46 +00002306 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002307}
2308
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002309/* POSIX methods */
2310
Guido van Rossum94f6f721999-01-06 18:42:14 +00002311
2312static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002313posix_do_stat(char *function_name, path_t *path,
2314 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002315{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002316 STRUCT_STAT st;
2317 int result;
2318
2319#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2320 if (follow_symlinks_specified(function_name, follow_symlinks))
2321 return NULL;
2322#endif
2323
2324 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2325 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2326 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2327 return NULL;
2328
2329 Py_BEGIN_ALLOW_THREADS
2330 if (path->fd != -1)
2331 result = FSTAT(path->fd, &st);
2332 else
2333#ifdef MS_WINDOWS
2334 if (path->wide) {
2335 if (follow_symlinks)
2336 result = win32_stat_w(path->wide, &st);
2337 else
2338 result = win32_lstat_w(path->wide, &st);
2339 }
2340 else
2341#endif
2342#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2343 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2344 result = LSTAT(path->narrow, &st);
2345 else
2346#endif
2347#ifdef HAVE_FSTATAT
2348 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2349 result = fstatat(dir_fd, path->narrow, &st,
2350 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2351 else
2352#endif
2353 result = STAT(path->narrow, &st);
2354 Py_END_ALLOW_THREADS
2355
Victor Stinner292c8352012-10-30 02:17:38 +01002356 if (result != 0) {
2357 return path_error(path);
2358 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002359
2360 return _pystat_fromstructstat(&st);
2361}
2362
Larry Hastings31826802013-10-19 00:09:25 -07002363#ifdef HAVE_FSTATAT
2364 #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter
2365#else
2366 #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable
2367#endif
2368
2369
Larry Hastings61272b72014-01-07 12:41:53 -08002370/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002371
2372class path_t_converter(CConverter):
2373
2374 type = "path_t"
2375 impl_by_reference = True
2376 parse_by_reference = True
2377
2378 converter = 'path_converter'
2379
2380 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002381 # right now path_t doesn't support default values.
2382 # to support a default value, you'll need to override initialize().
Larry Hastings7726ac92014-01-31 22:03:12 -08002383 if self.default is not unspecified:
2384 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002385
Larry Hastings7726ac92014-01-31 22:03:12 -08002386 if self.c_default is not None:
2387 fail("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002388
2389 self.nullable = nullable
2390 self.allow_fd = allow_fd
2391
Larry Hastings7726ac92014-01-31 22:03:12 -08002392 def pre_render(self):
2393 def strify(value):
2394 return str(int(bool(value)))
2395
2396 # add self.py_name here when merging with posixmodule conversion
Larry Hastings31826802013-10-19 00:09:25 -07002397 self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format(
2398 self.function.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002399 strify(self.nullable),
2400 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002401 )
2402
2403 def cleanup(self):
2404 return "path_cleanup(&" + self.name + ");\n"
2405
2406
2407class dir_fd_converter(CConverter):
2408 type = 'int'
2409 converter = 'OS_STAT_DIR_FD_CONVERTER'
2410
2411 def converter_init(self):
2412 if self.default in (unspecified, None):
2413 self.c_default = 'DEFAULT_DIR_FD'
2414
2415
Larry Hastings61272b72014-01-07 12:41:53 -08002416[python start generated code]*/
Larry Hastings7726ac92014-01-31 22:03:12 -08002417/*[python end generated code: output=da39a3ee5e6b4b0d input=5c9f456f53244fc3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002418
Larry Hastings61272b72014-01-07 12:41:53 -08002419/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002420
Larry Hastings2a727912014-01-16 11:32:01 -08002421os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002422
2423 path : path_t(allow_fd=True)
2424 Path to be examined; can be string, bytes, or open-file-descriptor int.
2425
2426 *
2427
2428 dir_fd : dir_fd = None
2429 If not None, it should be a file descriptor open to a directory,
2430 and path should be a relative string; path will then be relative to
2431 that directory.
2432
2433 follow_symlinks: bool = True
2434 If False, and the last element of the path is a symbolic link,
2435 stat will examine the symbolic link itself instead of the file
2436 the link points to.
2437
2438Perform a stat system call on the given path.
2439
2440dir_fd and follow_symlinks may not be implemented
2441 on your platform. If they are unavailable, using them will raise a
2442 NotImplementedError.
2443
2444It's an error to use dir_fd or follow_symlinks when specifying path as
2445 an open file descriptor.
2446
Larry Hastings61272b72014-01-07 12:41:53 -08002447[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002448
2449PyDoc_STRVAR(os_stat__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002450"stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n"
2451"--\n"
2452"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002453"Perform a stat system call on the given path.\n"
2454"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002455" path\n"
2456" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
2457" dir_fd\n"
2458" If not None, it should be a file descriptor open to a directory,\n"
2459" and path should be a relative string; path will then be relative to\n"
2460" that directory.\n"
2461" follow_symlinks\n"
2462" If False, and the last element of the path is a symbolic link,\n"
2463" stat will examine the symbolic link itself instead of the file\n"
2464" the link points to.\n"
2465"\n"
2466"dir_fd and follow_symlinks may not be implemented\n"
2467" on your platform. If they are unavailable, using them will raise a\n"
2468" NotImplementedError.\n"
2469"\n"
2470"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n"
2471" an open file descriptor.");
2472
2473#define OS_STAT_METHODDEF \
2474 {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002475
2476static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002477os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002478
2479static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002480os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002481{
Larry Hastings31826802013-10-19 00:09:25 -07002482 PyObject *return_value = NULL;
2483 static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2484 path_t path = PATH_T_INITIALIZE("stat", 0, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002485 int dir_fd = DEFAULT_DIR_FD;
2486 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002487
Larry Hastings31826802013-10-19 00:09:25 -07002488 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2489 "O&|$O&p:stat", _keywords,
2490 path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
2491 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002492 return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002493
2494exit:
2495 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002496 path_cleanup(&path);
Larry Hastings31826802013-10-19 00:09:25 -07002497
Larry Hastings9cf065c2012-06-22 16:30:09 -07002498 return return_value;
2499}
2500
Larry Hastings31826802013-10-19 00:09:25 -07002501static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002502os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002503/*[clinic end generated code: output=f1dcaa5e24db9882 input=5ae155bd475fd20a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002504{
2505 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2506}
2507
Larry Hastings9cf065c2012-06-22 16:30:09 -07002508PyDoc_STRVAR(posix_lstat__doc__,
2509"lstat(path, *, dir_fd=None) -> stat result\n\n\
2510Like stat(), but do not follow symbolic links.\n\
2511Equivalent to stat(path, follow_symlinks=False).");
2512
2513static PyObject *
2514posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2515{
2516 static char *keywords[] = {"path", "dir_fd", NULL};
2517 path_t path;
2518 int dir_fd = DEFAULT_DIR_FD;
2519 int follow_symlinks = 0;
2520 PyObject *return_value;
2521
2522 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002523 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002524 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2525 path_converter, &path,
2526#ifdef HAVE_FSTATAT
2527 dir_fd_converter, &dir_fd
2528#else
2529 dir_fd_unavailable, &dir_fd
2530#endif
2531 ))
2532 return NULL;
Larry Hastings31826802013-10-19 00:09:25 -07002533 return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002534 path_cleanup(&path);
2535 return return_value;
2536}
2537
Larry Hastings31826802013-10-19 00:09:25 -07002538
2539#ifdef HAVE_FACCESSAT
2540 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter
2541#else
2542 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable
2543#endif
Larry Hastings61272b72014-01-07 12:41:53 -08002544/*[clinic input]
Larry Hastings2a727912014-01-16 11:32:01 -08002545os.access
Larry Hastings31826802013-10-19 00:09:25 -07002546
2547 path: path_t(allow_fd=True)
2548 Path to be tested; can be string, bytes, or open-file-descriptor int.
2549
2550 mode: int
2551 Operating-system mode bitfield. Can be F_OK to test existence,
2552 or the inclusive-OR of R_OK, W_OK, and X_OK.
2553
2554 *
2555
2556 dir_fd : dir_fd = None
2557 If not None, it should be a file descriptor open to a directory,
2558 and path should be relative; path will then be relative to that
2559 directory.
2560
2561 effective_ids: bool = False
2562 If True, access will use the effective uid/gid instead of
2563 the real uid/gid.
2564
2565 follow_symlinks: bool = True
2566 If False, and the last element of the path is a symbolic link,
2567 access will examine the symbolic link itself instead of the file
2568 the link points to.
2569
2570Use the real uid/gid to test for access to a path.
2571
2572{parameters}
2573dir_fd, effective_ids, and follow_symlinks may not be implemented
2574 on your platform. If they are unavailable, using them will raise a
2575 NotImplementedError.
2576
2577Note that most operations will use the effective uid/gid, therefore this
2578 routine can be used in a suid/sgid environment to test if the invoking user
2579 has the specified access to the path.
2580
Larry Hastings61272b72014-01-07 12:41:53 -08002581[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002582
2583PyDoc_STRVAR(os_access__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002584"access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n"
2585" follow_symlinks=True)\n"
2586"--\n"
2587"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002588"Use the real uid/gid to test for access to a path.\n"
2589"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002590" path\n"
2591" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
2592" mode\n"
2593" Operating-system mode bitfield. Can be F_OK to test existence,\n"
2594" or the inclusive-OR of R_OK, W_OK, and X_OK.\n"
2595" dir_fd\n"
2596" If not None, it should be a file descriptor open to a directory,\n"
2597" and path should be relative; path will then be relative to that\n"
2598" directory.\n"
2599" effective_ids\n"
2600" If True, access will use the effective uid/gid instead of\n"
2601" the real uid/gid.\n"
2602" follow_symlinks\n"
2603" If False, and the last element of the path is a symbolic link,\n"
2604" access will examine the symbolic link itself instead of the file\n"
2605" the link points to.\n"
2606"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002607"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
2608" on your platform. If they are unavailable, using them will raise a\n"
2609" NotImplementedError.\n"
2610"\n"
2611"Note that most operations will use the effective uid/gid, therefore this\n"
2612" routine can be used in a suid/sgid environment to test if the invoking user\n"
2613" has the specified access to the path.");
2614
2615#define OS_ACCESS_METHODDEF \
2616 {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002617
2618static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002619os_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 -07002620
2621static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002622os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002623{
Larry Hastings31826802013-10-19 00:09:25 -07002624 PyObject *return_value = NULL;
2625 static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL};
2626 path_t path = PATH_T_INITIALIZE("access", 0, 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00002627 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002628 int dir_fd = DEFAULT_DIR_FD;
2629 int effective_ids = 0;
2630 int follow_symlinks = 1;
Larry Hastings31826802013-10-19 00:09:25 -07002631
2632 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2633 "O&i|$O&pp:access", _keywords,
2634 path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks))
2635 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002636 return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002637
2638exit:
2639 /* Cleanup for path */
2640 path_cleanup(&path);
2641
2642 return return_value;
2643}
2644
2645static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002646os_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 -08002647/*[clinic end generated code: output=a6ed4f151be9df0f input=2e2e7594371f5b7e]*/
Larry Hastings31826802013-10-19 00:09:25 -07002648{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002649 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002650
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002651#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002652 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002653#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002654 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002655#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002656
Larry Hastings9cf065c2012-06-22 16:30:09 -07002657#ifndef HAVE_FACCESSAT
2658 if (follow_symlinks_specified("access", follow_symlinks))
2659 goto exit;
2660
2661 if (effective_ids) {
2662 argument_unavailable_error("access", "effective_ids");
2663 goto exit;
2664 }
2665#endif
2666
2667#ifdef MS_WINDOWS
2668 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002669 if (path->wide != NULL)
2670 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002671 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002672 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002673 Py_END_ALLOW_THREADS
2674
2675 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002676 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002677 * * we didn't get a -1, and
2678 * * write access wasn't requested,
2679 * * or the file isn't read-only,
2680 * * or it's a directory.
2681 * (Directories cannot be read-only on Windows.)
2682 */
2683 return_value = PyBool_FromLong(
Tim Golden23005082013-10-25 11:22:37 +01002684 (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002685 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002686 !(attr & FILE_ATTRIBUTE_READONLY) ||
2687 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2688#else
2689
2690 Py_BEGIN_ALLOW_THREADS
2691#ifdef HAVE_FACCESSAT
2692 if ((dir_fd != DEFAULT_DIR_FD) ||
2693 effective_ids ||
2694 !follow_symlinks) {
2695 int flags = 0;
2696 if (!follow_symlinks)
2697 flags |= AT_SYMLINK_NOFOLLOW;
2698 if (effective_ids)
2699 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002700 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002701 }
2702 else
2703#endif
Larry Hastings31826802013-10-19 00:09:25 -07002704 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002705 Py_END_ALLOW_THREADS
2706 return_value = PyBool_FromLong(!result);
2707#endif
2708
2709#ifndef HAVE_FACCESSAT
2710exit:
2711#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002712 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002713}
2714
Guido van Rossumd371ff11999-01-25 16:12:23 +00002715#ifndef F_OK
2716#define F_OK 0
2717#endif
2718#ifndef R_OK
2719#define R_OK 4
2720#endif
2721#ifndef W_OK
2722#define W_OK 2
2723#endif
2724#ifndef X_OK
2725#define X_OK 1
2726#endif
2727
Larry Hastings31826802013-10-19 00:09:25 -07002728
Guido van Rossumd371ff11999-01-25 16:12:23 +00002729#ifdef HAVE_TTYNAME
Larry Hastings31826802013-10-19 00:09:25 -07002730
Larry Hastings61272b72014-01-07 12:41:53 -08002731/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002732os.ttyname -> DecodeFSDefault
2733
2734 fd: int
2735 Integer file descriptor handle.
2736
2737 /
2738
2739Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002740[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002741
2742PyDoc_STRVAR(os_ttyname__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002743"ttyname($module, fd, /)\n"
2744"--\n"
2745"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002746"Return the name of the terminal device connected to \'fd\'.\n"
2747"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002748" fd\n"
2749" Integer file descriptor handle.");
2750
2751#define OS_TTYNAME_METHODDEF \
2752 {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__},
2753
2754static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002755os_ttyname_impl(PyModuleDef *module, int fd);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002756
2757static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002758os_ttyname(PyModuleDef *module, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002759{
Larry Hastings31826802013-10-19 00:09:25 -07002760 PyObject *return_value = NULL;
2761 int fd;
2762 char *_return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002763
Larry Hastings31826802013-10-19 00:09:25 -07002764 if (!PyArg_ParseTuple(args,
2765 "i:ttyname",
2766 &fd))
2767 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002768 _return_value = os_ttyname_impl(module, fd);
Larry Hastings31826802013-10-19 00:09:25 -07002769 if (_return_value == NULL)
2770 goto exit;
2771 return_value = PyUnicode_DecodeFSDefault(_return_value);
2772
2773exit:
2774 return return_value;
2775}
2776
2777static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002778os_ttyname_impl(PyModuleDef *module, int fd)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002779/*[clinic end generated code: output=cee7bc4cffec01a2 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002780{
2781 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002782
Larry Hastings31826802013-10-19 00:09:25 -07002783 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002784 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002785 posix_error();
2786 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002787}
Larry Hastings31826802013-10-19 00:09:25 -07002788#else
2789#define OS_TTYNAME_METHODDEF
Guido van Rossumd371ff11999-01-25 16:12:23 +00002790#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002791
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002792#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002793PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002794"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002795Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002796
2797static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002798posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002799{
Victor Stinner8c62be82010-05-06 00:08:46 +00002800 char *ret;
2801 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002802
Greg Wardb48bc172000-03-01 21:51:56 +00002803#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002804 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002805#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002806 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002807#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002808 if (ret == NULL)
2809 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002810 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002811}
2812#endif
2813
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002814PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002815"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002816Change the current working directory to the specified path.\n\
2817\n\
2818path may always be specified as a string.\n\
2819On some platforms, path may also be specified as an open file descriptor.\n\
2820 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002821
Barry Warsaw53699e91996-12-10 23:23:01 +00002822static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002823posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002824{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002825 path_t path;
2826 int result;
2827 PyObject *return_value = NULL;
2828 static char *keywords[] = {"path", NULL};
2829
2830 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002831 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002832#ifdef HAVE_FCHDIR
2833 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002834#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2836 path_converter, &path
2837 ))
2838 return NULL;
2839
2840 Py_BEGIN_ALLOW_THREADS
2841#ifdef MS_WINDOWS
2842 if (path.wide)
2843 result = win32_wchdir(path.wide);
2844 else
2845 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002846 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002847#else
2848#ifdef HAVE_FCHDIR
2849 if (path.fd != -1)
2850 result = fchdir(path.fd);
2851 else
2852#endif
2853 result = chdir(path.narrow);
2854#endif
2855 Py_END_ALLOW_THREADS
2856
2857 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002858 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002859 goto exit;
2860 }
2861
2862 return_value = Py_None;
2863 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002864
Larry Hastings9cf065c2012-06-22 16:30:09 -07002865exit:
2866 path_cleanup(&path);
2867 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002868}
2869
Fred Drake4d1e64b2002-04-15 19:40:07 +00002870#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002871PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002872"fchdir(fd)\n\n\
2873Change to the directory of the given file descriptor. fd must be\n\
2874opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002875
2876static PyObject *
2877posix_fchdir(PyObject *self, PyObject *fdobj)
2878{
Victor Stinner8c62be82010-05-06 00:08:46 +00002879 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002880}
2881#endif /* HAVE_FCHDIR */
2882
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002883
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002884PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002885"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2886Change the access permissions of a file.\n\
2887\n\
2888path may always be specified as a string.\n\
2889On some platforms, path may also be specified as an open file descriptor.\n\
2890 If this functionality is unavailable, using it raises an exception.\n\
2891If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2892 and path should be relative; path will then be relative to that directory.\n\
2893If follow_symlinks is False, and the last element of the path is a symbolic\n\
2894 link, chmod will modify the symbolic link itself instead of the file the\n\
2895 link points to.\n\
2896It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2897 an open file descriptor.\n\
2898dir_fd and follow_symlinks may not be implemented on your platform.\n\
2899 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002900
Barry Warsaw53699e91996-12-10 23:23:01 +00002901static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002902posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002903{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002904 path_t path;
2905 int mode;
2906 int dir_fd = DEFAULT_DIR_FD;
2907 int follow_symlinks = 1;
2908 int result;
2909 PyObject *return_value = NULL;
2910 static char *keywords[] = {"path", "mode", "dir_fd",
2911 "follow_symlinks", NULL};
2912
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002913#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002914 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002915#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002916
Larry Hastings9cf065c2012-06-22 16:30:09 -07002917#ifdef HAVE_FCHMODAT
2918 int fchmodat_nofollow_unsupported = 0;
2919#endif
2920
2921 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002922 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002923#ifdef HAVE_FCHMOD
2924 path.allow_fd = 1;
2925#endif
2926 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2927 path_converter, &path,
2928 &mode,
2929#ifdef HAVE_FCHMODAT
2930 dir_fd_converter, &dir_fd,
2931#else
2932 dir_fd_unavailable, &dir_fd,
2933#endif
2934 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002935 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002936
2937#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2938 if (follow_symlinks_specified("chmod", follow_symlinks))
2939 goto exit;
2940#endif
2941
2942#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002943 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002944 if (path.wide)
2945 attr = GetFileAttributesW(path.wide);
2946 else
2947 attr = GetFileAttributesA(path.narrow);
Tim Golden23005082013-10-25 11:22:37 +01002948 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002949 result = 0;
2950 else {
2951 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002952 attr &= ~FILE_ATTRIBUTE_READONLY;
2953 else
2954 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002955 if (path.wide)
2956 result = SetFileAttributesW(path.wide, attr);
2957 else
2958 result = SetFileAttributesA(path.narrow, attr);
2959 }
2960 Py_END_ALLOW_THREADS
2961
2962 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002963 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002964 goto exit;
2965 }
2966#else /* MS_WINDOWS */
2967 Py_BEGIN_ALLOW_THREADS
2968#ifdef HAVE_FCHMOD
2969 if (path.fd != -1)
2970 result = fchmod(path.fd, mode);
2971 else
2972#endif
2973#ifdef HAVE_LCHMOD
2974 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2975 result = lchmod(path.narrow, mode);
2976 else
2977#endif
2978#ifdef HAVE_FCHMODAT
2979 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2980 /*
2981 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2982 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002983 * and then says it isn't implemented yet.
2984 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002985 *
2986 * Once it is supported, os.chmod will automatically
2987 * support dir_fd and follow_symlinks=False. (Hopefully.)
2988 * Until then, we need to be careful what exception we raise.
2989 */
2990 result = fchmodat(dir_fd, path.narrow, mode,
2991 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2992 /*
2993 * But wait! We can't throw the exception without allowing threads,
2994 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2995 */
2996 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002997 result &&
2998 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2999 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00003000 }
3001 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00003002#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003003 result = chmod(path.narrow, mode);
3004 Py_END_ALLOW_THREADS
3005
3006 if (result) {
3007#ifdef HAVE_FCHMODAT
3008 if (fchmodat_nofollow_unsupported) {
3009 if (dir_fd != DEFAULT_DIR_FD)
3010 dir_fd_and_follow_symlinks_invalid("chmod",
3011 dir_fd, follow_symlinks);
3012 else
3013 follow_symlinks_specified("chmod", follow_symlinks);
3014 }
3015 else
3016#endif
Victor Stinner292c8352012-10-30 02:17:38 +01003017 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003018 goto exit;
3019 }
3020#endif
3021
3022 Py_INCREF(Py_None);
3023 return_value = Py_None;
3024exit:
3025 path_cleanup(&path);
3026 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003027}
3028
Larry Hastings9cf065c2012-06-22 16:30:09 -07003029
Christian Heimes4e30a842007-11-30 22:12:06 +00003030#ifdef HAVE_FCHMOD
3031PyDoc_STRVAR(posix_fchmod__doc__,
3032"fchmod(fd, mode)\n\n\
3033Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003034descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003035
3036static PyObject *
3037posix_fchmod(PyObject *self, PyObject *args)
3038{
Victor Stinner8c62be82010-05-06 00:08:46 +00003039 int fd, mode, res;
3040 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
3041 return NULL;
3042 Py_BEGIN_ALLOW_THREADS
3043 res = fchmod(fd, mode);
3044 Py_END_ALLOW_THREADS
3045 if (res < 0)
3046 return posix_error();
3047 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003048}
3049#endif /* HAVE_FCHMOD */
3050
3051#ifdef HAVE_LCHMOD
3052PyDoc_STRVAR(posix_lchmod__doc__,
3053"lchmod(path, mode)\n\n\
3054Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003055affects the link itself rather than the target.\n\
3056Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003057
3058static PyObject *
3059posix_lchmod(PyObject *self, PyObject *args)
3060{
Victor Stinner292c8352012-10-30 02:17:38 +01003061 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003062 int i;
3063 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003064 memset(&path, 0, sizeof(path));
3065 path.function_name = "lchmod";
3066 if (!PyArg_ParseTuple(args, "O&i:lchmod",
3067 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00003068 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003069 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003070 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00003071 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003072 if (res < 0) {
3073 path_error(&path);
3074 path_cleanup(&path);
3075 return NULL;
3076 }
3077 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003078 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003079}
3080#endif /* HAVE_LCHMOD */
3081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003082
Thomas Wouterscf297e42007-02-23 15:07:44 +00003083#ifdef HAVE_CHFLAGS
3084PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003085"chflags(path, flags, *, follow_symlinks=True)\n\n\
3086Set file flags.\n\
3087\n\
3088If follow_symlinks is False, and the last element of the path is a symbolic\n\
3089 link, chflags will change flags on the symbolic link itself instead of the\n\
3090 file the link points to.\n\
3091follow_symlinks may not be implemented on your platform. If it is\n\
3092unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003093
3094static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003095posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003096{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003097 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003098 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003099 int follow_symlinks = 1;
3100 int result;
Victor Stinner45e90392013-07-18 23:57:35 +02003101 PyObject *return_value = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003102 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
3103
3104 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003105 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003106 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
3107 path_converter, &path,
3108 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003109 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110
3111#ifndef HAVE_LCHFLAGS
3112 if (follow_symlinks_specified("chflags", follow_symlinks))
3113 goto exit;
3114#endif
3115
Victor Stinner8c62be82010-05-06 00:08:46 +00003116 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003117#ifdef HAVE_LCHFLAGS
3118 if (!follow_symlinks)
3119 result = lchflags(path.narrow, flags);
3120 else
3121#endif
3122 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003123 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003124
3125 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003126 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003127 goto exit;
3128 }
3129
3130 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003131 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003132
3133exit:
3134 path_cleanup(&path);
3135 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003136}
3137#endif /* HAVE_CHFLAGS */
3138
3139#ifdef HAVE_LCHFLAGS
3140PyDoc_STRVAR(posix_lchflags__doc__,
3141"lchflags(path, flags)\n\n\
3142Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003143This function will not follow symbolic links.\n\
3144Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003145
3146static PyObject *
3147posix_lchflags(PyObject *self, PyObject *args)
3148{
Victor Stinner292c8352012-10-30 02:17:38 +01003149 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003150 unsigned long flags;
3151 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003152 memset(&path, 0, sizeof(path));
3153 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00003154 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01003155 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00003156 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003157 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003158 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003159 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003160 if (res < 0) {
3161 path_error(&path);
3162 path_cleanup(&path);
3163 return NULL;
3164 }
3165 path_cleanup(&path);
3166 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003167}
3168#endif /* HAVE_LCHFLAGS */
3169
Martin v. Löwis244edc82001-10-04 22:44:26 +00003170#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003171PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003172"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003173Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00003174
3175static PyObject *
3176posix_chroot(PyObject *self, PyObject *args)
3177{
Victor Stinner292c8352012-10-30 02:17:38 +01003178 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00003179}
3180#endif
3181
Guido van Rossum21142a01999-01-08 21:05:37 +00003182#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003183PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003184"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003185force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003186
3187static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003188posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003189{
Stefan Krah0e803b32010-11-26 16:16:47 +00003190 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003191}
3192#endif /* HAVE_FSYNC */
3193
Ross Lagerwall7807c352011-03-17 20:20:30 +02003194#ifdef HAVE_SYNC
3195PyDoc_STRVAR(posix_sync__doc__,
3196"sync()\n\n\
3197Force write of everything to disk.");
3198
3199static PyObject *
3200posix_sync(PyObject *self, PyObject *noargs)
3201{
3202 Py_BEGIN_ALLOW_THREADS
3203 sync();
3204 Py_END_ALLOW_THREADS
3205 Py_RETURN_NONE;
3206}
3207#endif
3208
Guido van Rossum21142a01999-01-08 21:05:37 +00003209#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00003210
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003211#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003212extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3213#endif
3214
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003215PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003216"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003217force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003218 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003219
3220static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003221posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003222{
Stefan Krah0e803b32010-11-26 16:16:47 +00003223 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003224}
3225#endif /* HAVE_FDATASYNC */
3226
3227
Fredrik Lundh10723342000-07-10 16:38:09 +00003228#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003229PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003230"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3231Change the owner and group id of path to the numeric uid and gid.\n\
3232\n\
3233path may always be specified as a string.\n\
3234On some platforms, path may also be specified as an open file descriptor.\n\
3235 If this functionality is unavailable, using it raises an exception.\n\
3236If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3237 and path should be relative; path will then be relative to that directory.\n\
3238If follow_symlinks is False, and the last element of the path is a symbolic\n\
3239 link, chown will modify the symbolic link itself instead of the file the\n\
3240 link points to.\n\
3241It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3242 an open file descriptor.\n\
3243dir_fd and follow_symlinks may not be implemented on your platform.\n\
3244 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003245
Barry Warsaw53699e91996-12-10 23:23:01 +00003246static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003247posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003248{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003249 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003250 uid_t uid;
3251 gid_t gid;
3252 int dir_fd = DEFAULT_DIR_FD;
3253 int follow_symlinks = 1;
3254 int result;
3255 PyObject *return_value = NULL;
3256 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3257 "follow_symlinks", NULL};
3258
3259 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003260 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003261#ifdef HAVE_FCHOWN
3262 path.allow_fd = 1;
3263#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003264 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003265 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003266 _Py_Uid_Converter, &uid,
3267 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003268#ifdef HAVE_FCHOWNAT
3269 dir_fd_converter, &dir_fd,
3270#else
3271 dir_fd_unavailable, &dir_fd,
3272#endif
3273 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003274 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003275
3276#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3277 if (follow_symlinks_specified("chown", follow_symlinks))
3278 goto exit;
3279#endif
3280 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3281 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3282 goto exit;
3283
3284#ifdef __APPLE__
3285 /*
3286 * This is for Mac OS X 10.3, which doesn't have lchown.
3287 * (But we still have an lchown symbol because of weak-linking.)
3288 * It doesn't have fchownat either. So there's no possibility
3289 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003290 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003291 if ((!follow_symlinks) && (lchown == NULL)) {
3292 follow_symlinks_specified("chown", follow_symlinks);
3293 goto exit;
3294 }
3295#endif
3296
Victor Stinner8c62be82010-05-06 00:08:46 +00003297 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003298#ifdef HAVE_FCHOWN
3299 if (path.fd != -1)
3300 result = fchown(path.fd, uid, gid);
3301 else
3302#endif
3303#ifdef HAVE_LCHOWN
3304 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3305 result = lchown(path.narrow, uid, gid);
3306 else
3307#endif
3308#ifdef HAVE_FCHOWNAT
3309 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3310 result = fchownat(dir_fd, path.narrow, uid, gid,
3311 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3312 else
3313#endif
3314 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003315 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003316
3317 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003318 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003319 goto exit;
3320 }
3321
3322 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003323 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003324
3325exit:
3326 path_cleanup(&path);
3327 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003328}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003329#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003330
Christian Heimes4e30a842007-11-30 22:12:06 +00003331#ifdef HAVE_FCHOWN
3332PyDoc_STRVAR(posix_fchown__doc__,
3333"fchown(fd, uid, gid)\n\n\
3334Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003335fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003336
3337static PyObject *
3338posix_fchown(PyObject *self, PyObject *args)
3339{
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003341 uid_t uid;
3342 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003343 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003344 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3345 _Py_Uid_Converter, &uid,
3346 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003347 return NULL;
3348 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003349 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003350 Py_END_ALLOW_THREADS
3351 if (res < 0)
3352 return posix_error();
3353 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003354}
3355#endif /* HAVE_FCHOWN */
3356
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003357#ifdef HAVE_LCHOWN
3358PyDoc_STRVAR(posix_lchown__doc__,
3359"lchown(path, uid, gid)\n\n\
3360Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003361This function will not follow symbolic links.\n\
3362Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003363
3364static PyObject *
3365posix_lchown(PyObject *self, PyObject *args)
3366{
Victor Stinner292c8352012-10-30 02:17:38 +01003367 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003368 uid_t uid;
3369 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003371 memset(&path, 0, sizeof(path));
3372 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003373 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003374 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003375 _Py_Uid_Converter, &uid,
3376 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003377 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003378 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003379 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003380 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003381 if (res < 0) {
3382 path_error(&path);
3383 path_cleanup(&path);
3384 return NULL;
3385 }
3386 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003387 Py_INCREF(Py_None);
3388 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003389}
3390#endif /* HAVE_LCHOWN */
3391
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003392
Barry Warsaw53699e91996-12-10 23:23:01 +00003393static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003394posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003395{
Victor Stinner8c62be82010-05-06 00:08:46 +00003396 char buf[1026];
3397 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003398
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003399#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003400 if (!use_bytes) {
3401 wchar_t wbuf[1026];
3402 wchar_t *wbuf2 = wbuf;
3403 PyObject *resobj;
3404 DWORD len;
3405 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003406 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 /* If the buffer is large enough, len does not include the
3408 terminating \0. If the buffer is too small, len includes
3409 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003410 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003411 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 if (wbuf2)
3413 len = GetCurrentDirectoryW(len, wbuf2);
3414 }
3415 Py_END_ALLOW_THREADS
3416 if (!wbuf2) {
3417 PyErr_NoMemory();
3418 return NULL;
3419 }
3420 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003421 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003422 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003423 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003424 }
3425 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003426 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003427 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 return resobj;
3429 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003430
3431 if (win32_warn_bytes_api())
3432 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003433#endif
3434
Victor Stinner8c62be82010-05-06 00:08:46 +00003435 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003436 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003437 Py_END_ALLOW_THREADS
3438 if (res == NULL)
3439 return posix_error();
3440 if (use_bytes)
3441 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003442 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003443}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003444
3445PyDoc_STRVAR(posix_getcwd__doc__,
3446"getcwd() -> path\n\n\
3447Return a unicode string representing the current working directory.");
3448
3449static PyObject *
3450posix_getcwd_unicode(PyObject *self)
3451{
3452 return posix_getcwd(0);
3453}
3454
3455PyDoc_STRVAR(posix_getcwdb__doc__,
3456"getcwdb() -> path\n\n\
3457Return a bytes string representing the current working directory.");
3458
3459static PyObject *
3460posix_getcwd_bytes(PyObject *self)
3461{
3462 return posix_getcwd(1);
3463}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003464
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3466#define HAVE_LINK 1
3467#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003468
Guido van Rossumb6775db1994-08-01 11:34:53 +00003469#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003470PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3472Create a hard link to a file.\n\
3473\n\
3474If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3475 descriptor open to a directory, and the respective path string (src or dst)\n\
3476 should be relative; the path will then be relative to that directory.\n\
3477If follow_symlinks is False, and the last element of src is a symbolic\n\
3478 link, link will create a link to the symbolic link itself instead of the\n\
3479 file the link points to.\n\
3480src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3481 platform. If they are unavailable, using them will raise a\n\
3482 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003483
Barry Warsaw53699e91996-12-10 23:23:01 +00003484static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003485posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003486{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 path_t src, dst;
3488 int src_dir_fd = DEFAULT_DIR_FD;
3489 int dst_dir_fd = DEFAULT_DIR_FD;
3490 int follow_symlinks = 1;
3491 PyObject *return_value = NULL;
3492 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3493 "follow_symlinks", NULL};
3494#ifdef MS_WINDOWS
3495 BOOL result;
3496#else
3497 int result;
3498#endif
3499
3500 memset(&src, 0, sizeof(src));
3501 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003502 src.function_name = "link";
3503 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003504 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3505 path_converter, &src,
3506 path_converter, &dst,
3507 dir_fd_converter, &src_dir_fd,
3508 dir_fd_converter, &dst_dir_fd,
3509 &follow_symlinks))
3510 return NULL;
3511
3512#ifndef HAVE_LINKAT
3513 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3514 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3515 goto exit;
3516 }
3517#endif
3518
3519 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3520 PyErr_SetString(PyExc_NotImplementedError,
3521 "link: src and dst must be the same type");
3522 goto exit;
3523 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003524
Brian Curtin1b9df392010-11-24 20:24:31 +00003525#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526 Py_BEGIN_ALLOW_THREADS
3527 if (src.wide)
3528 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3529 else
3530 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3531 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003532
Larry Hastings9cf065c2012-06-22 16:30:09 -07003533 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08003534 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003535 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003536 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537#else
3538 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003539#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003540 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3541 (dst_dir_fd != DEFAULT_DIR_FD) ||
3542 (!follow_symlinks))
3543 result = linkat(src_dir_fd, src.narrow,
3544 dst_dir_fd, dst.narrow,
3545 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3546 else
3547#endif
3548 result = link(src.narrow, dst.narrow);
3549 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003550
Larry Hastings9cf065c2012-06-22 16:30:09 -07003551 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08003552 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003553 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003554 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003555#endif
3556
3557 return_value = Py_None;
3558 Py_INCREF(Py_None);
3559
3560exit:
3561 path_cleanup(&src);
3562 path_cleanup(&dst);
3563 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003564}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003565#endif
3566
Brian Curtin1b9df392010-11-24 20:24:31 +00003567
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003568
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003569PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003570"listdir(path='.') -> list_of_filenames\n\n\
3571Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003572The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573entries '.' and '..' even if they are present in the directory.\n\
3574\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003575path can be specified as either str or bytes. If path is bytes,\n\
3576 the filenames returned will also be bytes; in all other circumstances\n\
3577 the filenames returned will be str.\n\
3578On some platforms, path may also be specified as an open file descriptor;\n\
3579 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003581
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003582#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003583static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003584_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003585{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003586 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 PyObject *v;
3588 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3589 BOOL result;
3590 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003591 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 char *bufptr = namebuf;
3593 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003594 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003595 PyObject *po = NULL;
3596 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003597
Gregory P. Smith40a21602013-03-20 20:52:50 -07003598 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003599 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003600 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003601
Gregory P. Smith40a21602013-03-20 20:52:50 -07003602 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003603 po_wchars = L".";
3604 len = 1;
3605 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003606 po_wchars = path->wide;
3607 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003608 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609 /* The +5 is so we can append "\\*.*\0" */
Victor Stinnerb6404912013-07-07 16:21:41 +02003610 wnamebuf = PyMem_Malloc((len + 5) * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003611 if (!wnamebuf) {
3612 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003613 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003614 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003615 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003616 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003617 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003618 if (wch != SEP && wch != ALTSEP && wch != L':')
3619 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003620 wcscpy(wnamebuf + len, L"*.*");
3621 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003622 if ((list = PyList_New(0)) == NULL) {
3623 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003624 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003625 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003626 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003627 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003628 if (hFindFile == INVALID_HANDLE_VALUE) {
3629 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003630 if (error == ERROR_FILE_NOT_FOUND)
3631 goto exit;
3632 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003633 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 }
3636 do {
3637 /* Skip over . and .. */
3638 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3639 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003640 v = PyUnicode_FromWideChar(wFileData.cFileName,
3641 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003642 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003643 Py_DECREF(list);
3644 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 break;
3646 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003647 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003648 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003649 Py_DECREF(list);
3650 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 break;
3652 }
3653 Py_DECREF(v);
3654 }
3655 Py_BEGIN_ALLOW_THREADS
3656 result = FindNextFileW(hFindFile, &wFileData);
3657 Py_END_ALLOW_THREADS
3658 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3659 it got to the end of the directory. */
3660 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003661 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003662 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003663 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003664 }
3665 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003666
Larry Hastings9cf065c2012-06-22 16:30:09 -07003667 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003668 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003669 strcpy(namebuf, path->narrow);
3670 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 if (len > 0) {
3672 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003673 if (ch != '\\' && ch != '/' && ch != ':')
3674 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003675 strcpy(namebuf + len, "*.*");
3676 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003677
Larry Hastings9cf065c2012-06-22 16:30:09 -07003678 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003679 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003680
Antoine Pitroub73caab2010-08-09 23:39:31 +00003681 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003682 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003683 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 if (hFindFile == INVALID_HANDLE_VALUE) {
3685 int error = GetLastError();
3686 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003687 goto exit;
3688 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003689 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003690 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003691 }
3692 do {
3693 /* Skip over . and .. */
3694 if (strcmp(FileData.cFileName, ".") != 0 &&
3695 strcmp(FileData.cFileName, "..") != 0) {
3696 v = PyBytes_FromString(FileData.cFileName);
3697 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003698 Py_DECREF(list);
3699 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 break;
3701 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003702 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003703 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003704 Py_DECREF(list);
3705 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003706 break;
3707 }
3708 Py_DECREF(v);
3709 }
3710 Py_BEGIN_ALLOW_THREADS
3711 result = FindNextFile(hFindFile, &FileData);
3712 Py_END_ALLOW_THREADS
3713 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3714 it got to the end of the directory. */
3715 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003716 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003717 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003718 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003719 }
3720 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003721
Larry Hastings9cf065c2012-06-22 16:30:09 -07003722exit:
3723 if (hFindFile != INVALID_HANDLE_VALUE) {
3724 if (FindClose(hFindFile) == FALSE) {
3725 if (list != NULL) {
3726 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003727 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728 }
3729 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003730 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003731 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003732
Larry Hastings9cf065c2012-06-22 16:30:09 -07003733 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003734} /* end of _listdir_windows_no_opendir */
3735
3736#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3737
3738static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003739_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003740{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003741 PyObject *v;
3742 DIR *dirp = NULL;
3743 struct dirent *ep;
3744 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003745#ifdef HAVE_FDOPENDIR
3746 int fd = -1;
3747#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003748
Victor Stinner8c62be82010-05-06 00:08:46 +00003749 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003750#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003751 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003752 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003753 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003754 if (fd == -1)
3755 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003756
Larry Hastingsfdaea062012-06-25 04:42:23 -07003757 return_str = 1;
3758
Larry Hastings9cf065c2012-06-22 16:30:09 -07003759 Py_BEGIN_ALLOW_THREADS
3760 dirp = fdopendir(fd);
3761 Py_END_ALLOW_THREADS
3762 }
3763 else
3764#endif
3765 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003766 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003767 if (path->narrow) {
3768 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003769 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003770 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003771 }
3772 else {
3773 name = ".";
3774 return_str = 1;
3775 }
3776
Larry Hastings9cf065c2012-06-22 16:30:09 -07003777 Py_BEGIN_ALLOW_THREADS
3778 dirp = opendir(name);
3779 Py_END_ALLOW_THREADS
3780 }
3781
3782 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003783 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003784#ifdef HAVE_FDOPENDIR
3785 if (fd != -1) {
3786 Py_BEGIN_ALLOW_THREADS
3787 close(fd);
3788 Py_END_ALLOW_THREADS
3789 }
3790#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003791 goto exit;
3792 }
3793 if ((list = PyList_New(0)) == NULL) {
3794 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003795 }
3796 for (;;) {
3797 errno = 0;
3798 Py_BEGIN_ALLOW_THREADS
3799 ep = readdir(dirp);
3800 Py_END_ALLOW_THREADS
3801 if (ep == NULL) {
3802 if (errno == 0) {
3803 break;
3804 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003805 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003806 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003807 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003808 }
3809 }
3810 if (ep->d_name[0] == '.' &&
3811 (NAMLEN(ep) == 1 ||
3812 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3813 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003814 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003815 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3816 else
3817 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003818 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003819 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003820 break;
3821 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003822 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003823 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003824 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003825 break;
3826 }
3827 Py_DECREF(v);
3828 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003829
Larry Hastings9cf065c2012-06-22 16:30:09 -07003830exit:
3831 if (dirp != NULL) {
3832 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003833#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003834 if (fd > -1)
3835 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003836#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003837 closedir(dirp);
3838 Py_END_ALLOW_THREADS
3839 }
3840
Larry Hastings9cf065c2012-06-22 16:30:09 -07003841 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003842} /* end of _posix_listdir */
3843#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003844
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003845static PyObject *
3846posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3847{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003848 path_t path;
3849 PyObject *list = NULL;
3850 static char *keywords[] = {"path", NULL};
3851 PyObject *return_value;
3852
3853 memset(&path, 0, sizeof(path));
3854 path.function_name = "listdir";
3855 path.nullable = 1;
3856#ifdef HAVE_FDOPENDIR
3857 path.allow_fd = 1;
3858 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003859#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003860
3861 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3862 path_converter, &path)) {
3863 return NULL;
3864 }
3865
3866#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3867 return_value = _listdir_windows_no_opendir(&path, list);
3868#else
3869 return_value = _posix_listdir(&path, list);
3870#endif
3871 path_cleanup(&path);
3872 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003873}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003874
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003875#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003876/* A helper function for abspath on win32 */
3877static PyObject *
3878posix__getfullpathname(PyObject *self, PyObject *args)
3879{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003880 const char *path;
Victor Stinner75875072013-11-24 19:23:25 +01003881 char outbuf[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00003882 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003883 PyObject *po;
3884
3885 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3886 {
3887 wchar_t *wpath;
Victor Stinner75875072013-11-24 19:23:25 +01003888 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003889 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003890 DWORD result;
3891 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003892
3893 wpath = PyUnicode_AsUnicode(po);
3894 if (wpath == NULL)
3895 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003896 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003897 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003898 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003899 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003900 woutbufp = PyMem_Malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003901 if (!woutbufp)
3902 return PyErr_NoMemory();
3903 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3904 }
3905 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003906 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003907 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003908 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003909 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003910 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003911 return v;
3912 }
3913 /* Drop the argument parsing error as narrow strings
3914 are also valid. */
3915 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003916
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003917 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3918 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003919 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003920 if (win32_warn_bytes_api())
3921 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003922 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003923 outbuf, &temp)) {
3924 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003925 return NULL;
3926 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003927 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3928 return PyUnicode_Decode(outbuf, strlen(outbuf),
3929 Py_FileSystemDefaultEncoding, NULL);
3930 }
3931 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003932} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003933
Brian Curtind25aef52011-06-13 15:16:04 -05003934
Brian Curtinf5e76d02010-11-24 13:14:05 +00003935
Brian Curtind40e6f72010-07-08 21:39:08 +00003936/* A helper function for samepath on windows */
3937static PyObject *
3938posix__getfinalpathname(PyObject *self, PyObject *args)
3939{
3940 HANDLE hFile;
3941 int buf_size;
3942 wchar_t *target_path;
3943 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003944 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003945 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003946
Victor Stinnereb5657a2011-09-30 01:44:27 +02003947 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003948 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003949 path = PyUnicode_AsUnicode(po);
3950 if (path == NULL)
3951 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003952
3953 if(!check_GetFinalPathNameByHandle()) {
3954 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3955 NotImplementedError. */
3956 return PyErr_Format(PyExc_NotImplementedError,
3957 "GetFinalPathNameByHandle not available on this platform");
3958 }
3959
3960 hFile = CreateFileW(
3961 path,
3962 0, /* desired access */
3963 0, /* share mode */
3964 NULL, /* security attributes */
3965 OPEN_EXISTING,
3966 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3967 FILE_FLAG_BACKUP_SEMANTICS,
3968 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003969
Victor Stinnereb5657a2011-09-30 01:44:27 +02003970 if(hFile == INVALID_HANDLE_VALUE)
3971 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003972
3973 /* We have a good handle to the target, use it to determine the
3974 target path name. */
3975 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3976
3977 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003978 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003979
Victor Stinnerb6404912013-07-07 16:21:41 +02003980 target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtind40e6f72010-07-08 21:39:08 +00003981 if(!target_path)
3982 return PyErr_NoMemory();
3983
3984 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3985 buf_size, VOLUME_NAME_DOS);
3986 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003987 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003988
3989 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003990 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003991
3992 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003993 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003994 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003995 return result;
3996
3997} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003998
Brian Curtin95d028f2011-06-09 09:10:38 -05003999PyDoc_STRVAR(posix__isdir__doc__,
4000"Return true if the pathname refers to an existing directory.");
4001
Brian Curtin9c669cc2011-06-08 18:17:18 -05004002static PyObject *
4003posix__isdir(PyObject *self, PyObject *args)
4004{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004005 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004006 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004007 DWORD attributes;
4008
4009 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02004010 wchar_t *wpath = PyUnicode_AsUnicode(po);
4011 if (wpath == NULL)
4012 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004013
4014 attributes = GetFileAttributesW(wpath);
4015 if (attributes == INVALID_FILE_ATTRIBUTES)
4016 Py_RETURN_FALSE;
4017 goto check;
4018 }
4019 /* Drop the argument parsing error as narrow strings
4020 are also valid. */
4021 PyErr_Clear();
4022
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004023 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05004024 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004025 if (win32_warn_bytes_api())
4026 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004027 attributes = GetFileAttributesA(path);
4028 if (attributes == INVALID_FILE_ATTRIBUTES)
4029 Py_RETURN_FALSE;
4030
4031check:
4032 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4033 Py_RETURN_TRUE;
4034 else
4035 Py_RETURN_FALSE;
4036}
Tim Golden6b528062013-08-01 12:44:00 +01004037
4038PyDoc_STRVAR(posix__getvolumepathname__doc__,
4039"Return volume mount point of the specified path.");
4040
4041/* A helper function for ismount on windows */
4042static PyObject *
4043posix__getvolumepathname(PyObject *self, PyObject *args)
4044{
4045 PyObject *po, *result;
4046 wchar_t *path, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004047 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004048 BOOL ret;
4049
4050 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
4051 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004052 path = PyUnicode_AsUnicodeAndSize(po, &buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004053 if (path == NULL)
4054 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004055 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01004056
4057 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01004058 buflen = Py_MAX(buflen, MAX_PATH);
4059
4060 if (buflen > DWORD_MAX) {
4061 PyErr_SetString(PyExc_OverflowError, "path too long");
4062 return NULL;
4063 }
4064
4065 mountpath = (wchar_t *)PyMem_Malloc(buflen * sizeof(wchar_t));
Tim Golden6b528062013-08-01 12:44:00 +01004066 if (mountpath == NULL)
4067 return PyErr_NoMemory();
4068
4069 Py_BEGIN_ALLOW_THREADS
Christian Heimes85ba92a2013-11-18 10:30:42 +01004070 ret = GetVolumePathNameW(path, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004071 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004072 Py_END_ALLOW_THREADS
4073
4074 if (!ret) {
4075 result = win32_error_object("_getvolumepathname", po);
4076 goto exit;
4077 }
4078 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4079
4080exit:
4081 PyMem_Free(mountpath);
4082 return result;
4083}
4084/* end of posix__getvolumepathname */
4085
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004086#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004087
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004088PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004089"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4090Create a directory.\n\
4091\n\
4092If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4093 and path should be relative; path will then be relative to that directory.\n\
4094dir_fd may not be implemented on your platform.\n\
4095 If it is unavailable, using it will raise a NotImplementedError.\n\
4096\n\
4097The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004098
Barry Warsaw53699e91996-12-10 23:23:01 +00004099static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004100posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004101{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004102 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004103 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004104 int dir_fd = DEFAULT_DIR_FD;
4105 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
4106 PyObject *return_value = NULL;
4107 int result;
4108
4109 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004110 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004111 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4112 path_converter, &path, &mode,
4113#ifdef HAVE_MKDIRAT
4114 dir_fd_converter, &dir_fd
4115#else
4116 dir_fd_unavailable, &dir_fd
4117#endif
4118 ))
4119 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004120
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004121#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004122 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004123 if (path.wide)
4124 result = CreateDirectoryW(path.wide, NULL);
4125 else
4126 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004127 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004128
Larry Hastings9cf065c2012-06-22 16:30:09 -07004129 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004130 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004131 goto exit;
4132 }
4133#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004134 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004135#if HAVE_MKDIRAT
4136 if (dir_fd != DEFAULT_DIR_FD)
4137 result = mkdirat(dir_fd, path.narrow, mode);
4138 else
4139#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004140#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004141 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004142#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004143 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004144#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004145 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004146 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01004147 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004148 goto exit;
4149 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004150#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004151 return_value = Py_None;
4152 Py_INCREF(Py_None);
4153exit:
4154 path_cleanup(&path);
4155 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004156}
4157
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004158
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004159/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4160#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004161#include <sys/resource.h>
4162#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004163
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004164
4165#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004166PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004167"nice(inc) -> new_priority\n\n\
4168Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004169
Barry Warsaw53699e91996-12-10 23:23:01 +00004170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004171posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004172{
Victor Stinner8c62be82010-05-06 00:08:46 +00004173 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004174
Victor Stinner8c62be82010-05-06 00:08:46 +00004175 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4176 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004177
Victor Stinner8c62be82010-05-06 00:08:46 +00004178 /* There are two flavours of 'nice': one that returns the new
4179 priority (as required by almost all standards out there) and the
4180 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4181 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004182
Victor Stinner8c62be82010-05-06 00:08:46 +00004183 If we are of the nice family that returns the new priority, we
4184 need to clear errno before the call, and check if errno is filled
4185 before calling posix_error() on a returnvalue of -1, because the
4186 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004187
Victor Stinner8c62be82010-05-06 00:08:46 +00004188 errno = 0;
4189 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004190#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004191 if (value == 0)
4192 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004193#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004194 if (value == -1 && errno != 0)
4195 /* either nice() or getpriority() returned an error */
4196 return posix_error();
4197 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004198}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004199#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004200
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004201
4202#ifdef HAVE_GETPRIORITY
4203PyDoc_STRVAR(posix_getpriority__doc__,
4204"getpriority(which, who) -> current_priority\n\n\
4205Get program scheduling priority.");
4206
4207static PyObject *
4208posix_getpriority(PyObject *self, PyObject *args)
4209{
4210 int which, who, retval;
4211
4212 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4213 return NULL;
4214 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004215 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004216 if (errno != 0)
4217 return posix_error();
4218 return PyLong_FromLong((long)retval);
4219}
4220#endif /* HAVE_GETPRIORITY */
4221
4222
4223#ifdef HAVE_SETPRIORITY
4224PyDoc_STRVAR(posix_setpriority__doc__,
4225"setpriority(which, who, prio) -> None\n\n\
4226Set program scheduling priority.");
4227
4228static PyObject *
4229posix_setpriority(PyObject *self, PyObject *args)
4230{
4231 int which, who, prio, retval;
4232
4233 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4234 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004235 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004236 if (retval == -1)
4237 return posix_error();
4238 Py_RETURN_NONE;
4239}
4240#endif /* HAVE_SETPRIORITY */
4241
4242
Barry Warsaw53699e91996-12-10 23:23:01 +00004243static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004244internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004245{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004246 char *function_name = is_replace ? "replace" : "rename";
4247 path_t src;
4248 path_t dst;
4249 int src_dir_fd = DEFAULT_DIR_FD;
4250 int dst_dir_fd = DEFAULT_DIR_FD;
4251 int dir_fd_specified;
4252 PyObject *return_value = NULL;
4253 char format[24];
4254 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4255
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004256#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004257 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004258 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004259#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004260 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004261#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004262
4263 memset(&src, 0, sizeof(src));
4264 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01004265 src.function_name = function_name;
4266 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004267 strcpy(format, "O&O&|$O&O&:");
4268 strcat(format, function_name);
4269 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4270 path_converter, &src,
4271 path_converter, &dst,
4272 dir_fd_converter, &src_dir_fd,
4273 dir_fd_converter, &dst_dir_fd))
4274 return NULL;
4275
4276 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4277 (dst_dir_fd != DEFAULT_DIR_FD);
4278#ifndef HAVE_RENAMEAT
4279 if (dir_fd_specified) {
4280 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4281 goto exit;
4282 }
4283#endif
4284
4285 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4286 PyErr_Format(PyExc_ValueError,
4287 "%s: src and dst must be the same type", function_name);
4288 goto exit;
4289 }
4290
4291#ifdef MS_WINDOWS
4292 Py_BEGIN_ALLOW_THREADS
4293 if (src.wide)
4294 result = MoveFileExW(src.wide, dst.wide, flags);
4295 else
4296 result = MoveFileExA(src.narrow, dst.narrow, flags);
4297 Py_END_ALLOW_THREADS
4298
4299 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08004300 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004301 goto exit;
4302 }
4303
4304#else
4305 Py_BEGIN_ALLOW_THREADS
4306#ifdef HAVE_RENAMEAT
4307 if (dir_fd_specified)
4308 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4309 else
4310#endif
4311 result = rename(src.narrow, dst.narrow);
4312 Py_END_ALLOW_THREADS
4313
4314 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08004315 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004316 goto exit;
4317 }
4318#endif
4319
4320 Py_INCREF(Py_None);
4321 return_value = Py_None;
4322exit:
4323 path_cleanup(&src);
4324 path_cleanup(&dst);
4325 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004326}
4327
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004328PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004329"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4330Rename a file or directory.\n\
4331\n\
4332If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4333 descriptor open to a directory, and the respective path string (src or dst)\n\
4334 should be relative; the path will then be relative to that directory.\n\
4335src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4336 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004337
4338static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004339posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004340{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004341 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004342}
4343
4344PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004345"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4346Rename a file or directory, overwriting the destination.\n\
4347\n\
4348If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4349 descriptor open to a directory, and the respective path string (src or dst)\n\
4350 should be relative; the path will then be relative to that directory.\n\
4351src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4352 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004353
4354static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004355posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004356{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004357 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004358}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004359
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004360PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004361"rmdir(path, *, dir_fd=None)\n\n\
4362Remove a directory.\n\
4363\n\
4364If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4365 and path should be relative; path will then be relative to that directory.\n\
4366dir_fd may not be implemented on your platform.\n\
4367 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004368
Barry Warsaw53699e91996-12-10 23:23:01 +00004369static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004370posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004371{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004372 path_t path;
4373 int dir_fd = DEFAULT_DIR_FD;
4374 static char *keywords[] = {"path", "dir_fd", NULL};
4375 int result;
4376 PyObject *return_value = NULL;
4377
4378 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004379 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004380 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4381 path_converter, &path,
4382#ifdef HAVE_UNLINKAT
4383 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004384#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004385 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004386#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004387 ))
4388 return NULL;
4389
4390 Py_BEGIN_ALLOW_THREADS
4391#ifdef MS_WINDOWS
4392 if (path.wide)
4393 result = RemoveDirectoryW(path.wide);
4394 else
4395 result = RemoveDirectoryA(path.narrow);
4396 result = !result; /* Windows, success=1, UNIX, success=0 */
4397#else
4398#ifdef HAVE_UNLINKAT
4399 if (dir_fd != DEFAULT_DIR_FD)
4400 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4401 else
4402#endif
4403 result = rmdir(path.narrow);
4404#endif
4405 Py_END_ALLOW_THREADS
4406
4407 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004408 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004409 goto exit;
4410 }
4411
4412 return_value = Py_None;
4413 Py_INCREF(Py_None);
4414
4415exit:
4416 path_cleanup(&path);
4417 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004418}
4419
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004420
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004421#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004422PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004423"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004424Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004425
Barry Warsaw53699e91996-12-10 23:23:01 +00004426static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004427posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004428{
Victor Stinner8c62be82010-05-06 00:08:46 +00004429 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004430#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004431 wchar_t *command;
4432 if (!PyArg_ParseTuple(args, "u:system", &command))
4433 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004434
Victor Stinner8c62be82010-05-06 00:08:46 +00004435 Py_BEGIN_ALLOW_THREADS
4436 sts = _wsystem(command);
4437 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004438#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004439 PyObject *command_obj;
4440 char *command;
4441 if (!PyArg_ParseTuple(args, "O&:system",
4442 PyUnicode_FSConverter, &command_obj))
4443 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004444
Victor Stinner8c62be82010-05-06 00:08:46 +00004445 command = PyBytes_AsString(command_obj);
4446 Py_BEGIN_ALLOW_THREADS
4447 sts = system(command);
4448 Py_END_ALLOW_THREADS
4449 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004450#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004451 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004452}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004453#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004454
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004455
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004456PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004457"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004458Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004459
Barry Warsaw53699e91996-12-10 23:23:01 +00004460static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004461posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004462{
Victor Stinner8c62be82010-05-06 00:08:46 +00004463 int i;
4464 if (!PyArg_ParseTuple(args, "i:umask", &i))
4465 return NULL;
4466 i = (int)umask(i);
4467 if (i < 0)
4468 return posix_error();
4469 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004470}
4471
Brian Curtind40e6f72010-07-08 21:39:08 +00004472#ifdef MS_WINDOWS
4473
4474/* override the default DeleteFileW behavior so that directory
4475symlinks can be removed with this function, the same as with
4476Unix symlinks */
4477BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4478{
4479 WIN32_FILE_ATTRIBUTE_DATA info;
4480 WIN32_FIND_DATAW find_data;
4481 HANDLE find_data_handle;
4482 int is_directory = 0;
4483 int is_link = 0;
4484
4485 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4486 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004487
Brian Curtind40e6f72010-07-08 21:39:08 +00004488 /* Get WIN32_FIND_DATA structure for the path to determine if
4489 it is a symlink */
4490 if(is_directory &&
4491 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4492 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4493
4494 if(find_data_handle != INVALID_HANDLE_VALUE) {
4495 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4496 FindClose(find_data_handle);
4497 }
4498 }
4499 }
4500
4501 if (is_directory && is_link)
4502 return RemoveDirectoryW(lpFileName);
4503
4504 return DeleteFileW(lpFileName);
4505}
4506#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004507
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004508PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004509"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004510Remove a file (same as remove()).\n\
4511\n\
4512If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4513 and path should be relative; path will then be relative to that directory.\n\
4514dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004515 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004517PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004518"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004519Remove a file (same as unlink()).\n\
4520\n\
4521If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4522 and path should be relative; path will then be relative to that directory.\n\
4523dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004524 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004525
Barry Warsaw53699e91996-12-10 23:23:01 +00004526static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004527posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004528{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004529 path_t path;
4530 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004531 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004532 int result;
4533 PyObject *return_value = NULL;
4534
4535 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004536 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004537 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538 path_converter, &path,
4539#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004540 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004541#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004542 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004543#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004544 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004545 return NULL;
4546
4547 Py_BEGIN_ALLOW_THREADS
4548#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004549 if (path.wide)
4550 result = Py_DeleteFileW(path.wide);
4551 else
4552 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004553 result = !result; /* Windows, success=1, UNIX, success=0 */
4554#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004555#ifdef HAVE_UNLINKAT
4556 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004557 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004558 else
4559#endif /* HAVE_UNLINKAT */
4560 result = unlink(path.narrow);
4561#endif
4562 Py_END_ALLOW_THREADS
4563
4564 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004565 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004566 goto exit;
4567 }
4568
4569 return_value = Py_None;
4570 Py_INCREF(Py_None);
4571
4572exit:
4573 path_cleanup(&path);
4574 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004575}
4576
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004577
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004578PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004579"uname() -> uname_result\n\n\
4580Return an object identifying the current operating system.\n\
4581The object behaves like a named tuple with the following fields:\n\
4582 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004583
Larry Hastings605a62d2012-06-24 04:33:36 -07004584static PyStructSequence_Field uname_result_fields[] = {
4585 {"sysname", "operating system name"},
4586 {"nodename", "name of machine on network (implementation-defined)"},
4587 {"release", "operating system release"},
4588 {"version", "operating system version"},
4589 {"machine", "hardware identifier"},
4590 {NULL}
4591};
4592
4593PyDoc_STRVAR(uname_result__doc__,
4594"uname_result: Result from os.uname().\n\n\
4595This object may be accessed either as a tuple of\n\
4596 (sysname, nodename, release, version, machine),\n\
4597or via the attributes sysname, nodename, release, version, and machine.\n\
4598\n\
4599See os.uname for more information.");
4600
4601static PyStructSequence_Desc uname_result_desc = {
4602 "uname_result", /* name */
4603 uname_result__doc__, /* doc */
4604 uname_result_fields,
4605 5
4606};
4607
4608static PyTypeObject UnameResultType;
4609
4610
4611#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004612static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004613posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004614{
Victor Stinner8c62be82010-05-06 00:08:46 +00004615 struct utsname u;
4616 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004617 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004618
Victor Stinner8c62be82010-05-06 00:08:46 +00004619 Py_BEGIN_ALLOW_THREADS
4620 res = uname(&u);
4621 Py_END_ALLOW_THREADS
4622 if (res < 0)
4623 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004624
4625 value = PyStructSequence_New(&UnameResultType);
4626 if (value == NULL)
4627 return NULL;
4628
4629#define SET(i, field) \
4630 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004631 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004632 if (!o) { \
4633 Py_DECREF(value); \
4634 return NULL; \
4635 } \
4636 PyStructSequence_SET_ITEM(value, i, o); \
4637 } \
4638
4639 SET(0, u.sysname);
4640 SET(1, u.nodename);
4641 SET(2, u.release);
4642 SET(3, u.version);
4643 SET(4, u.machine);
4644
4645#undef SET
4646
4647 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004648}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004649#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004650
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004651
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652PyDoc_STRVAR(posix_utime__doc__,
4653"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4654Set the access and modified time of path.\n\
4655\n\
4656path may always be specified as a string.\n\
4657On some platforms, path may also be specified as an open file descriptor.\n\
4658 If this functionality is unavailable, using it raises an exception.\n\
4659\n\
4660If times is not None, it must be a tuple (atime, mtime);\n\
4661 atime and mtime should be expressed as float seconds since the epoch.\n\
4662If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4663 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4664 since the epoch.\n\
4665If both times and ns are None, utime uses the current time.\n\
4666Specifying tuples for both times and ns is an error.\n\
4667\n\
4668If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4669 and path should be relative; path will then be relative to that directory.\n\
4670If follow_symlinks is False, and the last element of the path is a symbolic\n\
4671 link, utime will modify the symbolic link itself instead of the file the\n\
4672 link points to.\n\
4673It is an error to use dir_fd or follow_symlinks when specifying path\n\
4674 as an open file descriptor.\n\
4675dir_fd and follow_symlinks may not be available on your platform.\n\
4676 If they are unavailable, using them will raise a NotImplementedError.");
4677
4678typedef struct {
4679 int now;
4680 time_t atime_s;
4681 long atime_ns;
4682 time_t mtime_s;
4683 long mtime_ns;
4684} utime_t;
4685
4686/*
Victor Stinner484df002014-10-09 13:52:31 +02004687 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004688 * they also intentionally leak the declaration of a pointer named "time"
4689 */
4690#define UTIME_TO_TIMESPEC \
4691 struct timespec ts[2]; \
4692 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004693 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004694 time = NULL; \
4695 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004696 ts[0].tv_sec = ut->atime_s; \
4697 ts[0].tv_nsec = ut->atime_ns; \
4698 ts[1].tv_sec = ut->mtime_s; \
4699 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004700 time = ts; \
4701 } \
4702
4703#define UTIME_TO_TIMEVAL \
4704 struct timeval tv[2]; \
4705 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004706 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004707 time = NULL; \
4708 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004709 tv[0].tv_sec = ut->atime_s; \
4710 tv[0].tv_usec = ut->atime_ns / 1000; \
4711 tv[1].tv_sec = ut->mtime_s; \
4712 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004713 time = tv; \
4714 } \
4715
4716#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004717 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004718 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004719 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004720 time = NULL; \
4721 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004722 u.actime = ut->atime_s; \
4723 u.modtime = ut->mtime_s; \
4724 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004725 }
4726
4727#define UTIME_TO_TIME_T \
4728 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004729 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004730 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004731 time = NULL; \
4732 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004733 timet[0] = ut->atime_s; \
4734 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004735 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004736 } \
4737
4738
4739#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4740
4741#if UTIME_HAVE_DIR_FD
4742
4743static int
Victor Stinner484df002014-10-09 13:52:31 +02004744utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745{
4746#ifdef HAVE_UTIMENSAT
4747 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4748 UTIME_TO_TIMESPEC;
4749 return utimensat(dir_fd, path, time, flags);
4750#elif defined(HAVE_FUTIMESAT)
4751 UTIME_TO_TIMEVAL;
4752 /*
4753 * follow_symlinks will never be false here;
4754 * we only allow !follow_symlinks and dir_fd together
4755 * if we have utimensat()
4756 */
4757 assert(follow_symlinks);
4758 return futimesat(dir_fd, path, time);
4759#endif
4760}
4761
4762#endif
4763
4764#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4765
4766#if UTIME_HAVE_FD
4767
4768static int
Victor Stinner484df002014-10-09 13:52:31 +02004769utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770{
4771#ifdef HAVE_FUTIMENS
4772 UTIME_TO_TIMESPEC;
4773 return futimens(fd, time);
4774#else
4775 UTIME_TO_TIMEVAL;
4776 return futimes(fd, time);
4777#endif
4778}
4779
4780#endif
4781
4782
4783#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4784 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4785
4786#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4787
4788static int
Victor Stinner484df002014-10-09 13:52:31 +02004789utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004790{
4791#ifdef HAVE_UTIMENSAT
4792 UTIME_TO_TIMESPEC;
4793 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4794#else
4795 UTIME_TO_TIMEVAL;
4796 return lutimes(path, time);
4797#endif
4798}
4799
4800#endif
4801
4802#ifndef MS_WINDOWS
4803
4804static int
Victor Stinner484df002014-10-09 13:52:31 +02004805utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004806{
4807#ifdef HAVE_UTIMENSAT
4808 UTIME_TO_TIMESPEC;
4809 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4810#elif defined(HAVE_UTIMES)
4811 UTIME_TO_TIMEVAL;
4812 return utimes(path, time);
4813#elif defined(HAVE_UTIME_H)
4814 UTIME_TO_UTIMBUF;
4815 return utime(path, time);
4816#else
4817 UTIME_TO_TIME_T;
4818 return utime(path, time);
4819#endif
4820}
4821
4822#endif
4823
Larry Hastings76ad59b2012-05-03 00:30:07 -07004824static int
4825split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4826{
4827 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004828 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004829 divmod = PyNumber_Divmod(py_long, billion);
4830 if (!divmod)
4831 goto exit;
4832 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4833 if ((*s == -1) && PyErr_Occurred())
4834 goto exit;
4835 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004836 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004837 goto exit;
4838
4839 result = 1;
4840exit:
4841 Py_XDECREF(divmod);
4842 return result;
4843}
4844
Larry Hastings9cf065c2012-06-22 16:30:09 -07004845static PyObject *
4846posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004847{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004848 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004849 PyObject *times = NULL;
4850 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004851 int dir_fd = DEFAULT_DIR_FD;
4852 int follow_symlinks = 1;
4853 char *keywords[] = {"path", "times", "ns", "dir_fd",
4854 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004855
Larry Hastings9cf065c2012-06-22 16:30:09 -07004856 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004857
Larry Hastings9cf065c2012-06-22 16:30:09 -07004858#ifdef MS_WINDOWS
4859 HANDLE hFile;
4860 FILETIME atime, mtime;
4861#else
4862 int result;
4863#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004864
Larry Hastings9cf065c2012-06-22 16:30:09 -07004865 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004866
Larry Hastings9cf065c2012-06-22 16:30:09 -07004867 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004868 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004869 memset(&utime, 0, sizeof(utime_t));
Larry Hastings9cf065c2012-06-22 16:30:09 -07004870#if UTIME_HAVE_FD
4871 path.allow_fd = 1;
4872#endif
4873 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4874 "O&|O$OO&p:utime", keywords,
4875 path_converter, &path,
4876 &times, &ns,
4877#if UTIME_HAVE_DIR_FD
4878 dir_fd_converter, &dir_fd,
4879#else
4880 dir_fd_unavailable, &dir_fd,
4881#endif
4882 &follow_symlinks
4883 ))
4884 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004885
Larry Hastings9cf065c2012-06-22 16:30:09 -07004886 if (times && (times != Py_None) && ns) {
4887 PyErr_SetString(PyExc_ValueError,
4888 "utime: you may specify either 'times'"
4889 " or 'ns' but not both");
4890 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004891 }
4892
4893 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004894 time_t a_sec, m_sec;
4895 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004896 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004897 PyErr_SetString(PyExc_TypeError,
4898 "utime: 'times' must be either"
4899 " a tuple of two ints or None");
4900 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004901 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004902 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004903 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004904 &a_sec, &a_nsec, _PyTime_ROUND_DOWN) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004905 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004906 &m_sec, &m_nsec, _PyTime_ROUND_DOWN) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004907 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004908 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004909 utime.atime_s = a_sec;
4910 utime.atime_ns = a_nsec;
4911 utime.mtime_s = m_sec;
4912 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004913 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004914 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004915 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004916 PyErr_SetString(PyExc_TypeError,
4917 "utime: 'ns' must be a tuple of two ints");
4918 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004919 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004920 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004921 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004922 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004923 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004924 &utime.mtime_s, &utime.mtime_ns)) {
4925 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004926 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004927 }
4928 else {
4929 /* times and ns are both None/unspecified. use "now". */
4930 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004931 }
4932
Larry Hastings9cf065c2012-06-22 16:30:09 -07004933#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4934 if (follow_symlinks_specified("utime", follow_symlinks))
4935 goto exit;
4936#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004937
Larry Hastings9cf065c2012-06-22 16:30:09 -07004938 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4939 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4940 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4941 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004942
Larry Hastings9cf065c2012-06-22 16:30:09 -07004943#if !defined(HAVE_UTIMENSAT)
4944 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004945 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004946 "utime: cannot use dir_fd and follow_symlinks "
4947 "together on this platform");
4948 goto exit;
4949 }
4950#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004951
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004952#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004953 Py_BEGIN_ALLOW_THREADS
4954 if (path.wide)
4955 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004956 NULL, OPEN_EXISTING,
4957 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004958 else
4959 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004960 NULL, OPEN_EXISTING,
4961 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004962 Py_END_ALLOW_THREADS
4963 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004964 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004965 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004966 }
4967
Larry Hastings9cf065c2012-06-22 16:30:09 -07004968 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004969 GetSystemTimeAsFileTime(&mtime);
4970 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004971 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004972 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004973 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4974 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 }
4976 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4977 /* Avoid putting the file name into the error here,
4978 as that may confuse the user into believing that
4979 something is wrong with the file, when it also
4980 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004981 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004982 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004983 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004984#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004986
Larry Hastings9cf065c2012-06-22 16:30:09 -07004987#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4988 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4989 result = utime_nofollow_symlinks(&utime, path.narrow);
4990 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004991#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004992
4993#if UTIME_HAVE_DIR_FD
4994 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4995 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4996 else
4997#endif
4998
4999#if UTIME_HAVE_FD
5000 if (path.fd != -1)
5001 result = utime_fd(&utime, path.fd);
5002 else
5003#endif
5004
5005 result = utime_default(&utime, path.narrow);
5006
5007 Py_END_ALLOW_THREADS
5008
5009 if (result < 0) {
5010 /* see previous comment about not putting filename in error here */
5011 return_value = posix_error();
5012 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005013 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005014
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005015#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005016
5017 Py_INCREF(Py_None);
5018 return_value = Py_None;
5019
5020exit:
5021 path_cleanup(&path);
5022#ifdef MS_WINDOWS
5023 if (hFile != INVALID_HANDLE_VALUE)
5024 CloseHandle(hFile);
5025#endif
5026 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005027}
5028
Guido van Rossum3b066191991-06-04 19:40:25 +00005029/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005030
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005031PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005032"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005033Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005034
Barry Warsaw53699e91996-12-10 23:23:01 +00005035static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005036posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005037{
Victor Stinner8c62be82010-05-06 00:08:46 +00005038 int sts;
5039 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5040 return NULL;
5041 _exit(sts);
5042 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005043}
5044
Martin v. Löwis114619e2002-10-07 06:44:21 +00005045#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5046static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00005047free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005048{
Victor Stinner8c62be82010-05-06 00:08:46 +00005049 Py_ssize_t i;
5050 for (i = 0; i < count; i++)
5051 PyMem_Free(array[i]);
5052 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005053}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005054
Antoine Pitrou69f71142009-05-24 21:25:49 +00005055static
Martin v. Löwis011e8422009-05-05 04:43:17 +00005056int fsconvert_strdup(PyObject *o, char**out)
5057{
Victor Stinner8c62be82010-05-06 00:08:46 +00005058 PyObject *bytes;
5059 Py_ssize_t size;
5060 if (!PyUnicode_FSConverter(o, &bytes))
5061 return 0;
5062 size = PyBytes_GET_SIZE(bytes);
5063 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01005064 if (!*out) {
5065 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00005066 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01005067 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005068 memcpy(*out, PyBytes_AsString(bytes), size+1);
5069 Py_DECREF(bytes);
5070 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005071}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005072#endif
5073
Ross Lagerwall7807c352011-03-17 20:20:30 +02005074#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005075static char**
5076parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5077{
Victor Stinner8c62be82010-05-06 00:08:46 +00005078 char **envlist;
5079 Py_ssize_t i, pos, envc;
5080 PyObject *keys=NULL, *vals=NULL;
5081 PyObject *key, *val, *key2, *val2;
5082 char *p, *k, *v;
5083 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005084
Victor Stinner8c62be82010-05-06 00:08:46 +00005085 i = PyMapping_Size(env);
5086 if (i < 0)
5087 return NULL;
5088 envlist = PyMem_NEW(char *, i + 1);
5089 if (envlist == NULL) {
5090 PyErr_NoMemory();
5091 return NULL;
5092 }
5093 envc = 0;
5094 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005095 if (!keys)
5096 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005097 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005098 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005099 goto error;
5100 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5101 PyErr_Format(PyExc_TypeError,
5102 "env.keys() or env.values() is not a list");
5103 goto error;
5104 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005105
Victor Stinner8c62be82010-05-06 00:08:46 +00005106 for (pos = 0; pos < i; pos++) {
5107 key = PyList_GetItem(keys, pos);
5108 val = PyList_GetItem(vals, pos);
5109 if (!key || !val)
5110 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005111
Victor Stinner8c62be82010-05-06 00:08:46 +00005112 if (PyUnicode_FSConverter(key, &key2) == 0)
5113 goto error;
5114 if (PyUnicode_FSConverter(val, &val2) == 0) {
5115 Py_DECREF(key2);
5116 goto error;
5117 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005118
Victor Stinner8c62be82010-05-06 00:08:46 +00005119 k = PyBytes_AsString(key2);
5120 v = PyBytes_AsString(val2);
5121 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005122
Victor Stinner8c62be82010-05-06 00:08:46 +00005123 p = PyMem_NEW(char, len);
5124 if (p == NULL) {
5125 PyErr_NoMemory();
5126 Py_DECREF(key2);
5127 Py_DECREF(val2);
5128 goto error;
5129 }
5130 PyOS_snprintf(p, len, "%s=%s", k, v);
5131 envlist[envc++] = p;
5132 Py_DECREF(key2);
5133 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005134 }
5135 Py_DECREF(vals);
5136 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005137
Victor Stinner8c62be82010-05-06 00:08:46 +00005138 envlist[envc] = 0;
5139 *envc_ptr = envc;
5140 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005141
5142error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005143 Py_XDECREF(keys);
5144 Py_XDECREF(vals);
5145 while (--envc >= 0)
5146 PyMem_DEL(envlist[envc]);
5147 PyMem_DEL(envlist);
5148 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005149}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005150
Ross Lagerwall7807c352011-03-17 20:20:30 +02005151static char**
5152parse_arglist(PyObject* argv, Py_ssize_t *argc)
5153{
5154 int i;
5155 char **argvlist = PyMem_NEW(char *, *argc+1);
5156 if (argvlist == NULL) {
5157 PyErr_NoMemory();
5158 return NULL;
5159 }
5160 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005161 PyObject* item = PySequence_ITEM(argv, i);
5162 if (item == NULL)
5163 goto fail;
5164 if (!fsconvert_strdup(item, &argvlist[i])) {
5165 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005166 goto fail;
5167 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005168 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005169 }
5170 argvlist[*argc] = NULL;
5171 return argvlist;
5172fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005173 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005174 free_string_array(argvlist, *argc);
5175 return NULL;
5176}
5177#endif
5178
5179#ifdef HAVE_EXECV
5180PyDoc_STRVAR(posix_execv__doc__,
5181"execv(path, args)\n\n\
5182Execute an executable path with arguments, replacing current process.\n\
5183\n\
5184 path: path of executable file\n\
5185 args: tuple or list of strings");
5186
5187static PyObject *
5188posix_execv(PyObject *self, PyObject *args)
5189{
5190 PyObject *opath;
5191 char *path;
5192 PyObject *argv;
5193 char **argvlist;
5194 Py_ssize_t argc;
5195
5196 /* execv has two arguments: (path, argv), where
5197 argv is a list or tuple of strings. */
5198
5199 if (!PyArg_ParseTuple(args, "O&O:execv",
5200 PyUnicode_FSConverter,
5201 &opath, &argv))
5202 return NULL;
5203 path = PyBytes_AsString(opath);
5204 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5205 PyErr_SetString(PyExc_TypeError,
5206 "execv() arg 2 must be a tuple or list");
5207 Py_DECREF(opath);
5208 return NULL;
5209 }
5210 argc = PySequence_Size(argv);
5211 if (argc < 1) {
5212 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5213 Py_DECREF(opath);
5214 return NULL;
5215 }
5216
5217 argvlist = parse_arglist(argv, &argc);
5218 if (argvlist == NULL) {
5219 Py_DECREF(opath);
5220 return NULL;
5221 }
5222
5223 execv(path, argvlist);
5224
5225 /* If we get here it's definitely an error */
5226
5227 free_string_array(argvlist, argc);
5228 Py_DECREF(opath);
5229 return posix_error();
5230}
5231
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005232PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005233"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005234Execute a path with arguments and environment, replacing current process.\n\
5235\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005236 path: path of executable file\n\
5237 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005238 env: dictionary of strings mapping to strings\n\
5239\n\
5240On some platforms, you may specify an open file descriptor for path;\n\
5241 execve will execute the program the file descriptor is open to.\n\
5242 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005243
Barry Warsaw53699e91996-12-10 23:23:01 +00005244static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005245posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005246{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005247 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005248 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005249 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005250 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005251 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005252 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005253
Victor Stinner8c62be82010-05-06 00:08:46 +00005254 /* execve has three arguments: (path, argv, env), where
5255 argv is a list or tuple of strings and env is a dictionary
5256 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005257
Larry Hastings9cf065c2012-06-22 16:30:09 -07005258 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005259 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005260#ifdef HAVE_FEXECVE
5261 path.allow_fd = 1;
5262#endif
5263 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5264 path_converter, &path,
5265 &argv, &env
5266 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005267 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005268
Ross Lagerwall7807c352011-03-17 20:20:30 +02005269 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005270 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005271 "execve: argv must be a tuple or list");
5272 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005273 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005274 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005275 if (!PyMapping_Check(env)) {
5276 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005277 "execve: environment must be a mapping object");
5278 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005279 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005280
Ross Lagerwall7807c352011-03-17 20:20:30 +02005281 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005282 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005283 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005284 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005285
Victor Stinner8c62be82010-05-06 00:08:46 +00005286 envlist = parse_envlist(env, &envc);
5287 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005288 goto fail;
5289
Larry Hastings9cf065c2012-06-22 16:30:09 -07005290#ifdef HAVE_FEXECVE
5291 if (path.fd > -1)
5292 fexecve(path.fd, argvlist, envlist);
5293 else
5294#endif
5295 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005296
5297 /* If we get here it's definitely an error */
5298
Victor Stinner292c8352012-10-30 02:17:38 +01005299 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005300
5301 while (--envc >= 0)
5302 PyMem_DEL(envlist[envc]);
5303 PyMem_DEL(envlist);
5304 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005305 if (argvlist)
5306 free_string_array(argvlist, argc);
5307 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005308 return NULL;
5309}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005310#endif /* HAVE_EXECV */
5311
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005312
Guido van Rossuma1065681999-01-25 23:20:23 +00005313#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005314PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005315"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005316Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005317\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005318 mode: mode of process creation\n\
5319 path: path of executable file\n\
5320 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005321
5322static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005323posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005324{
Victor Stinner8c62be82010-05-06 00:08:46 +00005325 PyObject *opath;
5326 char *path;
5327 PyObject *argv;
5328 char **argvlist;
5329 int mode, i;
5330 Py_ssize_t argc;
5331 Py_intptr_t spawnval;
5332 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005333
Victor Stinner8c62be82010-05-06 00:08:46 +00005334 /* spawnv has three arguments: (mode, path, argv), where
5335 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005336
Victor Stinner8c62be82010-05-06 00:08:46 +00005337 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5338 PyUnicode_FSConverter,
5339 &opath, &argv))
5340 return NULL;
5341 path = PyBytes_AsString(opath);
5342 if (PyList_Check(argv)) {
5343 argc = PyList_Size(argv);
5344 getitem = PyList_GetItem;
5345 }
5346 else if (PyTuple_Check(argv)) {
5347 argc = PyTuple_Size(argv);
5348 getitem = PyTuple_GetItem;
5349 }
5350 else {
5351 PyErr_SetString(PyExc_TypeError,
5352 "spawnv() arg 2 must be a tuple or list");
5353 Py_DECREF(opath);
5354 return NULL;
5355 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005356
Victor Stinner8c62be82010-05-06 00:08:46 +00005357 argvlist = PyMem_NEW(char *, argc+1);
5358 if (argvlist == NULL) {
5359 Py_DECREF(opath);
5360 return PyErr_NoMemory();
5361 }
5362 for (i = 0; i < argc; i++) {
5363 if (!fsconvert_strdup((*getitem)(argv, i),
5364 &argvlist[i])) {
5365 free_string_array(argvlist, i);
5366 PyErr_SetString(
5367 PyExc_TypeError,
5368 "spawnv() arg 2 must contain only strings");
5369 Py_DECREF(opath);
5370 return NULL;
5371 }
5372 }
5373 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005374
Victor Stinner8c62be82010-05-06 00:08:46 +00005375 if (mode == _OLD_P_OVERLAY)
5376 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005377
Victor Stinner8c62be82010-05-06 00:08:46 +00005378 Py_BEGIN_ALLOW_THREADS
5379 spawnval = _spawnv(mode, path, argvlist);
5380 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005381
Victor Stinner8c62be82010-05-06 00:08:46 +00005382 free_string_array(argvlist, argc);
5383 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005384
Victor Stinner8c62be82010-05-06 00:08:46 +00005385 if (spawnval == -1)
5386 return posix_error();
5387 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005388 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005389}
5390
5391
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005392PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005393"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005394Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005395\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005396 mode: mode of process creation\n\
5397 path: path of executable file\n\
5398 args: tuple or list of arguments\n\
5399 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005400
5401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005402posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005403{
Victor Stinner8c62be82010-05-06 00:08:46 +00005404 PyObject *opath;
5405 char *path;
5406 PyObject *argv, *env;
5407 char **argvlist;
5408 char **envlist;
5409 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005410 int mode;
5411 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005412 Py_intptr_t spawnval;
5413 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5414 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005415
Victor Stinner8c62be82010-05-06 00:08:46 +00005416 /* spawnve has four arguments: (mode, path, argv, env), where
5417 argv is a list or tuple of strings and env is a dictionary
5418 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005419
Victor Stinner8c62be82010-05-06 00:08:46 +00005420 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5421 PyUnicode_FSConverter,
5422 &opath, &argv, &env))
5423 return NULL;
5424 path = PyBytes_AsString(opath);
5425 if (PyList_Check(argv)) {
5426 argc = PyList_Size(argv);
5427 getitem = PyList_GetItem;
5428 }
5429 else if (PyTuple_Check(argv)) {
5430 argc = PyTuple_Size(argv);
5431 getitem = PyTuple_GetItem;
5432 }
5433 else {
5434 PyErr_SetString(PyExc_TypeError,
5435 "spawnve() arg 2 must be a tuple or list");
5436 goto fail_0;
5437 }
5438 if (!PyMapping_Check(env)) {
5439 PyErr_SetString(PyExc_TypeError,
5440 "spawnve() arg 3 must be a mapping object");
5441 goto fail_0;
5442 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005443
Victor Stinner8c62be82010-05-06 00:08:46 +00005444 argvlist = PyMem_NEW(char *, argc+1);
5445 if (argvlist == NULL) {
5446 PyErr_NoMemory();
5447 goto fail_0;
5448 }
5449 for (i = 0; i < argc; i++) {
5450 if (!fsconvert_strdup((*getitem)(argv, i),
5451 &argvlist[i]))
5452 {
5453 lastarg = i;
5454 goto fail_1;
5455 }
5456 }
5457 lastarg = argc;
5458 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005459
Victor Stinner8c62be82010-05-06 00:08:46 +00005460 envlist = parse_envlist(env, &envc);
5461 if (envlist == NULL)
5462 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005463
Victor Stinner8c62be82010-05-06 00:08:46 +00005464 if (mode == _OLD_P_OVERLAY)
5465 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005466
Victor Stinner8c62be82010-05-06 00:08:46 +00005467 Py_BEGIN_ALLOW_THREADS
5468 spawnval = _spawnve(mode, path, argvlist, envlist);
5469 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005470
Victor Stinner8c62be82010-05-06 00:08:46 +00005471 if (spawnval == -1)
5472 (void) posix_error();
5473 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005474 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005475
Victor Stinner8c62be82010-05-06 00:08:46 +00005476 while (--envc >= 0)
5477 PyMem_DEL(envlist[envc]);
5478 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005479 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005480 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005481 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005482 Py_DECREF(opath);
5483 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005484}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005485
Guido van Rossuma1065681999-01-25 23:20:23 +00005486#endif /* HAVE_SPAWNV */
5487
5488
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005489#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005490PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005491"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005492Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5493\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005494Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005495
5496static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005497posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005498{
Victor Stinner8c62be82010-05-06 00:08:46 +00005499 pid_t pid;
5500 int result = 0;
5501 _PyImport_AcquireLock();
5502 pid = fork1();
5503 if (pid == 0) {
5504 /* child: this clobbers and resets the import lock. */
5505 PyOS_AfterFork();
5506 } else {
5507 /* parent: release the import lock. */
5508 result = _PyImport_ReleaseLock();
5509 }
5510 if (pid == -1)
5511 return posix_error();
5512 if (result < 0) {
5513 /* Don't clobber the OSError if the fork failed. */
5514 PyErr_SetString(PyExc_RuntimeError,
5515 "not holding the import lock");
5516 return NULL;
5517 }
5518 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005519}
5520#endif
5521
5522
Guido van Rossumad0ee831995-03-01 10:34:45 +00005523#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005524PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005525"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005526Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005527Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005528
Barry Warsaw53699e91996-12-10 23:23:01 +00005529static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005530posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005531{
Victor Stinner8c62be82010-05-06 00:08:46 +00005532 pid_t pid;
5533 int result = 0;
5534 _PyImport_AcquireLock();
5535 pid = fork();
5536 if (pid == 0) {
5537 /* child: this clobbers and resets the import lock. */
5538 PyOS_AfterFork();
5539 } else {
5540 /* parent: release the import lock. */
5541 result = _PyImport_ReleaseLock();
5542 }
5543 if (pid == -1)
5544 return posix_error();
5545 if (result < 0) {
5546 /* Don't clobber the OSError if the fork failed. */
5547 PyErr_SetString(PyExc_RuntimeError,
5548 "not holding the import lock");
5549 return NULL;
5550 }
5551 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005552}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005553#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005554
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005555#ifdef HAVE_SCHED_H
5556
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005557#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5558
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005559PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5560"sched_get_priority_max(policy)\n\n\
5561Get the maximum scheduling priority for *policy*.");
5562
5563static PyObject *
5564posix_sched_get_priority_max(PyObject *self, PyObject *args)
5565{
5566 int policy, max;
5567
5568 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5569 return NULL;
5570 max = sched_get_priority_max(policy);
5571 if (max < 0)
5572 return posix_error();
5573 return PyLong_FromLong(max);
5574}
5575
5576PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5577"sched_get_priority_min(policy)\n\n\
5578Get the minimum scheduling priority for *policy*.");
5579
5580static PyObject *
5581posix_sched_get_priority_min(PyObject *self, PyObject *args)
5582{
5583 int policy, min;
5584
5585 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5586 return NULL;
5587 min = sched_get_priority_min(policy);
5588 if (min < 0)
5589 return posix_error();
5590 return PyLong_FromLong(min);
5591}
5592
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005593#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5594
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005595#ifdef HAVE_SCHED_SETSCHEDULER
5596
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005597PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5598"sched_getscheduler(pid)\n\n\
5599Get the scheduling policy for the process with a PID of *pid*.\n\
5600Passing a PID of 0 returns the scheduling policy for the calling process.");
5601
5602static PyObject *
5603posix_sched_getscheduler(PyObject *self, PyObject *args)
5604{
5605 pid_t pid;
5606 int policy;
5607
5608 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5609 return NULL;
5610 policy = sched_getscheduler(pid);
5611 if (policy < 0)
5612 return posix_error();
5613 return PyLong_FromLong(policy);
5614}
5615
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005616#endif
5617
5618#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5619
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005620static PyObject *
5621sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5622{
5623 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005624 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005625
5626 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5627 return NULL;
5628 res = PyStructSequence_New(type);
5629 if (!res)
5630 return NULL;
5631 Py_INCREF(priority);
5632 PyStructSequence_SET_ITEM(res, 0, priority);
5633 return res;
5634}
5635
5636PyDoc_STRVAR(sched_param__doc__,
5637"sched_param(sched_priority): A scheduling parameter.\n\n\
5638Current has only one field: sched_priority");
5639
5640static PyStructSequence_Field sched_param_fields[] = {
5641 {"sched_priority", "the scheduling priority"},
5642 {0}
5643};
5644
5645static PyStructSequence_Desc sched_param_desc = {
5646 "sched_param", /* name */
5647 sched_param__doc__, /* doc */
5648 sched_param_fields,
5649 1
5650};
5651
5652static int
5653convert_sched_param(PyObject *param, struct sched_param *res)
5654{
5655 long priority;
5656
5657 if (Py_TYPE(param) != &SchedParamType) {
5658 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5659 return 0;
5660 }
5661 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5662 if (priority == -1 && PyErr_Occurred())
5663 return 0;
5664 if (priority > INT_MAX || priority < INT_MIN) {
5665 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5666 return 0;
5667 }
5668 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5669 return 1;
5670}
5671
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005672#endif
5673
5674#ifdef HAVE_SCHED_SETSCHEDULER
5675
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005676PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5677"sched_setscheduler(pid, policy, param)\n\n\
5678Set the scheduling policy, *policy*, for *pid*.\n\
5679If *pid* is 0, the calling process is changed.\n\
5680*param* is an instance of sched_param.");
5681
5682static PyObject *
5683posix_sched_setscheduler(PyObject *self, PyObject *args)
5684{
5685 pid_t pid;
5686 int policy;
5687 struct sched_param param;
5688
5689 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5690 &pid, &policy, &convert_sched_param, &param))
5691 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005692
5693 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005694 ** sched_setscheduler() returns 0 in Linux, but the previous
5695 ** scheduling policy under Solaris/Illumos, and others.
5696 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005697 */
5698 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005699 return posix_error();
5700 Py_RETURN_NONE;
5701}
5702
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005703#endif
5704
5705#ifdef HAVE_SCHED_SETPARAM
5706
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005707PyDoc_STRVAR(posix_sched_getparam__doc__,
5708"sched_getparam(pid) -> sched_param\n\n\
5709Returns scheduling parameters for the process with *pid* as an instance of the\n\
5710sched_param class. A PID of 0 means the calling process.");
5711
5712static PyObject *
5713posix_sched_getparam(PyObject *self, PyObject *args)
5714{
5715 pid_t pid;
5716 struct sched_param param;
5717 PyObject *res, *priority;
5718
5719 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5720 return NULL;
5721 if (sched_getparam(pid, &param))
5722 return posix_error();
5723 res = PyStructSequence_New(&SchedParamType);
5724 if (!res)
5725 return NULL;
5726 priority = PyLong_FromLong(param.sched_priority);
5727 if (!priority) {
5728 Py_DECREF(res);
5729 return NULL;
5730 }
5731 PyStructSequence_SET_ITEM(res, 0, priority);
5732 return res;
5733}
5734
5735PyDoc_STRVAR(posix_sched_setparam__doc__,
5736"sched_setparam(pid, param)\n\n\
5737Set scheduling parameters for a process with PID *pid*.\n\
5738A PID of 0 means the calling process.");
5739
5740static PyObject *
5741posix_sched_setparam(PyObject *self, PyObject *args)
5742{
5743 pid_t pid;
5744 struct sched_param param;
5745
5746 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5747 &pid, &convert_sched_param, &param))
5748 return NULL;
5749 if (sched_setparam(pid, &param))
5750 return posix_error();
5751 Py_RETURN_NONE;
5752}
5753
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005754#endif
5755
5756#ifdef HAVE_SCHED_RR_GET_INTERVAL
5757
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005758PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5759"sched_rr_get_interval(pid) -> float\n\n\
5760Return the round-robin quantum for the process with PID *pid* in seconds.");
5761
5762static PyObject *
5763posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5764{
5765 pid_t pid;
5766 struct timespec interval;
5767
5768 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5769 return NULL;
5770 if (sched_rr_get_interval(pid, &interval))
5771 return posix_error();
5772 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5773}
5774
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005775#endif
5776
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005777PyDoc_STRVAR(posix_sched_yield__doc__,
5778"sched_yield()\n\n\
5779Voluntarily relinquish the CPU.");
5780
5781static PyObject *
5782posix_sched_yield(PyObject *self, PyObject *noargs)
5783{
5784 if (sched_yield())
5785 return posix_error();
5786 Py_RETURN_NONE;
5787}
5788
Benjamin Peterson2740af82011-08-02 17:41:34 -05005789#ifdef HAVE_SCHED_SETAFFINITY
5790
Antoine Pitrou84869872012-08-04 16:16:35 +02005791/* The minimum number of CPUs allocated in a cpu_set_t */
5792static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005793
5794PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5795"sched_setaffinity(pid, cpu_set)\n\n\
5796Set the affinity of the process with PID *pid* to *cpu_set*.");
5797
5798static PyObject *
5799posix_sched_setaffinity(PyObject *self, PyObject *args)
5800{
5801 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005802 int ncpus;
5803 size_t setsize;
5804 cpu_set_t *mask = NULL;
5805 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005806
Antoine Pitrou84869872012-08-04 16:16:35 +02005807 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5808 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005809 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005810
5811 iterator = PyObject_GetIter(iterable);
5812 if (iterator == NULL)
5813 return NULL;
5814
5815 ncpus = NCPUS_START;
5816 setsize = CPU_ALLOC_SIZE(ncpus);
5817 mask = CPU_ALLOC(ncpus);
5818 if (mask == NULL) {
5819 PyErr_NoMemory();
5820 goto error;
5821 }
5822 CPU_ZERO_S(setsize, mask);
5823
5824 while ((item = PyIter_Next(iterator))) {
5825 long cpu;
5826 if (!PyLong_Check(item)) {
5827 PyErr_Format(PyExc_TypeError,
5828 "expected an iterator of ints, "
5829 "but iterator yielded %R",
5830 Py_TYPE(item));
5831 Py_DECREF(item);
5832 goto error;
5833 }
5834 cpu = PyLong_AsLong(item);
5835 Py_DECREF(item);
5836 if (cpu < 0) {
5837 if (!PyErr_Occurred())
5838 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5839 goto error;
5840 }
5841 if (cpu > INT_MAX - 1) {
5842 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5843 goto error;
5844 }
5845 if (cpu >= ncpus) {
5846 /* Grow CPU mask to fit the CPU number */
5847 int newncpus = ncpus;
5848 cpu_set_t *newmask;
5849 size_t newsetsize;
5850 while (newncpus <= cpu) {
5851 if (newncpus > INT_MAX / 2)
5852 newncpus = cpu + 1;
5853 else
5854 newncpus = newncpus * 2;
5855 }
5856 newmask = CPU_ALLOC(newncpus);
5857 if (newmask == NULL) {
5858 PyErr_NoMemory();
5859 goto error;
5860 }
5861 newsetsize = CPU_ALLOC_SIZE(newncpus);
5862 CPU_ZERO_S(newsetsize, newmask);
5863 memcpy(newmask, mask, setsize);
5864 CPU_FREE(mask);
5865 setsize = newsetsize;
5866 mask = newmask;
5867 ncpus = newncpus;
5868 }
5869 CPU_SET_S(cpu, setsize, mask);
5870 }
5871 Py_CLEAR(iterator);
5872
5873 if (sched_setaffinity(pid, setsize, mask)) {
5874 posix_error();
5875 goto error;
5876 }
5877 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005878 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005879
5880error:
5881 if (mask)
5882 CPU_FREE(mask);
5883 Py_XDECREF(iterator);
5884 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005885}
5886
5887PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5888"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5889Return the affinity of the process with PID *pid*.\n\
5890The returned cpu_set will be of size *ncpus*.");
5891
5892static PyObject *
5893posix_sched_getaffinity(PyObject *self, PyObject *args)
5894{
5895 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005896 int cpu, ncpus, count;
5897 size_t setsize;
5898 cpu_set_t *mask = NULL;
5899 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005900
Antoine Pitrou84869872012-08-04 16:16:35 +02005901 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5902 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005903 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005904
5905 ncpus = NCPUS_START;
5906 while (1) {
5907 setsize = CPU_ALLOC_SIZE(ncpus);
5908 mask = CPU_ALLOC(ncpus);
5909 if (mask == NULL)
5910 return PyErr_NoMemory();
5911 if (sched_getaffinity(pid, setsize, mask) == 0)
5912 break;
5913 CPU_FREE(mask);
5914 if (errno != EINVAL)
5915 return posix_error();
5916 if (ncpus > INT_MAX / 2) {
5917 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5918 "a large enough CPU set");
5919 return NULL;
5920 }
5921 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005922 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005923
5924 res = PySet_New(NULL);
5925 if (res == NULL)
5926 goto error;
5927 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5928 if (CPU_ISSET_S(cpu, setsize, mask)) {
5929 PyObject *cpu_num = PyLong_FromLong(cpu);
5930 --count;
5931 if (cpu_num == NULL)
5932 goto error;
5933 if (PySet_Add(res, cpu_num)) {
5934 Py_DECREF(cpu_num);
5935 goto error;
5936 }
5937 Py_DECREF(cpu_num);
5938 }
5939 }
5940 CPU_FREE(mask);
5941 return res;
5942
5943error:
5944 if (mask)
5945 CPU_FREE(mask);
5946 Py_XDECREF(res);
5947 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005948}
5949
Benjamin Peterson2740af82011-08-02 17:41:34 -05005950#endif /* HAVE_SCHED_SETAFFINITY */
5951
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005952#endif /* HAVE_SCHED_H */
5953
Neal Norwitzb59798b2003-03-21 01:43:31 +00005954/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005955/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5956#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005957#define DEV_PTY_FILE "/dev/ptc"
5958#define HAVE_DEV_PTMX
5959#else
5960#define DEV_PTY_FILE "/dev/ptmx"
5961#endif
5962
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005963#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005964#ifdef HAVE_PTY_H
5965#include <pty.h>
5966#else
5967#ifdef HAVE_LIBUTIL_H
5968#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005969#else
5970#ifdef HAVE_UTIL_H
5971#include <util.h>
5972#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005973#endif /* HAVE_LIBUTIL_H */
5974#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005975#ifdef HAVE_STROPTS_H
5976#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005977#endif
5978#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005979
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005980#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005981PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005982"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005983Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005984
5985static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005986posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005987{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005988 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005989#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005990 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005991#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005992#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005993 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005994#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005996#endif
5997#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005998
Thomas Wouters70c21a12000-07-14 14:28:33 +00005999#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006000 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006001 goto posix_error;
6002
6003 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6004 goto error;
6005 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6006 goto error;
6007
Neal Norwitzb59798b2003-03-21 01:43:31 +00006008#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006009 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6010 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006011 goto posix_error;
6012 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6013 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006014
Victor Stinnerdaf45552013-08-28 00:53:59 +02006015 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006016 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006017 goto posix_error;
6018
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006019#else
Victor Stinner000de532013-11-25 23:19:58 +01006020 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006021 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006022 goto posix_error;
6023
Victor Stinner8c62be82010-05-06 00:08:46 +00006024 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006025
Victor Stinner8c62be82010-05-06 00:08:46 +00006026 /* change permission of slave */
6027 if (grantpt(master_fd) < 0) {
6028 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006029 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006030 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006031
Victor Stinner8c62be82010-05-06 00:08:46 +00006032 /* unlock slave */
6033 if (unlockpt(master_fd) < 0) {
6034 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006035 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006037
Victor Stinner8c62be82010-05-06 00:08:46 +00006038 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006039
Victor Stinner8c62be82010-05-06 00:08:46 +00006040 slave_name = ptsname(master_fd); /* get name of slave */
6041 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006042 goto posix_error;
6043
6044 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00006045 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006046 goto posix_error;
Victor Stinner000de532013-11-25 23:19:58 +01006047
6048 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6049 goto posix_error;
6050
Neal Norwitzb59798b2003-03-21 01:43:31 +00006051#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006052 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6053 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006054#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006055 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006056#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006057#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006058#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006059
Victor Stinner8c62be82010-05-06 00:08:46 +00006060 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006061
Victor Stinnerdaf45552013-08-28 00:53:59 +02006062posix_error:
6063 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006064#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006065error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006066#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02006067 if (master_fd != -1)
6068 close(master_fd);
6069 if (slave_fd != -1)
6070 close(slave_fd);
6071 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006072}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006073#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006074
6075#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006076PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006077"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006078Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6079Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006080To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006081
6082static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006083posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006084{
Victor Stinner8c62be82010-05-06 00:08:46 +00006085 int master_fd = -1, result = 0;
6086 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006087
Victor Stinner8c62be82010-05-06 00:08:46 +00006088 _PyImport_AcquireLock();
6089 pid = forkpty(&master_fd, NULL, NULL, NULL);
6090 if (pid == 0) {
6091 /* child: this clobbers and resets the import lock. */
6092 PyOS_AfterFork();
6093 } else {
6094 /* parent: release the import lock. */
6095 result = _PyImport_ReleaseLock();
6096 }
6097 if (pid == -1)
6098 return posix_error();
6099 if (result < 0) {
6100 /* Don't clobber the OSError if the fork failed. */
6101 PyErr_SetString(PyExc_RuntimeError,
6102 "not holding the import lock");
6103 return NULL;
6104 }
6105 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006106}
6107#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006108
Ross Lagerwall7807c352011-03-17 20:20:30 +02006109
Guido van Rossumad0ee831995-03-01 10:34:45 +00006110#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006111PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006112"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006113Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006114
Barry Warsaw53699e91996-12-10 23:23:01 +00006115static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006116posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006117{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006118 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006119}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006120#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006122
Guido van Rossumad0ee831995-03-01 10:34:45 +00006123#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006124PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006125"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006126Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006127
Barry Warsaw53699e91996-12-10 23:23:01 +00006128static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006129posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006130{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006131 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006132}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006133#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006134
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006135
Guido van Rossumad0ee831995-03-01 10:34:45 +00006136#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006137PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006138"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006139Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006140
Barry Warsaw53699e91996-12-10 23:23:01 +00006141static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006142posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006143{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006144 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006145}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006146#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006147
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006148
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006149PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006150"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006151Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006152
Barry Warsaw53699e91996-12-10 23:23:01 +00006153static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006154posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006155{
Victor Stinner8c62be82010-05-06 00:08:46 +00006156 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006157}
6158
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006159#ifdef HAVE_GETGROUPLIST
6160PyDoc_STRVAR(posix_getgrouplist__doc__,
6161"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6162Returns a list of groups to which a user belongs.\n\n\
6163 user: username to lookup\n\
6164 group: base group id of the user");
6165
6166static PyObject *
6167posix_getgrouplist(PyObject *self, PyObject *args)
6168{
6169#ifdef NGROUPS_MAX
6170#define MAX_GROUPS NGROUPS_MAX
6171#else
6172 /* defined to be 16 on Solaris7, so this should be a small number */
6173#define MAX_GROUPS 64
6174#endif
6175
6176 const char *user;
6177 int i, ngroups;
6178 PyObject *list;
6179#ifdef __APPLE__
6180 int *groups, basegid;
6181#else
6182 gid_t *groups, basegid;
6183#endif
6184 ngroups = MAX_GROUPS;
6185
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006186#ifdef __APPLE__
6187 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006188 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006189#else
6190 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6191 _Py_Gid_Converter, &basegid))
6192 return NULL;
6193#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006194
6195#ifdef __APPLE__
6196 groups = PyMem_Malloc(ngroups * sizeof(int));
6197#else
6198 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6199#endif
6200 if (groups == NULL)
6201 return PyErr_NoMemory();
6202
6203 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6204 PyMem_Del(groups);
6205 return posix_error();
6206 }
6207
6208 list = PyList_New(ngroups);
6209 if (list == NULL) {
6210 PyMem_Del(groups);
6211 return NULL;
6212 }
6213
6214 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006215#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006216 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006217#else
6218 PyObject *o = _PyLong_FromGid(groups[i]);
6219#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006220 if (o == NULL) {
6221 Py_DECREF(list);
6222 PyMem_Del(groups);
6223 return NULL;
6224 }
6225 PyList_SET_ITEM(list, i, o);
6226 }
6227
6228 PyMem_Del(groups);
6229
6230 return list;
6231}
6232#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006233
Fred Drakec9680921999-12-13 16:37:25 +00006234#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006235PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006236"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006237Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006238
6239static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006240posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006241{
6242 PyObject *result = NULL;
6243
Fred Drakec9680921999-12-13 16:37:25 +00006244#ifdef NGROUPS_MAX
6245#define MAX_GROUPS NGROUPS_MAX
6246#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006247 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006248#define MAX_GROUPS 64
6249#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006250 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006251
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006252 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006253 * This is a helper variable to store the intermediate result when
6254 * that happens.
6255 *
6256 * To keep the code readable the OSX behaviour is unconditional,
6257 * according to the POSIX spec this should be safe on all unix-y
6258 * systems.
6259 */
6260 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006261 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006262
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006263#ifdef __APPLE__
6264 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6265 * there are more groups than can fit in grouplist. Therefore, on OS X
6266 * always first call getgroups with length 0 to get the actual number
6267 * of groups.
6268 */
6269 n = getgroups(0, NULL);
6270 if (n < 0) {
6271 return posix_error();
6272 } else if (n <= MAX_GROUPS) {
6273 /* groups will fit in existing array */
6274 alt_grouplist = grouplist;
6275 } else {
6276 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6277 if (alt_grouplist == NULL) {
6278 errno = EINVAL;
6279 return posix_error();
6280 }
6281 }
6282
6283 n = getgroups(n, alt_grouplist);
6284 if (n == -1) {
6285 if (alt_grouplist != grouplist) {
6286 PyMem_Free(alt_grouplist);
6287 }
6288 return posix_error();
6289 }
6290#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006291 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006292 if (n < 0) {
6293 if (errno == EINVAL) {
6294 n = getgroups(0, NULL);
6295 if (n == -1) {
6296 return posix_error();
6297 }
6298 if (n == 0) {
6299 /* Avoid malloc(0) */
6300 alt_grouplist = grouplist;
6301 } else {
6302 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6303 if (alt_grouplist == NULL) {
6304 errno = EINVAL;
6305 return posix_error();
6306 }
6307 n = getgroups(n, alt_grouplist);
6308 if (n == -1) {
6309 PyMem_Free(alt_grouplist);
6310 return posix_error();
6311 }
6312 }
6313 } else {
6314 return posix_error();
6315 }
6316 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006317#endif
6318
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006319 result = PyList_New(n);
6320 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006321 int i;
6322 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006323 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006325 Py_DECREF(result);
6326 result = NULL;
6327 break;
Fred Drakec9680921999-12-13 16:37:25 +00006328 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006329 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006330 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006331 }
6332
6333 if (alt_grouplist != grouplist) {
6334 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006335 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006336
Fred Drakec9680921999-12-13 16:37:25 +00006337 return result;
6338}
6339#endif
6340
Antoine Pitroub7572f02009-12-02 20:46:48 +00006341#ifdef HAVE_INITGROUPS
6342PyDoc_STRVAR(posix_initgroups__doc__,
6343"initgroups(username, gid) -> None\n\n\
6344Call the system initgroups() to initialize the group access list with all of\n\
6345the groups of which the specified username is a member, plus the specified\n\
6346group id.");
6347
6348static PyObject *
6349posix_initgroups(PyObject *self, PyObject *args)
6350{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006351 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006352 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006353 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006354#ifdef __APPLE__
6355 int gid;
6356#else
6357 gid_t gid;
6358#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006359
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006360#ifdef __APPLE__
6361 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6362 PyUnicode_FSConverter, &oname,
6363 &gid))
6364#else
6365 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6366 PyUnicode_FSConverter, &oname,
6367 _Py_Gid_Converter, &gid))
6368#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006369 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006370 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006371
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006372 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006373 Py_DECREF(oname);
6374 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006375 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006376
Victor Stinner8c62be82010-05-06 00:08:46 +00006377 Py_INCREF(Py_None);
6378 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006379}
6380#endif
6381
Martin v. Löwis606edc12002-06-13 21:09:11 +00006382#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006383PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006384"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006385Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006386
6387static PyObject *
6388posix_getpgid(PyObject *self, PyObject *args)
6389{
Victor Stinner8c62be82010-05-06 00:08:46 +00006390 pid_t pid, pgid;
6391 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6392 return NULL;
6393 pgid = getpgid(pid);
6394 if (pgid < 0)
6395 return posix_error();
6396 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006397}
6398#endif /* HAVE_GETPGID */
6399
6400
Guido van Rossumb6775db1994-08-01 11:34:53 +00006401#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006402PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006403"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006404Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006405
Barry Warsaw53699e91996-12-10 23:23:01 +00006406static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006407posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006408{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006409#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006410 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006411#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006412 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006413#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006414}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006415#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006416
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006417
Guido van Rossumb6775db1994-08-01 11:34:53 +00006418#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006419PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006420"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006421Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006422
Barry Warsaw53699e91996-12-10 23:23:01 +00006423static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006424posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006425{
Guido van Rossum64933891994-10-20 21:56:42 +00006426#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006427 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006428#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006429 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006430#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006431 return posix_error();
6432 Py_INCREF(Py_None);
6433 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006434}
6435
Guido van Rossumb6775db1994-08-01 11:34:53 +00006436#endif /* HAVE_SETPGRP */
6437
Guido van Rossumad0ee831995-03-01 10:34:45 +00006438#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006439
6440#ifdef MS_WINDOWS
6441#include <tlhelp32.h>
6442
6443static PyObject*
6444win32_getppid()
6445{
6446 HANDLE snapshot;
6447 pid_t mypid;
6448 PyObject* result = NULL;
6449 BOOL have_record;
6450 PROCESSENTRY32 pe;
6451
6452 mypid = getpid(); /* This function never fails */
6453
6454 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6455 if (snapshot == INVALID_HANDLE_VALUE)
6456 return PyErr_SetFromWindowsErr(GetLastError());
6457
6458 pe.dwSize = sizeof(pe);
6459 have_record = Process32First(snapshot, &pe);
6460 while (have_record) {
6461 if (mypid == (pid_t)pe.th32ProcessID) {
6462 /* We could cache the ulong value in a static variable. */
6463 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6464 break;
6465 }
6466
6467 have_record = Process32Next(snapshot, &pe);
6468 }
6469
6470 /* If our loop exits and our pid was not found (result will be NULL)
6471 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6472 * error anyway, so let's raise it. */
6473 if (!result)
6474 result = PyErr_SetFromWindowsErr(GetLastError());
6475
6476 CloseHandle(snapshot);
6477
6478 return result;
6479}
6480#endif /*MS_WINDOWS*/
6481
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006482PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006483"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006484Return the parent's process id. If the parent process has already exited,\n\
6485Windows machines will still return its id; others systems will return the id\n\
6486of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006487
Barry Warsaw53699e91996-12-10 23:23:01 +00006488static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006489posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006490{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006491#ifdef MS_WINDOWS
6492 return win32_getppid();
6493#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006495#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006496}
6497#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006498
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006499
Fred Drake12c6e2d1999-12-14 21:25:03 +00006500#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006501PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006502"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006503Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006504
6505static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006506posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006507{
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006509#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006510 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006511 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006512
6513 if (GetUserNameW(user_name, &num_chars)) {
6514 /* num_chars is the number of unicode chars plus null terminator */
6515 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006516 }
6517 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006518 result = PyErr_SetFromWindowsErr(GetLastError());
6519#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006520 char *name;
6521 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006522
Victor Stinner8c62be82010-05-06 00:08:46 +00006523 errno = 0;
6524 name = getlogin();
6525 if (name == NULL) {
6526 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006527 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006528 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006529 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006530 }
6531 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006532 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006533 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006534#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006535 return result;
6536}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006537#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006538
Guido van Rossumad0ee831995-03-01 10:34:45 +00006539#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006540PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006541"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006542Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006543
Barry Warsaw53699e91996-12-10 23:23:01 +00006544static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006545posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006546{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006547 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006548}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006549#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006550
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006551
Guido van Rossumad0ee831995-03-01 10:34:45 +00006552#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006553PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006554"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006555Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006556
Barry Warsaw53699e91996-12-10 23:23:01 +00006557static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006558posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006559{
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 pid_t pid;
6561 int sig;
6562 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6563 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006564 if (kill(pid, sig) == -1)
6565 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006566 Py_INCREF(Py_None);
6567 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006568}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006569#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006570
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006571#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006572PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006573"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006574Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006575
6576static PyObject *
6577posix_killpg(PyObject *self, PyObject *args)
6578{
Victor Stinner8c62be82010-05-06 00:08:46 +00006579 int sig;
6580 pid_t pgid;
6581 /* XXX some man pages make the `pgid` parameter an int, others
6582 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6583 take the same type. Moreover, pid_t is always at least as wide as
6584 int (else compilation of this module fails), which is safe. */
6585 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6586 return NULL;
6587 if (killpg(pgid, sig) == -1)
6588 return posix_error();
6589 Py_INCREF(Py_None);
6590 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006591}
6592#endif
6593
Brian Curtineb24d742010-04-12 17:16:38 +00006594#ifdef MS_WINDOWS
6595PyDoc_STRVAR(win32_kill__doc__,
6596"kill(pid, sig)\n\n\
6597Kill a process with a signal.");
6598
6599static PyObject *
6600win32_kill(PyObject *self, PyObject *args)
6601{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006602 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006603 pid_t pid;
6604 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006606
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006607 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006609
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 /* Console processes which share a common console can be sent CTRL+C or
6611 CTRL+BREAK events, provided they handle said events. */
6612 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006613 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006614 err = GetLastError();
6615 PyErr_SetFromWindowsErr(err);
6616 }
6617 else
6618 Py_RETURN_NONE;
6619 }
Brian Curtineb24d742010-04-12 17:16:38 +00006620
Victor Stinner8c62be82010-05-06 00:08:46 +00006621 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6622 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006623 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006624 if (handle == NULL) {
6625 err = GetLastError();
6626 return PyErr_SetFromWindowsErr(err);
6627 }
Brian Curtineb24d742010-04-12 17:16:38 +00006628
Victor Stinner8c62be82010-05-06 00:08:46 +00006629 if (TerminateProcess(handle, sig) == 0) {
6630 err = GetLastError();
6631 result = PyErr_SetFromWindowsErr(err);
6632 } else {
6633 Py_INCREF(Py_None);
6634 result = Py_None;
6635 }
Brian Curtineb24d742010-04-12 17:16:38 +00006636
Victor Stinner8c62be82010-05-06 00:08:46 +00006637 CloseHandle(handle);
6638 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006639}
6640#endif /* MS_WINDOWS */
6641
Guido van Rossumc0125471996-06-28 18:55:32 +00006642#ifdef HAVE_PLOCK
6643
6644#ifdef HAVE_SYS_LOCK_H
6645#include <sys/lock.h>
6646#endif
6647
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006648PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006649"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006650Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006651
Barry Warsaw53699e91996-12-10 23:23:01 +00006652static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006653posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006654{
Victor Stinner8c62be82010-05-06 00:08:46 +00006655 int op;
6656 if (!PyArg_ParseTuple(args, "i:plock", &op))
6657 return NULL;
6658 if (plock(op) == -1)
6659 return posix_error();
6660 Py_INCREF(Py_None);
6661 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006662}
6663#endif
6664
Guido van Rossumb6775db1994-08-01 11:34:53 +00006665#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006666PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006667"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006668Set the current process's user id.");
6669
Barry Warsaw53699e91996-12-10 23:23:01 +00006670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006671posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006672{
Victor Stinner8c62be82010-05-06 00:08:46 +00006673 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006674 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006675 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006676 if (setuid(uid) < 0)
6677 return posix_error();
6678 Py_INCREF(Py_None);
6679 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006680}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006681#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006682
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006683
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006684#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006685PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006686"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006687Set the current process's effective user id.");
6688
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006689static PyObject *
6690posix_seteuid (PyObject *self, PyObject *args)
6691{
Victor Stinner8c62be82010-05-06 00:08:46 +00006692 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006693 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 if (seteuid(euid) < 0) {
6696 return posix_error();
6697 } else {
6698 Py_INCREF(Py_None);
6699 return Py_None;
6700 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006701}
6702#endif /* HAVE_SETEUID */
6703
6704#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006705PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006706"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006707Set the current process's effective group id.");
6708
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006709static PyObject *
6710posix_setegid (PyObject *self, PyObject *args)
6711{
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006713 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 if (setegid(egid) < 0) {
6716 return posix_error();
6717 } else {
6718 Py_INCREF(Py_None);
6719 return Py_None;
6720 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006721}
6722#endif /* HAVE_SETEGID */
6723
6724#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006725PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006726"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006727Set the current process's real and effective user ids.");
6728
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006729static PyObject *
6730posix_setreuid (PyObject *self, PyObject *args)
6731{
Victor Stinner8c62be82010-05-06 00:08:46 +00006732 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006733 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6734 _Py_Uid_Converter, &ruid,
6735 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006736 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 if (setreuid(ruid, euid) < 0) {
6738 return posix_error();
6739 } else {
6740 Py_INCREF(Py_None);
6741 return Py_None;
6742 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006743}
6744#endif /* HAVE_SETREUID */
6745
6746#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006747PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006748"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006749Set the current process's real and effective group ids.");
6750
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006751static PyObject *
6752posix_setregid (PyObject *self, PyObject *args)
6753{
Victor Stinner8c62be82010-05-06 00:08:46 +00006754 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006755 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6756 _Py_Gid_Converter, &rgid,
6757 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006758 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006759 if (setregid(rgid, egid) < 0) {
6760 return posix_error();
6761 } else {
6762 Py_INCREF(Py_None);
6763 return Py_None;
6764 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006765}
6766#endif /* HAVE_SETREGID */
6767
Guido van Rossumb6775db1994-08-01 11:34:53 +00006768#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006769PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006770"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006771Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006772
Barry Warsaw53699e91996-12-10 23:23:01 +00006773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006774posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006775{
Victor Stinner8c62be82010-05-06 00:08:46 +00006776 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006777 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 if (setgid(gid) < 0)
6780 return posix_error();
6781 Py_INCREF(Py_None);
6782 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006783}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006784#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006785
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006786#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006787PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006788"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006789Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006790
6791static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006792posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006793{
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 int i, len;
6795 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006796
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 if (!PySequence_Check(groups)) {
6798 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6799 return NULL;
6800 }
6801 len = PySequence_Size(groups);
6802 if (len > MAX_GROUPS) {
6803 PyErr_SetString(PyExc_ValueError, "too many groups");
6804 return NULL;
6805 }
6806 for(i = 0; i < len; i++) {
6807 PyObject *elem;
6808 elem = PySequence_GetItem(groups, i);
6809 if (!elem)
6810 return NULL;
6811 if (!PyLong_Check(elem)) {
6812 PyErr_SetString(PyExc_TypeError,
6813 "groups must be integers");
6814 Py_DECREF(elem);
6815 return NULL;
6816 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006817 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006818 Py_DECREF(elem);
6819 return NULL;
6820 }
6821 }
6822 Py_DECREF(elem);
6823 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006824
Victor Stinner8c62be82010-05-06 00:08:46 +00006825 if (setgroups(len, grouplist) < 0)
6826 return posix_error();
6827 Py_INCREF(Py_None);
6828 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006829}
6830#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006831
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006832#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6833static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006834wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006835{
Victor Stinner8c62be82010-05-06 00:08:46 +00006836 PyObject *result;
6837 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006838 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006839
Victor Stinner8c62be82010-05-06 00:08:46 +00006840 if (pid == -1)
6841 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006842
Victor Stinner8c62be82010-05-06 00:08:46 +00006843 if (struct_rusage == NULL) {
6844 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6845 if (m == NULL)
6846 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006847 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006848 Py_DECREF(m);
6849 if (struct_rusage == NULL)
6850 return NULL;
6851 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006852
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6854 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6855 if (!result)
6856 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006857
6858#ifndef doubletime
6859#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6860#endif
6861
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006863 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006864 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006865 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006866#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006867 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6868 SET_INT(result, 2, ru->ru_maxrss);
6869 SET_INT(result, 3, ru->ru_ixrss);
6870 SET_INT(result, 4, ru->ru_idrss);
6871 SET_INT(result, 5, ru->ru_isrss);
6872 SET_INT(result, 6, ru->ru_minflt);
6873 SET_INT(result, 7, ru->ru_majflt);
6874 SET_INT(result, 8, ru->ru_nswap);
6875 SET_INT(result, 9, ru->ru_inblock);
6876 SET_INT(result, 10, ru->ru_oublock);
6877 SET_INT(result, 11, ru->ru_msgsnd);
6878 SET_INT(result, 12, ru->ru_msgrcv);
6879 SET_INT(result, 13, ru->ru_nsignals);
6880 SET_INT(result, 14, ru->ru_nvcsw);
6881 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006882#undef SET_INT
6883
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 if (PyErr_Occurred()) {
6885 Py_DECREF(result);
6886 return NULL;
6887 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006888
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006890}
6891#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6892
6893#ifdef HAVE_WAIT3
6894PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006895"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006896Wait for completion of a child process.");
6897
6898static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006899posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006900{
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 pid_t pid;
6902 int options;
6903 struct rusage ru;
6904 WAIT_TYPE status;
6905 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006906
Victor Stinner4195b5c2012-02-08 23:03:19 +01006907 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006909
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 Py_BEGIN_ALLOW_THREADS
6911 pid = wait3(&status, options, &ru);
6912 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006913
Victor Stinner4195b5c2012-02-08 23:03:19 +01006914 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006915}
6916#endif /* HAVE_WAIT3 */
6917
6918#ifdef HAVE_WAIT4
6919PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006920"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006921Wait for completion of a given child process.");
6922
6923static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006924posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006925{
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 pid_t pid;
6927 int options;
6928 struct rusage ru;
6929 WAIT_TYPE status;
6930 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006931
Victor Stinner4195b5c2012-02-08 23:03:19 +01006932 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006933 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006934
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 Py_BEGIN_ALLOW_THREADS
6936 pid = wait4(pid, &status, options, &ru);
6937 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006938
Victor Stinner4195b5c2012-02-08 23:03:19 +01006939 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006940}
6941#endif /* HAVE_WAIT4 */
6942
Ross Lagerwall7807c352011-03-17 20:20:30 +02006943#if defined(HAVE_WAITID) && !defined(__APPLE__)
6944PyDoc_STRVAR(posix_waitid__doc__,
6945"waitid(idtype, id, options) -> waitid_result\n\n\
6946Wait for the completion of one or more child processes.\n\n\
6947idtype can be P_PID, P_PGID or P_ALL.\n\
6948id specifies the pid to wait on.\n\
6949options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6950or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6951Returns either waitid_result or None if WNOHANG is specified and there are\n\
6952no children in a waitable state.");
6953
6954static PyObject *
6955posix_waitid(PyObject *self, PyObject *args)
6956{
6957 PyObject *result;
6958 idtype_t idtype;
6959 id_t id;
6960 int options, res;
6961 siginfo_t si;
6962 si.si_pid = 0;
6963 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6964 return NULL;
6965 Py_BEGIN_ALLOW_THREADS
6966 res = waitid(idtype, id, &si, options);
6967 Py_END_ALLOW_THREADS
6968 if (res == -1)
6969 return posix_error();
6970
6971 if (si.si_pid == 0)
6972 Py_RETURN_NONE;
6973
6974 result = PyStructSequence_New(&WaitidResultType);
6975 if (!result)
6976 return NULL;
6977
6978 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006979 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006980 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6981 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6982 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6983 if (PyErr_Occurred()) {
6984 Py_DECREF(result);
6985 return NULL;
6986 }
6987
6988 return result;
6989}
6990#endif
6991
Guido van Rossumb6775db1994-08-01 11:34:53 +00006992#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006993PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006994"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006995Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006996
Barry Warsaw53699e91996-12-10 23:23:01 +00006997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006998posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006999{
Victor Stinner8c62be82010-05-06 00:08:46 +00007000 pid_t pid;
7001 int options;
7002 WAIT_TYPE status;
7003 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007004
Victor Stinner8c62be82010-05-06 00:08:46 +00007005 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7006 return NULL;
7007 Py_BEGIN_ALLOW_THREADS
7008 pid = waitpid(pid, &status, options);
7009 Py_END_ALLOW_THREADS
7010 if (pid == -1)
7011 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007012
Victor Stinner8c62be82010-05-06 00:08:46 +00007013 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007014}
7015
Tim Petersab034fa2002-02-01 11:27:43 +00007016#elif defined(HAVE_CWAIT)
7017
7018/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007019PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007020"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007021"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007022
7023static PyObject *
7024posix_waitpid(PyObject *self, PyObject *args)
7025{
Victor Stinner8c62be82010-05-06 00:08:46 +00007026 Py_intptr_t pid;
7027 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007028
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007029 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 return NULL;
7031 Py_BEGIN_ALLOW_THREADS
7032 pid = _cwait(&status, pid, options);
7033 Py_END_ALLOW_THREADS
7034 if (pid == -1)
7035 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007036
Victor Stinner8c62be82010-05-06 00:08:46 +00007037 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007038 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007039}
7040#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007041
Guido van Rossumad0ee831995-03-01 10:34:45 +00007042#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007043PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007044"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007045Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007046
Barry Warsaw53699e91996-12-10 23:23:01 +00007047static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007048posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007049{
Victor Stinner8c62be82010-05-06 00:08:46 +00007050 pid_t pid;
7051 WAIT_TYPE status;
7052 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007053
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 Py_BEGIN_ALLOW_THREADS
7055 pid = wait(&status);
7056 Py_END_ALLOW_THREADS
7057 if (pid == -1)
7058 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007059
Victor Stinner8c62be82010-05-06 00:08:46 +00007060 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007061}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007062#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007063
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007064
Larry Hastings9cf065c2012-06-22 16:30:09 -07007065#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7066PyDoc_STRVAR(readlink__doc__,
7067"readlink(path, *, dir_fd=None) -> path\n\n\
7068Return a string representing the path to which the symbolic link points.\n\
7069\n\
7070If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7071 and path should be relative; path will then be relative to that directory.\n\
7072dir_fd may not be implemented on your platform.\n\
7073 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007074#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007075
Guido van Rossumb6775db1994-08-01 11:34:53 +00007076#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007077
Barry Warsaw53699e91996-12-10 23:23:01 +00007078static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007079posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007080{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007081 path_t path;
7082 int dir_fd = DEFAULT_DIR_FD;
7083 char buffer[MAXPATHLEN];
7084 ssize_t length;
7085 PyObject *return_value = NULL;
7086 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007087
Larry Hastings9cf065c2012-06-22 16:30:09 -07007088 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007089 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007090 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7091 path_converter, &path,
7092#ifdef HAVE_READLINKAT
7093 dir_fd_converter, &dir_fd
7094#else
7095 dir_fd_unavailable, &dir_fd
7096#endif
7097 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007098 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007099
Victor Stinner8c62be82010-05-06 00:08:46 +00007100 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007101#ifdef HAVE_READLINKAT
7102 if (dir_fd != DEFAULT_DIR_FD)
7103 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007104 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007105#endif
7106 length = readlink(path.narrow, buffer, sizeof(buffer));
7107 Py_END_ALLOW_THREADS
7108
7109 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007110 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007111 goto exit;
7112 }
7113
7114 if (PyUnicode_Check(path.object))
7115 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7116 else
7117 return_value = PyBytes_FromStringAndSize(buffer, length);
7118exit:
7119 path_cleanup(&path);
7120 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007121}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122
7123
Guido van Rossumb6775db1994-08-01 11:34:53 +00007124#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007125
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007126
Larry Hastings9cf065c2012-06-22 16:30:09 -07007127#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007128PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007129"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7130Create a symbolic link pointing to src named dst.\n\n\
7131target_is_directory is required on Windows if the target is to be\n\
7132 interpreted as a directory. (On Windows, symlink requires\n\
7133 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7134 target_is_directory is ignored on non-Windows platforms.\n\
7135\n\
7136If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7137 and path should be relative; path will then be relative to that directory.\n\
7138dir_fd may not be implemented on your platform.\n\
7139 If it is unavailable, using it will raise a NotImplementedError.");
7140
7141#if defined(MS_WINDOWS)
7142
7143/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7144static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7145static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007146
Larry Hastings9cf065c2012-06-22 16:30:09 -07007147static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007148check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007149{
7150 HINSTANCE hKernel32;
7151 /* only recheck */
7152 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7153 return 1;
7154 hKernel32 = GetModuleHandleW(L"KERNEL32");
7155 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7156 "CreateSymbolicLinkW");
7157 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7158 "CreateSymbolicLinkA");
7159 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7160}
7161
Victor Stinner31b3b922013-06-05 01:49:17 +02007162/* Remove the last portion of the path */
7163static void
7164_dirnameW(WCHAR *path)
7165{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007166 WCHAR *ptr;
7167
7168 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007169 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007170 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007171 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007172 }
7173 *ptr = 0;
7174}
7175
Victor Stinner31b3b922013-06-05 01:49:17 +02007176/* Remove the last portion of the path */
7177static void
7178_dirnameA(char *path)
7179{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007180 char *ptr;
7181
7182 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007183 for(ptr = path + strlen(path); ptr != path; ptr--) {
7184 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007185 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007186 }
7187 *ptr = 0;
7188}
7189
Victor Stinner31b3b922013-06-05 01:49:17 +02007190/* Is this path absolute? */
7191static int
7192_is_absW(const WCHAR *path)
7193{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007194 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7195
7196}
7197
Victor Stinner31b3b922013-06-05 01:49:17 +02007198/* Is this path absolute? */
7199static int
7200_is_absA(const char *path)
7201{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007202 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7203
7204}
7205
Victor Stinner31b3b922013-06-05 01:49:17 +02007206/* join root and rest with a backslash */
7207static void
7208_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7209{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007210 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007211
Victor Stinner31b3b922013-06-05 01:49:17 +02007212 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007213 wcscpy(dest_path, rest);
7214 return;
7215 }
7216
7217 root_len = wcslen(root);
7218
7219 wcscpy(dest_path, root);
7220 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007221 dest_path[root_len] = L'\\';
7222 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007223 }
7224 wcscpy(dest_path+root_len, rest);
7225}
7226
Victor Stinner31b3b922013-06-05 01:49:17 +02007227/* join root and rest with a backslash */
7228static void
7229_joinA(char *dest_path, const char *root, const char *rest)
7230{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007231 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007232
Victor Stinner31b3b922013-06-05 01:49:17 +02007233 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007234 strcpy(dest_path, rest);
7235 return;
7236 }
7237
7238 root_len = strlen(root);
7239
7240 strcpy(dest_path, root);
7241 if(root_len) {
7242 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007243 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007244 }
7245 strcpy(dest_path+root_len, rest);
7246}
7247
Victor Stinner31b3b922013-06-05 01:49:17 +02007248/* Return True if the path at src relative to dest is a directory */
7249static int
7250_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007251{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007252 WIN32_FILE_ATTRIBUTE_DATA src_info;
7253 WCHAR dest_parent[MAX_PATH];
7254 WCHAR src_resolved[MAX_PATH] = L"";
7255
7256 /* dest_parent = os.path.dirname(dest) */
7257 wcscpy(dest_parent, dest);
7258 _dirnameW(dest_parent);
7259 /* src_resolved = os.path.join(dest_parent, src) */
7260 _joinW(src_resolved, dest_parent, src);
7261 return (
7262 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7263 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7264 );
7265}
7266
Victor Stinner31b3b922013-06-05 01:49:17 +02007267/* Return True if the path at src relative to dest is a directory */
7268static int
7269_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007270{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007271 WIN32_FILE_ATTRIBUTE_DATA src_info;
7272 char dest_parent[MAX_PATH];
7273 char src_resolved[MAX_PATH] = "";
7274
7275 /* dest_parent = os.path.dirname(dest) */
7276 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007277 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007278 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007279 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007280 return (
7281 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7282 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7283 );
7284}
7285
Larry Hastings9cf065c2012-06-22 16:30:09 -07007286#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007287
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007288static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007289posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007290{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007291 path_t src;
7292 path_t dst;
7293 int dir_fd = DEFAULT_DIR_FD;
7294 int target_is_directory = 0;
7295 static char *keywords[] = {"src", "dst", "target_is_directory",
7296 "dir_fd", NULL};
7297 PyObject *return_value;
7298#ifdef MS_WINDOWS
7299 DWORD result;
7300#else
7301 int result;
7302#endif
7303
7304 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007305 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007306 src.argument_name = "src";
7307 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007308 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007309 dst.argument_name = "dst";
7310
7311#ifdef MS_WINDOWS
7312 if (!check_CreateSymbolicLink()) {
7313 PyErr_SetString(PyExc_NotImplementedError,
7314 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007315 return NULL;
7316 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007317 if (!win32_can_symlink) {
7318 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007319 return NULL;
7320 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007321#endif
7322
7323 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7324 keywords,
7325 path_converter, &src,
7326 path_converter, &dst,
7327 &target_is_directory,
7328#ifdef HAVE_SYMLINKAT
7329 dir_fd_converter, &dir_fd
7330#else
7331 dir_fd_unavailable, &dir_fd
7332#endif
7333 ))
7334 return NULL;
7335
7336 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7337 PyErr_SetString(PyExc_ValueError,
7338 "symlink: src and dst must be the same type");
7339 return_value = NULL;
7340 goto exit;
7341 }
7342
7343#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007344
Larry Hastings9cf065c2012-06-22 16:30:09 -07007345 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007346 if (dst.wide) {
7347 /* if src is a directory, ensure target_is_directory==1 */
7348 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007349 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7350 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007351 }
7352 else {
7353 /* if src is a directory, ensure target_is_directory==1 */
7354 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007355 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7356 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007357 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007358 Py_END_ALLOW_THREADS
7359
7360 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08007361 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007362 goto exit;
7363 }
7364
7365#else
7366
7367 Py_BEGIN_ALLOW_THREADS
7368#if HAVE_SYMLINKAT
7369 if (dir_fd != DEFAULT_DIR_FD)
7370 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7371 else
7372#endif
7373 result = symlink(src.narrow, dst.narrow);
7374 Py_END_ALLOW_THREADS
7375
7376 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08007377 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007378 goto exit;
7379 }
7380#endif
7381
7382 return_value = Py_None;
7383 Py_INCREF(Py_None);
7384 goto exit; /* silence "unused label" warning */
7385exit:
7386 path_cleanup(&src);
7387 path_cleanup(&dst);
7388 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007389}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007390
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007391#endif /* HAVE_SYMLINK */
7392
Larry Hastings9cf065c2012-06-22 16:30:09 -07007393
Brian Curtind40e6f72010-07-08 21:39:08 +00007394#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7395
Brian Curtind40e6f72010-07-08 21:39:08 +00007396static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007397win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007398{
7399 wchar_t *path;
7400 DWORD n_bytes_returned;
7401 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007402 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007403 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007404 HANDLE reparse_point_handle;
7405
7406 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7407 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7408 wchar_t *print_name;
7409
Larry Hastings9cf065c2012-06-22 16:30:09 -07007410 static char *keywords[] = {"path", "dir_fd", NULL};
7411
7412 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7413 &po,
7414 dir_fd_unavailable, &dir_fd
7415 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007416 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007417
Victor Stinnereb5657a2011-09-30 01:44:27 +02007418 path = PyUnicode_AsUnicode(po);
7419 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007420 return NULL;
7421
7422 /* First get a handle to the reparse point */
7423 Py_BEGIN_ALLOW_THREADS
7424 reparse_point_handle = CreateFileW(
7425 path,
7426 0,
7427 0,
7428 0,
7429 OPEN_EXISTING,
7430 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7431 0);
7432 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007433
Brian Curtind40e6f72010-07-08 21:39:08 +00007434 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007435 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007436
Brian Curtind40e6f72010-07-08 21:39:08 +00007437 Py_BEGIN_ALLOW_THREADS
7438 /* New call DeviceIoControl to read the reparse point */
7439 io_result = DeviceIoControl(
7440 reparse_point_handle,
7441 FSCTL_GET_REPARSE_POINT,
7442 0, 0, /* in buffer */
7443 target_buffer, sizeof(target_buffer),
7444 &n_bytes_returned,
7445 0 /* we're not using OVERLAPPED_IO */
7446 );
7447 CloseHandle(reparse_point_handle);
7448 Py_END_ALLOW_THREADS
7449
7450 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007451 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007452
7453 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7454 {
7455 PyErr_SetString(PyExc_ValueError,
7456 "not a symbolic link");
7457 return NULL;
7458 }
Brian Curtin74e45612010-07-09 15:58:59 +00007459 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7460 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7461
7462 result = PyUnicode_FromWideChar(print_name,
7463 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007464 return result;
7465}
7466
7467#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7468
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007469
Larry Hastings605a62d2012-06-24 04:33:36 -07007470static PyStructSequence_Field times_result_fields[] = {
7471 {"user", "user time"},
7472 {"system", "system time"},
7473 {"children_user", "user time of children"},
7474 {"children_system", "system time of children"},
7475 {"elapsed", "elapsed time since an arbitrary point in the past"},
7476 {NULL}
7477};
7478
7479PyDoc_STRVAR(times_result__doc__,
7480"times_result: Result from os.times().\n\n\
7481This object may be accessed either as a tuple of\n\
7482 (user, system, children_user, children_system, elapsed),\n\
7483or via the attributes user, system, children_user, children_system,\n\
7484and elapsed.\n\
7485\n\
7486See os.times for more information.");
7487
7488static PyStructSequence_Desc times_result_desc = {
7489 "times_result", /* name */
7490 times_result__doc__, /* doc */
7491 times_result_fields,
7492 5
7493};
7494
7495static PyTypeObject TimesResultType;
7496
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007497#ifdef MS_WINDOWS
7498#define HAVE_TIMES /* mandatory, for the method table */
7499#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007500
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007501#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007502
7503static PyObject *
7504build_times_result(double user, double system,
7505 double children_user, double children_system,
7506 double elapsed)
7507{
7508 PyObject *value = PyStructSequence_New(&TimesResultType);
7509 if (value == NULL)
7510 return NULL;
7511
7512#define SET(i, field) \
7513 { \
7514 PyObject *o = PyFloat_FromDouble(field); \
7515 if (!o) { \
7516 Py_DECREF(value); \
7517 return NULL; \
7518 } \
7519 PyStructSequence_SET_ITEM(value, i, o); \
7520 } \
7521
7522 SET(0, user);
7523 SET(1, system);
7524 SET(2, children_user);
7525 SET(3, children_system);
7526 SET(4, elapsed);
7527
7528#undef SET
7529
7530 return value;
7531}
7532
7533PyDoc_STRVAR(posix_times__doc__,
7534"times() -> times_result\n\n\
7535Return an object containing floating point numbers indicating process\n\
7536times. The object behaves like a named tuple with these fields:\n\
7537 (utime, stime, cutime, cstime, elapsed_time)");
7538
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007539#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007540static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007541posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007542{
Victor Stinner8c62be82010-05-06 00:08:46 +00007543 FILETIME create, exit, kernel, user;
7544 HANDLE hProc;
7545 hProc = GetCurrentProcess();
7546 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7547 /* The fields of a FILETIME structure are the hi and lo part
7548 of a 64-bit value expressed in 100 nanosecond units.
7549 1e7 is one second in such units; 1e-7 the inverse.
7550 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7551 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007552 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007553 (double)(user.dwHighDateTime*429.4967296 +
7554 user.dwLowDateTime*1e-7),
7555 (double)(kernel.dwHighDateTime*429.4967296 +
7556 kernel.dwLowDateTime*1e-7),
7557 (double)0,
7558 (double)0,
7559 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007560}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007561#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007562#define NEED_TICKS_PER_SECOND
7563static long ticks_per_second = -1;
7564static PyObject *
7565posix_times(PyObject *self, PyObject *noargs)
7566{
7567 struct tms t;
7568 clock_t c;
7569 errno = 0;
7570 c = times(&t);
7571 if (c == (clock_t) -1)
7572 return posix_error();
7573 return build_times_result(
7574 (double)t.tms_utime / ticks_per_second,
7575 (double)t.tms_stime / ticks_per_second,
7576 (double)t.tms_cutime / ticks_per_second,
7577 (double)t.tms_cstime / ticks_per_second,
7578 (double)c / ticks_per_second);
7579}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007580#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007581
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007582#endif /* HAVE_TIMES */
7583
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007584
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007585#ifdef HAVE_GETSID
7586PyDoc_STRVAR(posix_getsid__doc__,
7587"getsid(pid) -> sid\n\n\
7588Call the system call getsid().");
7589
7590static PyObject *
7591posix_getsid(PyObject *self, PyObject *args)
7592{
Victor Stinner8c62be82010-05-06 00:08:46 +00007593 pid_t pid;
7594 int sid;
7595 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7596 return NULL;
7597 sid = getsid(pid);
7598 if (sid < 0)
7599 return posix_error();
7600 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007601}
7602#endif /* HAVE_GETSID */
7603
7604
Guido van Rossumb6775db1994-08-01 11:34:53 +00007605#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007606PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007607"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007608Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007609
Barry Warsaw53699e91996-12-10 23:23:01 +00007610static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007611posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007612{
Victor Stinner8c62be82010-05-06 00:08:46 +00007613 if (setsid() < 0)
7614 return posix_error();
7615 Py_INCREF(Py_None);
7616 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007617}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007618#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007619
Guido van Rossumb6775db1994-08-01 11:34:53 +00007620#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007621PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007622"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007623Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007624
Barry Warsaw53699e91996-12-10 23:23:01 +00007625static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007626posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007627{
Victor Stinner8c62be82010-05-06 00:08:46 +00007628 pid_t pid;
7629 int pgrp;
7630 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7631 return NULL;
7632 if (setpgid(pid, pgrp) < 0)
7633 return posix_error();
7634 Py_INCREF(Py_None);
7635 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007636}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007637#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007638
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007639
Guido van Rossumb6775db1994-08-01 11:34:53 +00007640#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007641PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007642"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007643Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007644
Barry Warsaw53699e91996-12-10 23:23:01 +00007645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007646posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007647{
Victor Stinner8c62be82010-05-06 00:08:46 +00007648 int fd;
7649 pid_t pgid;
7650 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7651 return NULL;
7652 pgid = tcgetpgrp(fd);
7653 if (pgid < 0)
7654 return posix_error();
7655 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007656}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007657#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007658
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007659
Guido van Rossumb6775db1994-08-01 11:34:53 +00007660#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007661PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007662"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007663Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007664
Barry Warsaw53699e91996-12-10 23:23:01 +00007665static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007666posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007667{
Victor Stinner8c62be82010-05-06 00:08:46 +00007668 int fd;
7669 pid_t pgid;
7670 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7671 return NULL;
7672 if (tcsetpgrp(fd, pgid) < 0)
7673 return posix_error();
7674 Py_INCREF(Py_None);
7675 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007676}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007677#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007678
Guido van Rossum687dd131993-05-17 08:34:16 +00007679/* Functions acting on file descriptors */
7680
Victor Stinnerdaf45552013-08-28 00:53:59 +02007681#ifdef O_CLOEXEC
7682extern int _Py_open_cloexec_works;
7683#endif
7684
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007685PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007686"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7687Open a file for low level IO. Returns a file handle (integer).\n\
7688\n\
7689If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7690 and path should be relative; path will then be relative to that directory.\n\
7691dir_fd may not be implemented on your platform.\n\
7692 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007693
Barry Warsaw53699e91996-12-10 23:23:01 +00007694static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007695posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007696{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007697 path_t path;
7698 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007699 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007700 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007701 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007702 PyObject *return_value = NULL;
7703 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Victor Stinnerdaf45552013-08-28 00:53:59 +02007704#ifdef O_CLOEXEC
7705 int *atomic_flag_works = &_Py_open_cloexec_works;
7706#elif !defined(MS_WINDOWS)
7707 int *atomic_flag_works = NULL;
7708#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007709
Larry Hastings9cf065c2012-06-22 16:30:09 -07007710 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007711 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007712 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7713 path_converter, &path,
7714 &flags, &mode,
7715#ifdef HAVE_OPENAT
7716 dir_fd_converter, &dir_fd
7717#else
7718 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007719#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007720 ))
7721 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007722
Victor Stinnerdaf45552013-08-28 00:53:59 +02007723#ifdef MS_WINDOWS
7724 flags |= O_NOINHERIT;
7725#elif defined(O_CLOEXEC)
7726 flags |= O_CLOEXEC;
7727#endif
7728
Victor Stinner8c62be82010-05-06 00:08:46 +00007729 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007730#ifdef MS_WINDOWS
7731 if (path.wide)
7732 fd = _wopen(path.wide, flags, mode);
7733 else
7734#endif
7735#ifdef HAVE_OPENAT
7736 if (dir_fd != DEFAULT_DIR_FD)
7737 fd = openat(dir_fd, path.narrow, flags, mode);
7738 else
7739#endif
7740 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007741 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007742
Larry Hastings9cf065c2012-06-22 16:30:09 -07007743 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007744 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007745 goto exit;
7746 }
7747
Victor Stinnerdaf45552013-08-28 00:53:59 +02007748#ifndef MS_WINDOWS
7749 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7750 close(fd);
7751 goto exit;
7752 }
7753#endif
7754
Larry Hastings9cf065c2012-06-22 16:30:09 -07007755 return_value = PyLong_FromLong((long)fd);
7756
7757exit:
7758 path_cleanup(&path);
7759 return return_value;
7760}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007761
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007762PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007763"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007764Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007765
Benjamin Peterson932bba32014-02-11 10:16:16 -05007766/*
7767The underscore at end of function name avoids a name clash with the libc
7768function posix_close.
7769*/
Barry Warsaw53699e91996-12-10 23:23:01 +00007770static PyObject *
Benjamin Peterson932bba32014-02-11 10:16:16 -05007771posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007772{
Victor Stinner8c62be82010-05-06 00:08:46 +00007773 int fd, res;
7774 if (!PyArg_ParseTuple(args, "i:close", &fd))
7775 return NULL;
7776 if (!_PyVerify_fd(fd))
7777 return posix_error();
7778 Py_BEGIN_ALLOW_THREADS
7779 res = close(fd);
7780 Py_END_ALLOW_THREADS
7781 if (res < 0)
7782 return posix_error();
7783 Py_INCREF(Py_None);
7784 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007785}
7786
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007787
Victor Stinner8c62be82010-05-06 00:08:46 +00007788PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007789"closerange(fd_low, fd_high)\n\n\
7790Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7791
7792static PyObject *
7793posix_closerange(PyObject *self, PyObject *args)
7794{
Victor Stinner8c62be82010-05-06 00:08:46 +00007795 int fd_from, fd_to, i;
7796 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7797 return NULL;
7798 Py_BEGIN_ALLOW_THREADS
7799 for (i = fd_from; i < fd_to; i++)
7800 if (_PyVerify_fd(i))
7801 close(i);
7802 Py_END_ALLOW_THREADS
7803 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007804}
7805
7806
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007807PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007808"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007809Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007810
Barry Warsaw53699e91996-12-10 23:23:01 +00007811static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007812posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007813{
Victor Stinner8c62be82010-05-06 00:08:46 +00007814 int fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007815
Victor Stinner8c62be82010-05-06 00:08:46 +00007816 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7817 return NULL;
Tim Golden23005082013-10-25 11:22:37 +01007818
Victor Stinnerdaf45552013-08-28 00:53:59 +02007819 fd = _Py_dup(fd);
7820 if (fd == -1)
7821 return NULL;
7822
Victor Stinner8c62be82010-05-06 00:08:46 +00007823 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007824}
7825
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007826
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007827PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007828"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007829Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007830
Barry Warsaw53699e91996-12-10 23:23:01 +00007831static PyObject *
Victor Stinnerdaf45552013-08-28 00:53:59 +02007832posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007833{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007834 static char *keywords[] = {"fd", "fd2", "inheritable", NULL};
7835 int fd, fd2;
7836 int inheritable = 1;
7837 int res;
7838#if defined(HAVE_DUP3) && \
7839 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7840 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7841 int dup3_works = -1;
7842#endif
7843
7844 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords,
7845 &fd, &fd2, &inheritable))
Victor Stinner8c62be82010-05-06 00:08:46 +00007846 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007847
Victor Stinner8c62be82010-05-06 00:08:46 +00007848 if (!_PyVerify_fd_dup2(fd, fd2))
7849 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007850
7851#ifdef MS_WINDOWS
7852 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007853 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007854 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 if (res < 0)
7856 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007857
7858 /* Character files like console cannot be make non-inheritable */
7859 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7860 close(fd2);
7861 return NULL;
7862 }
7863
7864#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7865 Py_BEGIN_ALLOW_THREADS
7866 if (!inheritable)
7867 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7868 else
7869 res = dup2(fd, fd2);
7870 Py_END_ALLOW_THREADS
7871 if (res < 0)
7872 return posix_error();
7873
7874#else
7875
7876#ifdef HAVE_DUP3
7877 if (!inheritable && dup3_works != 0) {
7878 Py_BEGIN_ALLOW_THREADS
7879 res = dup3(fd, fd2, O_CLOEXEC);
7880 Py_END_ALLOW_THREADS
7881 if (res < 0) {
7882 if (dup3_works == -1)
7883 dup3_works = (errno != ENOSYS);
7884 if (dup3_works)
7885 return posix_error();
7886 }
7887 }
7888
7889 if (inheritable || dup3_works == 0)
7890 {
7891#endif
7892 Py_BEGIN_ALLOW_THREADS
7893 res = dup2(fd, fd2);
7894 Py_END_ALLOW_THREADS
7895 if (res < 0)
7896 return posix_error();
7897
7898 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7899 close(fd2);
7900 return NULL;
7901 }
7902#ifdef HAVE_DUP3
7903 }
7904#endif
7905
7906#endif
7907
Victor Stinner8c62be82010-05-06 00:08:46 +00007908 Py_INCREF(Py_None);
7909 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007910}
7911
Ross Lagerwall7807c352011-03-17 20:20:30 +02007912#ifdef HAVE_LOCKF
7913PyDoc_STRVAR(posix_lockf__doc__,
7914"lockf(fd, cmd, len)\n\n\
7915Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7916fd is an open file descriptor.\n\
7917cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7918F_TEST.\n\
7919len specifies the section of the file to lock.");
7920
7921static PyObject *
7922posix_lockf(PyObject *self, PyObject *args)
7923{
7924 int fd, cmd, res;
7925 off_t len;
7926 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7927 &fd, &cmd, _parse_off_t, &len))
7928 return NULL;
7929
7930 Py_BEGIN_ALLOW_THREADS
7931 res = lockf(fd, cmd, len);
7932 Py_END_ALLOW_THREADS
7933
7934 if (res < 0)
7935 return posix_error();
7936
7937 Py_RETURN_NONE;
7938}
7939#endif
7940
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007941
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007942PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007943"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007944Set the current position of a file descriptor.\n\
7945Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007946
Barry Warsaw53699e91996-12-10 23:23:01 +00007947static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007948posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007949{
Victor Stinner8c62be82010-05-06 00:08:46 +00007950 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007951#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007952 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007953#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007954 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007955#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007956 PyObject *posobj;
7957 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007958 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007959#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007960 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7961 switch (how) {
7962 case 0: how = SEEK_SET; break;
7963 case 1: how = SEEK_CUR; break;
7964 case 2: how = SEEK_END; break;
7965 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007966#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007967
Ross Lagerwall8e749672011-03-17 21:54:07 +02007968#if !defined(HAVE_LARGEFILE_SUPPORT)
7969 pos = PyLong_AsLong(posobj);
7970#else
7971 pos = PyLong_AsLongLong(posobj);
7972#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 if (PyErr_Occurred())
7974 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007975
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 if (!_PyVerify_fd(fd))
7977 return posix_error();
7978 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02007979#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007980 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007981#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007983#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 Py_END_ALLOW_THREADS
7985 if (res < 0)
7986 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007987
7988#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007989 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007990#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007992#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007993}
7994
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007996PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07007997"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007998Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007999
Barry Warsaw53699e91996-12-10 23:23:01 +00008000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008001posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008002{
Victor Stinner8c62be82010-05-06 00:08:46 +00008003 int fd, size;
8004 Py_ssize_t n;
8005 PyObject *buffer;
8006 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
8007 return NULL;
8008 if (size < 0) {
8009 errno = EINVAL;
8010 return posix_error();
8011 }
8012 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8013 if (buffer == NULL)
8014 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00008015 if (!_PyVerify_fd(fd)) {
8016 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00008017 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00008018 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008019 Py_BEGIN_ALLOW_THREADS
8020 n = read(fd, PyBytes_AS_STRING(buffer), size);
8021 Py_END_ALLOW_THREADS
8022 if (n < 0) {
8023 Py_DECREF(buffer);
8024 return posix_error();
8025 }
8026 if (n != size)
8027 _PyBytes_Resize(&buffer, n);
8028 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008029}
8030
Ross Lagerwall7807c352011-03-17 20:20:30 +02008031#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8032 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008033static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008034iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8035{
8036 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008037 Py_ssize_t blen, total = 0;
8038
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008039 *iov = PyMem_New(struct iovec, cnt);
8040 if (*iov == NULL) {
8041 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008042 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008043 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008044
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008045 *buf = PyMem_New(Py_buffer, cnt);
8046 if (*buf == NULL) {
8047 PyMem_Del(*iov);
8048 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008049 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008050 }
8051
8052 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008053 PyObject *item = PySequence_GetItem(seq, i);
8054 if (item == NULL)
8055 goto fail;
8056 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8057 Py_DECREF(item);
8058 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008059 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008060 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008061 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008062 blen = (*buf)[i].len;
8063 (*iov)[i].iov_len = blen;
8064 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008065 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008066 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008067
8068fail:
8069 PyMem_Del(*iov);
8070 for (j = 0; j < i; j++) {
8071 PyBuffer_Release(&(*buf)[j]);
8072 }
8073 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008074 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008075}
8076
8077static void
8078iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8079{
8080 int i;
8081 PyMem_Del(iov);
8082 for (i = 0; i < cnt; i++) {
8083 PyBuffer_Release(&buf[i]);
8084 }
8085 PyMem_Del(buf);
8086}
8087#endif
8088
Ross Lagerwall7807c352011-03-17 20:20:30 +02008089#ifdef HAVE_READV
8090PyDoc_STRVAR(posix_readv__doc__,
8091"readv(fd, buffers) -> bytesread\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008092Read from a file descriptor fd into a number of mutable, bytes-like\n\
8093objects (\"buffers\"). readv will transfer data into each buffer\n\
8094until it is full and then move on to the next buffer in the sequence\n\
8095to hold the rest of the data.\n\n\
8096readv returns the total number of bytes read (which may be less than\n\
8097the total capacity of all the buffers.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008098
8099static PyObject *
8100posix_readv(PyObject *self, PyObject *args)
8101{
8102 int fd, cnt;
8103 Py_ssize_t n;
8104 PyObject *seq;
8105 struct iovec *iov;
8106 Py_buffer *buf;
8107
8108 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8109 return NULL;
8110 if (!PySequence_Check(seq)) {
8111 PyErr_SetString(PyExc_TypeError,
8112 "readv() arg 2 must be a sequence");
8113 return NULL;
8114 }
8115 cnt = PySequence_Size(seq);
8116
Victor Stinner57ddf782014-01-08 15:21:28 +01008117 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE) < 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008118 return NULL;
8119
8120 Py_BEGIN_ALLOW_THREADS
8121 n = readv(fd, iov, cnt);
8122 Py_END_ALLOW_THREADS
8123
8124 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008125 if (n < 0)
8126 return posix_error();
8127
Ross Lagerwall7807c352011-03-17 20:20:30 +02008128 return PyLong_FromSsize_t(n);
8129}
8130#endif
8131
8132#ifdef HAVE_PREAD
8133PyDoc_STRVAR(posix_pread__doc__,
8134"pread(fd, buffersize, offset) -> string\n\n\
8135Read from a file descriptor, fd, at a position of offset. It will read up\n\
8136to buffersize number of bytes. The file offset remains unchanged.");
8137
8138static PyObject *
8139posix_pread(PyObject *self, PyObject *args)
8140{
8141 int fd, size;
8142 off_t offset;
8143 Py_ssize_t n;
8144 PyObject *buffer;
8145 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8146 return NULL;
8147
8148 if (size < 0) {
8149 errno = EINVAL;
8150 return posix_error();
8151 }
8152 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8153 if (buffer == NULL)
8154 return NULL;
8155 if (!_PyVerify_fd(fd)) {
8156 Py_DECREF(buffer);
8157 return posix_error();
8158 }
8159 Py_BEGIN_ALLOW_THREADS
8160 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8161 Py_END_ALLOW_THREADS
8162 if (n < 0) {
8163 Py_DECREF(buffer);
8164 return posix_error();
8165 }
8166 if (n != size)
8167 _PyBytes_Resize(&buffer, n);
8168 return buffer;
8169}
8170#endif
8171
8172PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008173"write(fd, data) -> byteswritten\n\n\
8174Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008175
8176static PyObject *
8177posix_write(PyObject *self, PyObject *args)
8178{
8179 Py_buffer pbuf;
8180 int fd;
8181 Py_ssize_t size, len;
8182
8183 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8184 return NULL;
8185 if (!_PyVerify_fd(fd)) {
8186 PyBuffer_Release(&pbuf);
8187 return posix_error();
8188 }
8189 len = pbuf.len;
8190 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008191#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008192 if (len > INT_MAX)
8193 len = INT_MAX;
8194 size = write(fd, pbuf.buf, (int)len);
8195#else
8196 size = write(fd, pbuf.buf, len);
8197#endif
8198 Py_END_ALLOW_THREADS
8199 PyBuffer_Release(&pbuf);
8200 if (size < 0)
8201 return posix_error();
8202 return PyLong_FromSsize_t(size);
8203}
8204
8205#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008206PyDoc_STRVAR(posix_sendfile__doc__,
8207"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8208sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8209 -> byteswritten\n\
8210Copy nbytes bytes from file descriptor in to file descriptor out.");
8211
8212static PyObject *
8213posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8214{
8215 int in, out;
8216 Py_ssize_t ret;
8217 off_t offset;
8218
8219#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8220#ifndef __APPLE__
8221 Py_ssize_t len;
8222#endif
8223 PyObject *headers = NULL, *trailers = NULL;
8224 Py_buffer *hbuf, *tbuf;
8225 off_t sbytes;
8226 struct sf_hdtr sf;
8227 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008228 static char *keywords[] = {"out", "in",
8229 "offset", "count",
8230 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008231
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008232 sf.headers = NULL;
8233 sf.trailers = NULL;
8234
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008235#ifdef __APPLE__
8236 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008237 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008238#else
8239 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008240 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008241#endif
8242 &headers, &trailers, &flags))
8243 return NULL;
8244 if (headers != NULL) {
8245 if (!PySequence_Check(headers)) {
8246 PyErr_SetString(PyExc_TypeError,
8247 "sendfile() headers must be a sequence or None");
8248 return NULL;
8249 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008250 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008251 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008252 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008253 (i = iov_setup(&(sf.headers), &hbuf,
8254 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008255 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008256#ifdef __APPLE__
8257 sbytes += i;
8258#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008259 }
8260 }
8261 if (trailers != NULL) {
8262 if (!PySequence_Check(trailers)) {
8263 PyErr_SetString(PyExc_TypeError,
8264 "sendfile() trailers must be a sequence or None");
8265 return NULL;
8266 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008267 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008268 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008269 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008270 (i = iov_setup(&(sf.trailers), &tbuf,
8271 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008272 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008273#ifdef __APPLE__
8274 sbytes += i;
8275#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008276 }
8277 }
8278
8279 Py_BEGIN_ALLOW_THREADS
8280#ifdef __APPLE__
8281 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8282#else
8283 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8284#endif
8285 Py_END_ALLOW_THREADS
8286
8287 if (sf.headers != NULL)
8288 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8289 if (sf.trailers != NULL)
8290 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8291
8292 if (ret < 0) {
8293 if ((errno == EAGAIN) || (errno == EBUSY)) {
8294 if (sbytes != 0) {
8295 // some data has been sent
8296 goto done;
8297 }
8298 else {
8299 // no data has been sent; upper application is supposed
8300 // to retry on EAGAIN or EBUSY
8301 return posix_error();
8302 }
8303 }
8304 return posix_error();
8305 }
8306 goto done;
8307
8308done:
8309 #if !defined(HAVE_LARGEFILE_SUPPORT)
8310 return Py_BuildValue("l", sbytes);
8311 #else
8312 return Py_BuildValue("L", sbytes);
8313 #endif
8314
8315#else
8316 Py_ssize_t count;
8317 PyObject *offobj;
8318 static char *keywords[] = {"out", "in",
8319 "offset", "count", NULL};
8320 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8321 keywords, &out, &in, &offobj, &count))
8322 return NULL;
8323#ifdef linux
8324 if (offobj == Py_None) {
8325 Py_BEGIN_ALLOW_THREADS
8326 ret = sendfile(out, in, NULL, count);
8327 Py_END_ALLOW_THREADS
8328 if (ret < 0)
8329 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008330 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008331 }
8332#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008333 if (!_parse_off_t(offobj, &offset))
8334 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008335 Py_BEGIN_ALLOW_THREADS
8336 ret = sendfile(out, in, &offset, count);
8337 Py_END_ALLOW_THREADS
8338 if (ret < 0)
8339 return posix_error();
8340 return Py_BuildValue("n", ret);
8341#endif
8342}
8343#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008344
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008345PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008346"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008347Like stat(), but for an open file descriptor.\n\
8348Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008349
Barry Warsaw53699e91996-12-10 23:23:01 +00008350static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008351posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008352{
Victor Stinner8c62be82010-05-06 00:08:46 +00008353 int fd;
8354 STRUCT_STAT st;
8355 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008356 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008357 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008358 Py_BEGIN_ALLOW_THREADS
8359 res = FSTAT(fd, &st);
8360 Py_END_ALLOW_THREADS
8361 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008362#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008363 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008364#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008365 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008366#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008367 }
Tim Peters5aa91602002-01-30 05:46:57 +00008368
Victor Stinner4195b5c2012-02-08 23:03:19 +01008369 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008370}
8371
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008372PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008373"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008374Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008375connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008376
8377static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008378posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008379{
Victor Stinner8c62be82010-05-06 00:08:46 +00008380 int fd;
8381 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8382 return NULL;
8383 if (!_PyVerify_fd(fd))
8384 return PyBool_FromLong(0);
8385 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008386}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008387
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008388#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008389PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008390"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008391Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008392
Barry Warsaw53699e91996-12-10 23:23:01 +00008393static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008394posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008395{
Victor Stinner8c62be82010-05-06 00:08:46 +00008396 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008397#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008398 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008399 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008400 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008401#else
8402 int res;
8403#endif
8404
8405#ifdef MS_WINDOWS
8406 attr.nLength = sizeof(attr);
8407 attr.lpSecurityDescriptor = NULL;
8408 attr.bInheritHandle = FALSE;
8409
8410 Py_BEGIN_ALLOW_THREADS
8411 ok = CreatePipe(&read, &write, &attr, 0);
8412 if (ok) {
8413 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8414 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8415 if (fds[0] == -1 || fds[1] == -1) {
8416 CloseHandle(read);
8417 CloseHandle(write);
8418 ok = 0;
8419 }
8420 }
8421 Py_END_ALLOW_THREADS
8422
Victor Stinner8c62be82010-05-06 00:08:46 +00008423 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008424 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008425#else
8426
8427#ifdef HAVE_PIPE2
8428 Py_BEGIN_ALLOW_THREADS
8429 res = pipe2(fds, O_CLOEXEC);
8430 Py_END_ALLOW_THREADS
8431
8432 if (res != 0 && errno == ENOSYS)
8433 {
8434#endif
8435 Py_BEGIN_ALLOW_THREADS
8436 res = pipe(fds);
8437 Py_END_ALLOW_THREADS
8438
8439 if (res == 0) {
8440 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8441 close(fds[0]);
8442 close(fds[1]);
8443 return NULL;
8444 }
8445 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8446 close(fds[0]);
8447 close(fds[1]);
8448 return NULL;
8449 }
8450 }
8451#ifdef HAVE_PIPE2
8452 }
8453#endif
8454
8455 if (res != 0)
8456 return PyErr_SetFromErrno(PyExc_OSError);
8457#endif /* !MS_WINDOWS */
8458 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008459}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008460#endif /* HAVE_PIPE */
8461
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008462#ifdef HAVE_PIPE2
8463PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008464"pipe2(flags) -> (read_end, write_end)\n\n\
8465Create a pipe with flags set atomically.\n\
8466flags can be constructed by ORing together one or more of these values:\n\
8467O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008468");
8469
8470static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008471posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008472{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008473 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008474 int fds[2];
8475 int res;
8476
Serhiy Storchaka78980432013-01-15 01:12:17 +02008477 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008478 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008479 return NULL;
8480
8481 res = pipe2(fds, flags);
8482 if (res != 0)
8483 return posix_error();
8484 return Py_BuildValue("(ii)", fds[0], fds[1]);
8485}
8486#endif /* HAVE_PIPE2 */
8487
Ross Lagerwall7807c352011-03-17 20:20:30 +02008488#ifdef HAVE_WRITEV
8489PyDoc_STRVAR(posix_writev__doc__,
8490"writev(fd, buffers) -> byteswritten\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008491Write the contents of *buffers* to file descriptor *fd*. *buffers*\n\
8492must be a sequence of bytes-like objects.\n\n\
8493writev writes the contents of each object to the file descriptor\n\
8494and returns the total number of bytes written.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008495
8496static PyObject *
8497posix_writev(PyObject *self, PyObject *args)
8498{
8499 int fd, cnt;
8500 Py_ssize_t res;
8501 PyObject *seq;
8502 struct iovec *iov;
8503 Py_buffer *buf;
8504 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8505 return NULL;
8506 if (!PySequence_Check(seq)) {
8507 PyErr_SetString(PyExc_TypeError,
8508 "writev() arg 2 must be a sequence");
8509 return NULL;
8510 }
8511 cnt = PySequence_Size(seq);
8512
Victor Stinner57ddf782014-01-08 15:21:28 +01008513 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008514 return NULL;
8515 }
8516
8517 Py_BEGIN_ALLOW_THREADS
8518 res = writev(fd, iov, cnt);
8519 Py_END_ALLOW_THREADS
8520
8521 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008522 if (res < 0)
8523 return posix_error();
8524
Ross Lagerwall7807c352011-03-17 20:20:30 +02008525 return PyLong_FromSsize_t(res);
8526}
8527#endif
8528
8529#ifdef HAVE_PWRITE
8530PyDoc_STRVAR(posix_pwrite__doc__,
8531"pwrite(fd, string, offset) -> byteswritten\n\n\
8532Write string to a file descriptor, fd, from offset, leaving the file\n\
8533offset unchanged.");
8534
8535static PyObject *
8536posix_pwrite(PyObject *self, PyObject *args)
8537{
8538 Py_buffer pbuf;
8539 int fd;
8540 off_t offset;
8541 Py_ssize_t size;
8542
8543 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8544 return NULL;
8545
8546 if (!_PyVerify_fd(fd)) {
8547 PyBuffer_Release(&pbuf);
8548 return posix_error();
8549 }
8550 Py_BEGIN_ALLOW_THREADS
8551 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8552 Py_END_ALLOW_THREADS
8553 PyBuffer_Release(&pbuf);
8554 if (size < 0)
8555 return posix_error();
8556 return PyLong_FromSsize_t(size);
8557}
8558#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008559
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008560#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008561PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008562"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8563Create a FIFO (a POSIX named pipe).\n\
8564\n\
8565If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8566 and path should be relative; path will then be relative to that directory.\n\
8567dir_fd may not be implemented on your platform.\n\
8568 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008569
Barry Warsaw53699e91996-12-10 23:23:01 +00008570static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008571posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008572{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008573 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008574 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008575 int dir_fd = DEFAULT_DIR_FD;
8576 int result;
8577 PyObject *return_value = NULL;
8578 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8579
8580 memset(&path, 0, sizeof(path));
8581 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8582 path_converter, &path,
8583 &mode,
8584#ifdef HAVE_MKFIFOAT
8585 dir_fd_converter, &dir_fd
8586#else
8587 dir_fd_unavailable, &dir_fd
8588#endif
8589 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008590 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008591
Victor Stinner8c62be82010-05-06 00:08:46 +00008592 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008593#ifdef HAVE_MKFIFOAT
8594 if (dir_fd != DEFAULT_DIR_FD)
8595 result = mkfifoat(dir_fd, path.narrow, mode);
8596 else
8597#endif
8598 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008599 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008600
8601 if (result < 0) {
8602 return_value = posix_error();
8603 goto exit;
8604 }
8605
8606 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008607 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008608
8609exit:
8610 path_cleanup(&path);
8611 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008612}
8613#endif
8614
Neal Norwitz11690112002-07-30 01:08:28 +00008615#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008616PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008617"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008618Create a filesystem node (file, device special file or named pipe)\n\
8619named filename. mode specifies both the permissions to use and the\n\
8620type of node to be created, being combined (bitwise OR) with one of\n\
8621S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008622device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008623os.makedev()), otherwise it is ignored.\n\
8624\n\
8625If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8626 and path should be relative; path will then be relative to that directory.\n\
8627dir_fd may not be implemented on your platform.\n\
8628 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008629
8630
8631static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008632posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008633{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008634 path_t path;
8635 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008636 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008637 int dir_fd = DEFAULT_DIR_FD;
8638 int result;
8639 PyObject *return_value = NULL;
8640 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8641
8642 memset(&path, 0, sizeof(path));
8643 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8644 path_converter, &path,
8645 &mode, &device,
8646#ifdef HAVE_MKNODAT
8647 dir_fd_converter, &dir_fd
8648#else
8649 dir_fd_unavailable, &dir_fd
8650#endif
8651 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008652 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008653
Victor Stinner8c62be82010-05-06 00:08:46 +00008654 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008655#ifdef HAVE_MKNODAT
8656 if (dir_fd != DEFAULT_DIR_FD)
8657 result = mknodat(dir_fd, path.narrow, mode, device);
8658 else
8659#endif
8660 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008661 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008662
8663 if (result < 0) {
8664 return_value = posix_error();
8665 goto exit;
8666 }
8667
8668 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008669 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008670
Larry Hastings9cf065c2012-06-22 16:30:09 -07008671exit:
8672 path_cleanup(&path);
8673 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008674}
8675#endif
8676
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008677#ifdef HAVE_DEVICE_MACROS
8678PyDoc_STRVAR(posix_major__doc__,
8679"major(device) -> major number\n\
8680Extracts a device major number from a raw device number.");
8681
8682static PyObject *
8683posix_major(PyObject *self, PyObject *args)
8684{
Victor Stinner8c62be82010-05-06 00:08:46 +00008685 int device;
8686 if (!PyArg_ParseTuple(args, "i:major", &device))
8687 return NULL;
8688 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008689}
8690
8691PyDoc_STRVAR(posix_minor__doc__,
8692"minor(device) -> minor number\n\
8693Extracts a device minor number from a raw device number.");
8694
8695static PyObject *
8696posix_minor(PyObject *self, PyObject *args)
8697{
Victor Stinner8c62be82010-05-06 00:08:46 +00008698 int device;
8699 if (!PyArg_ParseTuple(args, "i:minor", &device))
8700 return NULL;
8701 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008702}
8703
8704PyDoc_STRVAR(posix_makedev__doc__,
8705"makedev(major, minor) -> device number\n\
8706Composes a raw device number from the major and minor device numbers.");
8707
8708static PyObject *
8709posix_makedev(PyObject *self, PyObject *args)
8710{
Victor Stinner8c62be82010-05-06 00:08:46 +00008711 int major, minor;
8712 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8713 return NULL;
8714 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008715}
8716#endif /* device macros */
8717
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008718
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008719#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008720PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008721"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008722Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008723
Barry Warsaw53699e91996-12-10 23:23:01 +00008724static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008725posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008726{
Victor Stinner8c62be82010-05-06 00:08:46 +00008727 int fd;
8728 off_t length;
8729 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008730
Ross Lagerwall7807c352011-03-17 20:20:30 +02008731 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008732 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008733
Victor Stinner8c62be82010-05-06 00:08:46 +00008734 Py_BEGIN_ALLOW_THREADS
8735 res = ftruncate(fd, length);
8736 Py_END_ALLOW_THREADS
8737 if (res < 0)
8738 return posix_error();
8739 Py_INCREF(Py_None);
8740 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008741}
8742#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008743
Ross Lagerwall7807c352011-03-17 20:20:30 +02008744#ifdef HAVE_TRUNCATE
8745PyDoc_STRVAR(posix_truncate__doc__,
8746"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008747Truncate the file given by path to length bytes.\n\
8748On some platforms, path may also be specified as an open file descriptor.\n\
8749 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008750
8751static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008752posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008753{
Georg Brandl306336b2012-06-24 12:55:33 +02008754 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008755 off_t length;
8756 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008757 PyObject *result = NULL;
8758 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008759
Georg Brandl306336b2012-06-24 12:55:33 +02008760 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008761 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008762#ifdef HAVE_FTRUNCATE
8763 path.allow_fd = 1;
8764#endif
8765 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8766 path_converter, &path,
8767 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008768 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008769
8770 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008771#ifdef HAVE_FTRUNCATE
8772 if (path.fd != -1)
8773 res = ftruncate(path.fd, length);
8774 else
8775#endif
8776 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008777 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008778 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008779 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008780 else {
8781 Py_INCREF(Py_None);
8782 result = Py_None;
8783 }
8784 path_cleanup(&path);
8785 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008786}
8787#endif
8788
Victor Stinnerd6b17692014-09-30 12:20:05 +02008789/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8790 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8791 defined, which is the case in Python on AIX. AIX bug report:
8792 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8793#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8794# define POSIX_FADVISE_AIX_BUG
8795#endif
8796
8797#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008798PyDoc_STRVAR(posix_posix_fallocate__doc__,
8799"posix_fallocate(fd, offset, len)\n\n\
8800Ensures that enough disk space is allocated for the file specified by fd\n\
8801starting from offset and continuing for len bytes.");
8802
8803static PyObject *
8804posix_posix_fallocate(PyObject *self, PyObject *args)
8805{
8806 off_t len, offset;
8807 int res, fd;
8808
8809 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8810 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8811 return NULL;
8812
8813 Py_BEGIN_ALLOW_THREADS
8814 res = posix_fallocate(fd, offset, len);
8815 Py_END_ALLOW_THREADS
8816 if (res != 0) {
8817 errno = res;
8818 return posix_error();
8819 }
8820 Py_RETURN_NONE;
8821}
8822#endif
8823
Victor Stinnerd6b17692014-09-30 12:20:05 +02008824#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008825PyDoc_STRVAR(posix_posix_fadvise__doc__,
8826"posix_fadvise(fd, offset, len, advice)\n\n\
8827Announces an intention to access data in a specific pattern thus allowing\n\
8828the kernel to make optimizations.\n\
8829The advice applies to the region of the file specified by fd starting at\n\
8830offset and continuing for len bytes.\n\
8831advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8832POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8833POSIX_FADV_DONTNEED.");
8834
8835static PyObject *
8836posix_posix_fadvise(PyObject *self, PyObject *args)
8837{
8838 off_t len, offset;
8839 int res, fd, advice;
8840
8841 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8842 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8843 return NULL;
8844
8845 Py_BEGIN_ALLOW_THREADS
8846 res = posix_fadvise(fd, offset, len, advice);
8847 Py_END_ALLOW_THREADS
8848 if (res != 0) {
8849 errno = res;
8850 return posix_error();
8851 }
8852 Py_RETURN_NONE;
8853}
8854#endif
8855
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008856#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008857PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008858"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008859Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008860
Fred Drake762e2061999-08-26 17:23:54 +00008861/* Save putenv() parameters as values here, so we can collect them when they
8862 * get re-set with another call for the same key. */
8863static PyObject *posix_putenv_garbage;
8864
Tim Peters5aa91602002-01-30 05:46:57 +00008865static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008866posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008867{
Victor Stinner84ae1182010-05-06 22:05:07 +00008868 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008869#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008870 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008871 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008872
Victor Stinner8c62be82010-05-06 00:08:46 +00008873 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008874 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008875 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008876 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008877
Victor Stinner65170952011-11-22 22:16:17 +01008878 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008879 if (newstr == NULL) {
8880 PyErr_NoMemory();
8881 goto error;
8882 }
Victor Stinner65170952011-11-22 22:16:17 +01008883 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8884 PyErr_Format(PyExc_ValueError,
8885 "the environment variable is longer than %u characters",
8886 _MAX_ENV);
8887 goto error;
8888 }
8889
Victor Stinner8c62be82010-05-06 00:08:46 +00008890 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008891 if (newenv == NULL)
8892 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008893 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008894 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008895 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008896 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008897#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008898 PyObject *os1, *os2;
8899 char *s1, *s2;
8900 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008901
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008902 if (!PyArg_ParseTuple(args,
8903 "O&O&:putenv",
8904 PyUnicode_FSConverter, &os1,
8905 PyUnicode_FSConverter, &os2))
8906 return NULL;
8907 s1 = PyBytes_AsString(os1);
8908 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008909
Victor Stinner65170952011-11-22 22:16:17 +01008910 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008911 if (newstr == NULL) {
8912 PyErr_NoMemory();
8913 goto error;
8914 }
8915
Victor Stinner8c62be82010-05-06 00:08:46 +00008916 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008917 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008918 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008919 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008920 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008921#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008922
Victor Stinner8c62be82010-05-06 00:08:46 +00008923 /* Install the first arg and newstr in posix_putenv_garbage;
8924 * this will cause previous value to be collected. This has to
8925 * happen after the real putenv() call because the old value
8926 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008927 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008928 /* really not much we can do; just leak */
8929 PyErr_Clear();
8930 }
8931 else {
8932 Py_DECREF(newstr);
8933 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008934
Martin v. Löwis011e8422009-05-05 04:43:17 +00008935#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008936 Py_DECREF(os1);
8937 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008938#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008939 Py_RETURN_NONE;
8940
8941error:
8942#ifndef MS_WINDOWS
8943 Py_DECREF(os1);
8944 Py_DECREF(os2);
8945#endif
8946 Py_XDECREF(newstr);
8947 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008948}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008949#endif /* putenv */
8950
Guido van Rossumc524d952001-10-19 01:31:59 +00008951#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008952PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008953"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008954Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008955
8956static PyObject *
8957posix_unsetenv(PyObject *self, PyObject *args)
8958{
Victor Stinner65170952011-11-22 22:16:17 +01008959 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008960#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008961 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008962#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008963
8964 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008965
Victor Stinner65170952011-11-22 22:16:17 +01008966 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008967 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008968
Victor Stinner984890f2011-11-24 13:53:38 +01008969#ifdef HAVE_BROKEN_UNSETENV
8970 unsetenv(PyBytes_AS_STRING(name));
8971#else
Victor Stinner65170952011-11-22 22:16:17 +01008972 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008973 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008974 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008975 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008976 }
Victor Stinner984890f2011-11-24 13:53:38 +01008977#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008978
Victor Stinner8c62be82010-05-06 00:08:46 +00008979 /* Remove the key from posix_putenv_garbage;
8980 * this will cause it to be collected. This has to
8981 * happen after the real unsetenv() call because the
8982 * old value was still accessible until then.
8983 */
Victor Stinner65170952011-11-22 22:16:17 +01008984 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008985 /* really not much we can do; just leak */
8986 PyErr_Clear();
8987 }
Victor Stinner65170952011-11-22 22:16:17 +01008988 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008989 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008990}
8991#endif /* unsetenv */
8992
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008993PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008994"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008995Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008996
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008998posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008999{
Victor Stinner8c62be82010-05-06 00:08:46 +00009000 int code;
9001 char *message;
9002 if (!PyArg_ParseTuple(args, "i:strerror", &code))
9003 return NULL;
9004 message = strerror(code);
9005 if (message == NULL) {
9006 PyErr_SetString(PyExc_ValueError,
9007 "strerror() argument out of range");
9008 return NULL;
9009 }
Victor Stinner1b579672011-12-17 05:47:23 +01009010 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009011}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009012
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009013
Guido van Rossumc9641791998-08-04 15:26:23 +00009014#ifdef HAVE_SYS_WAIT_H
9015
Fred Drake106c1a02002-04-23 15:58:02 +00009016#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009017PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009018"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009019Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00009020
9021static PyObject *
9022posix_WCOREDUMP(PyObject *self, PyObject *args)
9023{
Victor Stinner8c62be82010-05-06 00:08:46 +00009024 WAIT_TYPE status;
9025 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009026
Victor Stinner8c62be82010-05-06 00:08:46 +00009027 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
9028 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009029
Victor Stinner8c62be82010-05-06 00:08:46 +00009030 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009031}
9032#endif /* WCOREDUMP */
9033
9034#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009035PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009036"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00009037Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009038job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00009039
9040static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009041posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00009042{
Victor Stinner8c62be82010-05-06 00:08:46 +00009043 WAIT_TYPE status;
9044 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009045
Victor Stinner8c62be82010-05-06 00:08:46 +00009046 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
9047 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009048
Victor Stinner8c62be82010-05-06 00:08:46 +00009049 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009050}
9051#endif /* WIFCONTINUED */
9052
Guido van Rossumc9641791998-08-04 15:26:23 +00009053#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009054PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009055"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009056Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009057
9058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009059posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009060{
Victor Stinner8c62be82010-05-06 00:08:46 +00009061 WAIT_TYPE status;
9062 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009063
Victor Stinner8c62be82010-05-06 00:08:46 +00009064 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
9065 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009066
Victor Stinner8c62be82010-05-06 00:08:46 +00009067 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009068}
9069#endif /* WIFSTOPPED */
9070
9071#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009072PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009073"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009074Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009075
9076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009077posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009078{
Victor Stinner8c62be82010-05-06 00:08:46 +00009079 WAIT_TYPE status;
9080 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009081
Victor Stinner8c62be82010-05-06 00:08:46 +00009082 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9083 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009084
Victor Stinner8c62be82010-05-06 00:08:46 +00009085 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009086}
9087#endif /* WIFSIGNALED */
9088
9089#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009090PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009091"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009092Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009093system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009094
9095static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009096posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009097{
Victor Stinner8c62be82010-05-06 00:08:46 +00009098 WAIT_TYPE status;
9099 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009100
Victor Stinner8c62be82010-05-06 00:08:46 +00009101 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9102 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009103
Victor Stinner8c62be82010-05-06 00:08:46 +00009104 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009105}
9106#endif /* WIFEXITED */
9107
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009108#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009109PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009110"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009111Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009112
9113static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009114posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009115{
Victor Stinner8c62be82010-05-06 00:08:46 +00009116 WAIT_TYPE status;
9117 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009118
Victor Stinner8c62be82010-05-06 00:08:46 +00009119 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9120 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009121
Victor Stinner8c62be82010-05-06 00:08:46 +00009122 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009123}
9124#endif /* WEXITSTATUS */
9125
9126#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009127PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009128"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009129Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009130value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009131
9132static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009133posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009134{
Victor Stinner8c62be82010-05-06 00:08:46 +00009135 WAIT_TYPE status;
9136 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009137
Victor Stinner8c62be82010-05-06 00:08:46 +00009138 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9139 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009140
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009142}
9143#endif /* WTERMSIG */
9144
9145#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009146PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009147"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009148Return the signal that stopped the process that provided\n\
9149the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009150
9151static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009152posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009153{
Victor Stinner8c62be82010-05-06 00:08:46 +00009154 WAIT_TYPE status;
9155 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009156
Victor Stinner8c62be82010-05-06 00:08:46 +00009157 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9158 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009159
Victor Stinner8c62be82010-05-06 00:08:46 +00009160 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009161}
9162#endif /* WSTOPSIG */
9163
9164#endif /* HAVE_SYS_WAIT_H */
9165
9166
Thomas Wouters477c8d52006-05-27 19:21:47 +00009167#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009168#ifdef _SCO_DS
9169/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9170 needed definitions in sys/statvfs.h */
9171#define _SVID3
9172#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009173#include <sys/statvfs.h>
9174
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009175static PyObject*
9176_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009177 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9178 if (v == NULL)
9179 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009180
9181#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009182 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9183 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9184 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9185 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9186 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9187 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9188 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9189 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9190 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9191 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009192#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009193 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9194 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9195 PyStructSequence_SET_ITEM(v, 2,
9196 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9197 PyStructSequence_SET_ITEM(v, 3,
9198 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9199 PyStructSequence_SET_ITEM(v, 4,
9200 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9201 PyStructSequence_SET_ITEM(v, 5,
9202 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9203 PyStructSequence_SET_ITEM(v, 6,
9204 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9205 PyStructSequence_SET_ITEM(v, 7,
9206 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9207 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9208 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009209#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009210 if (PyErr_Occurred()) {
9211 Py_DECREF(v);
9212 return NULL;
9213 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009214
Victor Stinner8c62be82010-05-06 00:08:46 +00009215 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009216}
9217
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009218PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009219"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009220Perform an fstatvfs system call on the given fd.\n\
9221Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009222
9223static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009224posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009225{
Victor Stinner8c62be82010-05-06 00:08:46 +00009226 int fd, res;
9227 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009228
Victor Stinner8c62be82010-05-06 00:08:46 +00009229 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9230 return NULL;
9231 Py_BEGIN_ALLOW_THREADS
9232 res = fstatvfs(fd, &st);
9233 Py_END_ALLOW_THREADS
9234 if (res != 0)
9235 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009236
Victor Stinner8c62be82010-05-06 00:08:46 +00009237 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009238}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009239#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009240
9241
Thomas Wouters477c8d52006-05-27 19:21:47 +00009242#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009243#include <sys/statvfs.h>
9244
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009245PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009246"statvfs(path)\n\n\
9247Perform a statvfs system call on the given path.\n\
9248\n\
9249path may always be specified as a string.\n\
9250On some platforms, path may also be specified as an open file descriptor.\n\
9251 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009252
9253static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009254posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009255{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009256 static char *keywords[] = {"path", NULL};
9257 path_t path;
9258 int result;
9259 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009260 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009261
Larry Hastings9cf065c2012-06-22 16:30:09 -07009262 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009263 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009264#ifdef HAVE_FSTATVFS
9265 path.allow_fd = 1;
9266#endif
9267 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9268 path_converter, &path
9269 ))
9270 return NULL;
9271
9272 Py_BEGIN_ALLOW_THREADS
9273#ifdef HAVE_FSTATVFS
9274 if (path.fd != -1) {
9275#ifdef __APPLE__
9276 /* handle weak-linking on Mac OS X 10.3 */
9277 if (fstatvfs == NULL) {
9278 fd_specified("statvfs", path.fd);
9279 goto exit;
9280 }
9281#endif
9282 result = fstatvfs(path.fd, &st);
9283 }
9284 else
9285#endif
9286 result = statvfs(path.narrow, &st);
9287 Py_END_ALLOW_THREADS
9288
9289 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009290 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009291 goto exit;
9292 }
9293
9294 return_value = _pystatvfs_fromstructstatvfs(st);
9295
9296exit:
9297 path_cleanup(&path);
9298 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009299}
9300#endif /* HAVE_STATVFS */
9301
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009302#ifdef MS_WINDOWS
9303PyDoc_STRVAR(win32__getdiskusage__doc__,
9304"_getdiskusage(path) -> (total, free)\n\n\
9305Return disk usage statistics about the given path as (total, free) tuple.");
9306
9307static PyObject *
9308win32__getdiskusage(PyObject *self, PyObject *args)
9309{
9310 BOOL retval;
9311 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009312 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009313
Victor Stinner6139c1b2011-11-09 22:14:14 +01009314 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009315 return NULL;
9316
9317 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009318 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009319 Py_END_ALLOW_THREADS
9320 if (retval == 0)
9321 return PyErr_SetFromWindowsErr(0);
9322
9323 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9324}
9325#endif
9326
9327
Fred Drakec9680921999-12-13 16:37:25 +00009328/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9329 * It maps strings representing configuration variable names to
9330 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009331 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009332 * rarely-used constants. There are three separate tables that use
9333 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009334 *
9335 * This code is always included, even if none of the interfaces that
9336 * need it are included. The #if hackery needed to avoid it would be
9337 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009338 */
9339struct constdef {
9340 char *name;
9341 long value;
9342};
9343
Fred Drake12c6e2d1999-12-14 21:25:03 +00009344static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009345conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009346 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009347{
Christian Heimes217cfd12007-12-02 14:31:20 +00009348 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009349 *valuep = PyLong_AS_LONG(arg);
9350 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009351 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009352 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009353 /* look up the value in the table using a binary search */
9354 size_t lo = 0;
9355 size_t mid;
9356 size_t hi = tablesize;
9357 int cmp;
9358 const char *confname;
9359 if (!PyUnicode_Check(arg)) {
9360 PyErr_SetString(PyExc_TypeError,
9361 "configuration names must be strings or integers");
9362 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009364 confname = _PyUnicode_AsString(arg);
9365 if (confname == NULL)
9366 return 0;
9367 while (lo < hi) {
9368 mid = (lo + hi) / 2;
9369 cmp = strcmp(confname, table[mid].name);
9370 if (cmp < 0)
9371 hi = mid;
9372 else if (cmp > 0)
9373 lo = mid + 1;
9374 else {
9375 *valuep = table[mid].value;
9376 return 1;
9377 }
9378 }
9379 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9380 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009382}
9383
9384
9385#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9386static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009387#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009389#endif
9390#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009392#endif
Fred Drakec9680921999-12-13 16:37:25 +00009393#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009395#endif
9396#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009398#endif
9399#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009401#endif
9402#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009403 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009404#endif
9405#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009406 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009407#endif
9408#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009409 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009410#endif
9411#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009412 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009413#endif
9414#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009415 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009416#endif
9417#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009418 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009419#endif
9420#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009421 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009422#endif
9423#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009424 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009425#endif
9426#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009427 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009428#endif
9429#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009430 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009431#endif
9432#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009433 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009434#endif
9435#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009436 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009437#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009438#ifdef _PC_ACL_ENABLED
9439 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9440#endif
9441#ifdef _PC_MIN_HOLE_SIZE
9442 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9443#endif
9444#ifdef _PC_ALLOC_SIZE_MIN
9445 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9446#endif
9447#ifdef _PC_REC_INCR_XFER_SIZE
9448 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9449#endif
9450#ifdef _PC_REC_MAX_XFER_SIZE
9451 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9452#endif
9453#ifdef _PC_REC_MIN_XFER_SIZE
9454 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9455#endif
9456#ifdef _PC_REC_XFER_ALIGN
9457 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9458#endif
9459#ifdef _PC_SYMLINK_MAX
9460 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9461#endif
9462#ifdef _PC_XATTR_ENABLED
9463 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9464#endif
9465#ifdef _PC_XATTR_EXISTS
9466 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9467#endif
9468#ifdef _PC_TIMESTAMP_RESOLUTION
9469 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9470#endif
Fred Drakec9680921999-12-13 16:37:25 +00009471};
9472
Fred Drakec9680921999-12-13 16:37:25 +00009473static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009474conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009475{
9476 return conv_confname(arg, valuep, posix_constants_pathconf,
9477 sizeof(posix_constants_pathconf)
9478 / sizeof(struct constdef));
9479}
9480#endif
9481
9482#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009483PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009484"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009485Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009486If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009487
9488static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009489posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009490{
9491 PyObject *result = NULL;
9492 int name, fd;
9493
Fred Drake12c6e2d1999-12-14 21:25:03 +00009494 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9495 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009496 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009497
Stefan Krah0e803b32010-11-26 16:16:47 +00009498 errno = 0;
9499 limit = fpathconf(fd, name);
9500 if (limit == -1 && errno != 0)
9501 posix_error();
9502 else
9503 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009504 }
9505 return result;
9506}
9507#endif
9508
9509
9510#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009511PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009512"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009513Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009514If there is no limit, return -1.\n\
9515On some platforms, path may also be specified as an open file descriptor.\n\
9516 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009517
9518static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009519posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009520{
Georg Brandl306336b2012-06-24 12:55:33 +02009521 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009522 PyObject *result = NULL;
9523 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009524 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009525
Georg Brandl306336b2012-06-24 12:55:33 +02009526 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009527 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009528#ifdef HAVE_FPATHCONF
9529 path.allow_fd = 1;
9530#endif
9531 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9532 path_converter, &path,
9533 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009535
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009537#ifdef HAVE_FPATHCONF
9538 if (path.fd != -1)
9539 limit = fpathconf(path.fd, name);
9540 else
9541#endif
9542 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 if (limit == -1 && errno != 0) {
9544 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009545 /* could be a path or name problem */
9546 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009547 else
Victor Stinner292c8352012-10-30 02:17:38 +01009548 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 }
9550 else
9551 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009552 }
Georg Brandl306336b2012-06-24 12:55:33 +02009553 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009554 return result;
9555}
9556#endif
9557
9558#ifdef HAVE_CONFSTR
9559static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009560#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009562#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009563#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009565#endif
9566#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009568#endif
Fred Draked86ed291999-12-15 15:34:33 +00009569#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009571#endif
9572#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009574#endif
9575#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009577#endif
9578#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009580#endif
Fred Drakec9680921999-12-13 16:37:25 +00009581#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009583#endif
9584#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009586#endif
9587#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009589#endif
9590#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009592#endif
9593#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009595#endif
9596#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009598#endif
9599#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009601#endif
9602#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009604#endif
Fred Draked86ed291999-12-15 15:34:33 +00009605#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009607#endif
Fred Drakec9680921999-12-13 16:37:25 +00009608#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009610#endif
Fred Draked86ed291999-12-15 15:34:33 +00009611#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009613#endif
9614#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009616#endif
9617#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009619#endif
9620#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009622#endif
Fred Drakec9680921999-12-13 16:37:25 +00009623#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009625#endif
9626#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009628#endif
9629#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009630 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009631#endif
9632#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009633 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009634#endif
9635#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009636 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009637#endif
9638#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009640#endif
9641#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009643#endif
9644#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009646#endif
9647#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009649#endif
9650#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009652#endif
9653#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009655#endif
9656#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009658#endif
9659#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009661#endif
9662#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009664#endif
9665#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009666 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009667#endif
9668#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009670#endif
Fred Draked86ed291999-12-15 15:34:33 +00009671#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009673#endif
9674#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009676#endif
9677#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009679#endif
9680#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009682#endif
9683#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009685#endif
9686#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009688#endif
9689#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009691#endif
9692#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009694#endif
9695#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009697#endif
9698#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009700#endif
9701#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009703#endif
9704#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009706#endif
9707#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009709#endif
Fred Drakec9680921999-12-13 16:37:25 +00009710};
9711
9712static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009713conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009714{
9715 return conv_confname(arg, valuep, posix_constants_confstr,
9716 sizeof(posix_constants_confstr)
9717 / sizeof(struct constdef));
9718}
9719
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009720PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009721"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009722Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009723
9724static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009725posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009726{
9727 PyObject *result = NULL;
9728 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009729 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009730 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009731
Victor Stinnercb043522010-09-10 23:49:04 +00009732 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9733 return NULL;
9734
9735 errno = 0;
9736 len = confstr(name, buffer, sizeof(buffer));
9737 if (len == 0) {
9738 if (errno) {
9739 posix_error();
9740 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009741 }
9742 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009743 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009744 }
9745 }
Victor Stinnercb043522010-09-10 23:49:04 +00009746
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009747 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009748 char *buf = PyMem_Malloc(len);
9749 if (buf == NULL)
9750 return PyErr_NoMemory();
9751 confstr(name, buf, len);
9752 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9753 PyMem_Free(buf);
9754 }
9755 else
9756 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009757 return result;
9758}
9759#endif
9760
9761
9762#ifdef HAVE_SYSCONF
9763static struct constdef posix_constants_sysconf[] = {
9764#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
Fred Draked86ed291999-12-15 15:34:33 +00009794#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009796#endif
9797#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009799#endif
Fred Drakec9680921999-12-13 16:37:25 +00009800#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
Fred Drakec9680921999-12-13 16:37:25 +00009803#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
Fred Draked86ed291999-12-15 15:34:33 +00009818#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009820#endif
Fred Drakec9680921999-12-13 16:37:25 +00009821#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
Fred Draked86ed291999-12-15 15:34:33 +00009836#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009838#endif
Fred Drakec9680921999-12-13 16:37:25 +00009839#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
9872#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
9884#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
9887#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
9890#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
9893#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
Fred Draked86ed291999-12-15 15:34:33 +00009908#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009910#endif
Fred Drakec9680921999-12-13 16:37:25 +00009911#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
Fred Draked86ed291999-12-15 15:34:33 +00009920#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009922#endif
Fred Drakec9680921999-12-13 16:37:25 +00009923#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
Fred Draked86ed291999-12-15 15:34:33 +00009926#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009928#endif
9929#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009931#endif
Fred Drakec9680921999-12-13 16:37:25 +00009932#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
Fred Draked86ed291999-12-15 15:34:33 +00009944#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009946#endif
Fred Drakec9680921999-12-13 16:37:25 +00009947#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
Fred Draked86ed291999-12-15 15:34:33 +00009968#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009970#endif
Fred Drakec9680921999-12-13 16:37:25 +00009971#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
Fred Draked86ed291999-12-15 15:34:33 +00009977#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009979#endif
Fred Drakec9680921999-12-13 16:37:25 +00009980#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
Fred Draked86ed291999-12-15 15:34:33 +000010007#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010009#endif
10010#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010012#endif
Fred Drakec9680921999-12-13 16:37:25 +000010013#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
Fred Draked86ed291999-12-15 15:34:33 +000010118#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010120#endif
Fred Drakec9680921999-12-13 16:37:25 +000010121#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256};
10257
10258static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010259conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010260{
10261 return conv_confname(arg, valuep, posix_constants_sysconf,
10262 sizeof(posix_constants_sysconf)
10263 / sizeof(struct constdef));
10264}
10265
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010266PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010267"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010268Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010269
10270static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010271posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010272{
10273 PyObject *result = NULL;
10274 int name;
10275
10276 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +020010277 long value;
Fred Drakec9680921999-12-13 16:37:25 +000010278
10279 errno = 0;
10280 value = sysconf(name);
10281 if (value == -1 && errno != 0)
10282 posix_error();
10283 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010284 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010285 }
10286 return result;
10287}
10288#endif
10289
10290
Fred Drakebec628d1999-12-15 18:31:10 +000010291/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010292 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010293 * the exported dictionaries that are used to publish information about the
10294 * names available on the host platform.
10295 *
10296 * Sorting the table at runtime ensures that the table is properly ordered
10297 * when used, even for platforms we're not able to test on. It also makes
10298 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010299 */
Fred Drakebec628d1999-12-15 18:31:10 +000010300
10301static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010302cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010303{
10304 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010306 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010308
10309 return strcmp(c1->name, c2->name);
10310}
10311
10312static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010313setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010315{
Fred Drakebec628d1999-12-15 18:31:10 +000010316 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010317 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010318
10319 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10320 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010321 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010323
Barry Warsaw3155db32000-04-13 15:20:40 +000010324 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 PyObject *o = PyLong_FromLong(table[i].value);
10326 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10327 Py_XDECREF(o);
10328 Py_DECREF(d);
10329 return -1;
10330 }
10331 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010332 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010333 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010334}
10335
Fred Drakebec628d1999-12-15 18:31:10 +000010336/* Return -1 on failure, 0 on success. */
10337static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010338setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010339{
10340#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010341 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010342 sizeof(posix_constants_pathconf)
10343 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010344 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010345 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010346#endif
10347#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010348 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010349 sizeof(posix_constants_confstr)
10350 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010351 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010352 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010353#endif
10354#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010355 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010356 sizeof(posix_constants_sysconf)
10357 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010358 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010359 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010360#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010361 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010362}
Fred Draked86ed291999-12-15 15:34:33 +000010363
10364
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010365PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010366"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010367Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010368in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010369
10370static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010371posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010372{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010373 abort();
10374 /*NOTREACHED*/
10375 Py_FatalError("abort() called from Python code didn't abort!");
10376 return NULL;
10377}
Fred Drakebec628d1999-12-15 18:31:10 +000010378
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010379#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010380PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010381"startfile(filepath [, operation]) - Start a file with its associated\n\
10382application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010383\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010384When \"operation\" is not specified or \"open\", this acts like\n\
10385double-clicking the file in Explorer, or giving the file name as an\n\
10386argument to the DOS \"start\" command: the file is opened with whatever\n\
10387application (if any) its extension is associated.\n\
10388When another \"operation\" is given, it specifies what should be done with\n\
10389the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010390\n\
10391startfile returns as soon as the associated application is launched.\n\
10392There is no option to wait for the application to close, and no way\n\
10393to retrieve the application's exit status.\n\
10394\n\
10395The filepath is relative to the current directory. If you want to use\n\
10396an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010397the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010398
10399static PyObject *
10400win32_startfile(PyObject *self, PyObject *args)
10401{
Victor Stinner8c62be82010-05-06 00:08:46 +000010402 PyObject *ofilepath;
10403 char *filepath;
10404 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010405 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010406 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010407
Victor Stinnereb5657a2011-09-30 01:44:27 +020010408 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010409 if (!PyArg_ParseTuple(args, "U|s:startfile",
10410 &unipath, &operation)) {
10411 PyErr_Clear();
10412 goto normal;
10413 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010414
Victor Stinner8c62be82010-05-06 00:08:46 +000010415 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010416 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010418 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 PyErr_Clear();
10420 operation = NULL;
10421 goto normal;
10422 }
10423 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010424
Victor Stinnereb5657a2011-09-30 01:44:27 +020010425 wpath = PyUnicode_AsUnicode(unipath);
10426 if (wpath == NULL)
10427 goto normal;
10428 if (uoperation) {
10429 woperation = PyUnicode_AsUnicode(uoperation);
10430 if (woperation == NULL)
10431 goto normal;
10432 }
10433 else
10434 woperation = NULL;
10435
Victor Stinner8c62be82010-05-06 00:08:46 +000010436 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010437 rc = ShellExecuteW((HWND)0, woperation, wpath,
10438 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 Py_END_ALLOW_THREADS
10440
Victor Stinnereb5657a2011-09-30 01:44:27 +020010441 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010443 win32_error_object("startfile", unipath);
10444 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010445 }
10446 Py_INCREF(Py_None);
10447 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010448
10449normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010450 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10451 PyUnicode_FSConverter, &ofilepath,
10452 &operation))
10453 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010454 if (win32_warn_bytes_api()) {
10455 Py_DECREF(ofilepath);
10456 return NULL;
10457 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 filepath = PyBytes_AsString(ofilepath);
10459 Py_BEGIN_ALLOW_THREADS
10460 rc = ShellExecute((HWND)0, operation, filepath,
10461 NULL, NULL, SW_SHOWNORMAL);
10462 Py_END_ALLOW_THREADS
10463 if (rc <= (HINSTANCE)32) {
10464 PyObject *errval = win32_error("startfile", filepath);
10465 Py_DECREF(ofilepath);
10466 return errval;
10467 }
10468 Py_DECREF(ofilepath);
10469 Py_INCREF(Py_None);
10470 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010471}
10472#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010473
Martin v. Löwis438b5342002-12-27 10:16:42 +000010474#ifdef HAVE_GETLOADAVG
10475PyDoc_STRVAR(posix_getloadavg__doc__,
10476"getloadavg() -> (float, float, float)\n\n\
10477Return the number of processes in the system run queue averaged over\n\
10478the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10479was unobtainable");
10480
10481static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010482posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010483{
10484 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010485 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010486 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10487 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010488 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010489 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010490}
10491#endif
10492
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010493PyDoc_STRVAR(device_encoding__doc__,
10494"device_encoding(fd) -> str\n\n\
10495Return a string describing the encoding of the device\n\
10496if the output is a terminal; else return None.");
10497
10498static PyObject *
10499device_encoding(PyObject *self, PyObject *args)
10500{
Victor Stinner8c62be82010-05-06 00:08:46 +000010501 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010502
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10504 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010505
10506 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010507}
10508
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010509#ifdef HAVE_SETRESUID
10510PyDoc_STRVAR(posix_setresuid__doc__,
10511"setresuid(ruid, euid, suid)\n\n\
10512Set the current process's real, effective, and saved user ids.");
10513
10514static PyObject*
10515posix_setresuid (PyObject *self, PyObject *args)
10516{
Victor Stinner8c62be82010-05-06 00:08:46 +000010517 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010518 uid_t ruid, euid, suid;
10519 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10520 _Py_Uid_Converter, &ruid,
10521 _Py_Uid_Converter, &euid,
10522 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 return NULL;
10524 if (setresuid(ruid, euid, suid) < 0)
10525 return posix_error();
10526 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010527}
10528#endif
10529
10530#ifdef HAVE_SETRESGID
10531PyDoc_STRVAR(posix_setresgid__doc__,
10532"setresgid(rgid, egid, sgid)\n\n\
10533Set the current process's real, effective, and saved group ids.");
10534
10535static PyObject*
10536posix_setresgid (PyObject *self, PyObject *args)
10537{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010538 gid_t rgid, egid, sgid;
10539 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10540 _Py_Gid_Converter, &rgid,
10541 _Py_Gid_Converter, &egid,
10542 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 return NULL;
10544 if (setresgid(rgid, egid, sgid) < 0)
10545 return posix_error();
10546 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010547}
10548#endif
10549
10550#ifdef HAVE_GETRESUID
10551PyDoc_STRVAR(posix_getresuid__doc__,
10552"getresuid() -> (ruid, euid, suid)\n\n\
10553Get tuple of the current process's real, effective, and saved user ids.");
10554
10555static PyObject*
10556posix_getresuid (PyObject *self, PyObject *noargs)
10557{
Victor Stinner8c62be82010-05-06 00:08:46 +000010558 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 if (getresuid(&ruid, &euid, &suid) < 0)
10560 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010561 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10562 _PyLong_FromUid(euid),
10563 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010564}
10565#endif
10566
10567#ifdef HAVE_GETRESGID
10568PyDoc_STRVAR(posix_getresgid__doc__,
10569"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010570Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010571
10572static PyObject*
10573posix_getresgid (PyObject *self, PyObject *noargs)
10574{
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010576 if (getresgid(&rgid, &egid, &sgid) < 0)
10577 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010578 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10579 _PyLong_FromGid(egid),
10580 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010581}
10582#endif
10583
Benjamin Peterson9428d532011-09-14 11:45:52 -040010584#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010585
Benjamin Peterson799bd802011-08-31 22:15:17 -040010586PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010587"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10588Return the value of extended attribute attribute on path.\n\
10589\n\
10590path may be either a string or an open file descriptor.\n\
10591If follow_symlinks is False, and the last element of the path is a symbolic\n\
10592 link, getxattr will examine the symbolic link itself instead of the file\n\
10593 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010594
10595static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010596posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010597{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010598 path_t path;
10599 path_t attribute;
10600 int follow_symlinks = 1;
10601 PyObject *buffer = NULL;
10602 int i;
10603 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010604
Larry Hastings9cf065c2012-06-22 16:30:09 -070010605 memset(&path, 0, sizeof(path));
10606 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010607 path.function_name = "getxattr";
10608 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010609 path.allow_fd = 1;
10610 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10611 path_converter, &path,
10612 path_converter, &attribute,
10613 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010614 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010615
Larry Hastings9cf065c2012-06-22 16:30:09 -070010616 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10617 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010618
Larry Hastings9cf065c2012-06-22 16:30:09 -070010619 for (i = 0; ; i++) {
10620 void *ptr;
10621 ssize_t result;
10622 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10623 Py_ssize_t buffer_size = buffer_sizes[i];
10624 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010625 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010626 goto exit;
10627 }
10628 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10629 if (!buffer)
10630 goto exit;
10631 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010632
Larry Hastings9cf065c2012-06-22 16:30:09 -070010633 Py_BEGIN_ALLOW_THREADS;
10634 if (path.fd >= 0)
10635 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10636 else if (follow_symlinks)
10637 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10638 else
10639 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10640 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010641
Larry Hastings9cf065c2012-06-22 16:30:09 -070010642 if (result < 0) {
10643 Py_DECREF(buffer);
10644 buffer = NULL;
10645 if (errno == ERANGE)
10646 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010647 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010648 goto exit;
10649 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010650
Larry Hastings9cf065c2012-06-22 16:30:09 -070010651 if (result != buffer_size) {
10652 /* Can only shrink. */
10653 _PyBytes_Resize(&buffer, result);
10654 }
10655 break;
10656 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010657
Larry Hastings9cf065c2012-06-22 16:30:09 -070010658exit:
10659 path_cleanup(&path);
10660 path_cleanup(&attribute);
10661 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010662}
10663
10664PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010665"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10666Set extended attribute attribute on path to value.\n\
10667path may be either a string or an open file descriptor.\n\
10668If follow_symlinks is False, and the last element of the path is a symbolic\n\
10669 link, setxattr will modify the symbolic link itself instead of the file\n\
10670 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010671
10672static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010673posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010674{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010675 path_t path;
10676 path_t attribute;
10677 Py_buffer value;
10678 int flags = 0;
10679 int follow_symlinks = 1;
10680 int result;
10681 PyObject *return_value = NULL;
10682 static char *keywords[] = {"path", "attribute", "value",
10683 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010684
Larry Hastings9cf065c2012-06-22 16:30:09 -070010685 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010686 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010687 path.allow_fd = 1;
10688 memset(&attribute, 0, sizeof(attribute));
10689 memset(&value, 0, sizeof(value));
10690 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10691 keywords,
10692 path_converter, &path,
10693 path_converter, &attribute,
10694 &value, &flags,
10695 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010696 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010697
10698 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10699 goto exit;
10700
Benjamin Peterson799bd802011-08-31 22:15:17 -040010701 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010702 if (path.fd > -1)
10703 result = fsetxattr(path.fd, attribute.narrow,
10704 value.buf, value.len, flags);
10705 else if (follow_symlinks)
10706 result = setxattr(path.narrow, attribute.narrow,
10707 value.buf, value.len, flags);
10708 else
10709 result = lsetxattr(path.narrow, attribute.narrow,
10710 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010711 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010712
Larry Hastings9cf065c2012-06-22 16:30:09 -070010713 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010714 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010715 goto exit;
10716 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010717
Larry Hastings9cf065c2012-06-22 16:30:09 -070010718 return_value = Py_None;
10719 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010720
Larry Hastings9cf065c2012-06-22 16:30:09 -070010721exit:
10722 path_cleanup(&path);
10723 path_cleanup(&attribute);
10724 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010725
Larry Hastings9cf065c2012-06-22 16:30:09 -070010726 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010727}
10728
10729PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010730"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10731Remove extended attribute attribute on path.\n\
10732path may be either a string or an open file descriptor.\n\
10733If follow_symlinks is False, and the last element of the path is a symbolic\n\
10734 link, removexattr will modify the symbolic link itself instead of the file\n\
10735 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010736
10737static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010738posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010739{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010740 path_t path;
10741 path_t attribute;
10742 int follow_symlinks = 1;
10743 int result;
10744 PyObject *return_value = NULL;
10745 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010746
Larry Hastings9cf065c2012-06-22 16:30:09 -070010747 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010748 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010749 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010750 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010751 path.allow_fd = 1;
10752 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10753 keywords,
10754 path_converter, &path,
10755 path_converter, &attribute,
10756 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010757 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010758
10759 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10760 goto exit;
10761
Benjamin Peterson799bd802011-08-31 22:15:17 -040010762 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010763 if (path.fd > -1)
10764 result = fremovexattr(path.fd, attribute.narrow);
10765 else if (follow_symlinks)
10766 result = removexattr(path.narrow, attribute.narrow);
10767 else
10768 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010769 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010770
Larry Hastings9cf065c2012-06-22 16:30:09 -070010771 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010772 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010773 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010774 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010775
Larry Hastings9cf065c2012-06-22 16:30:09 -070010776 return_value = Py_None;
10777 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010778
Larry Hastings9cf065c2012-06-22 16:30:09 -070010779exit:
10780 path_cleanup(&path);
10781 path_cleanup(&attribute);
10782
10783 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010784}
10785
10786PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010787"listxattr(path='.', *, follow_symlinks=True)\n\n\
10788Return a list of extended attributes on path.\n\
10789\n\
10790path may be either None, a string, or an open file descriptor.\n\
10791if path is None, listxattr will examine the current directory.\n\
10792If follow_symlinks is False, and the last element of the path is a symbolic\n\
10793 link, listxattr will examine the symbolic link itself instead of the file\n\
10794 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010795
10796static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010797posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010798{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010799 path_t path;
10800 int follow_symlinks = 1;
10801 Py_ssize_t i;
10802 PyObject *result = NULL;
10803 char *buffer = NULL;
10804 char *name;
10805 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010806
Larry Hastings9cf065c2012-06-22 16:30:09 -070010807 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010808 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010809 path.allow_fd = 1;
10810 path.fd = -1;
10811 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10812 path_converter, &path,
10813 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010814 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010815
Larry Hastings9cf065c2012-06-22 16:30:09 -070010816 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10817 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010818
Larry Hastings9cf065c2012-06-22 16:30:09 -070010819 name = path.narrow ? path.narrow : ".";
10820 for (i = 0; ; i++) {
10821 char *start, *trace, *end;
10822 ssize_t length;
10823 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10824 Py_ssize_t buffer_size = buffer_sizes[i];
10825 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010826 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010827 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010828 break;
10829 }
10830 buffer = PyMem_MALLOC(buffer_size);
10831 if (!buffer) {
10832 PyErr_NoMemory();
10833 break;
10834 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010835
Larry Hastings9cf065c2012-06-22 16:30:09 -070010836 Py_BEGIN_ALLOW_THREADS;
10837 if (path.fd > -1)
10838 length = flistxattr(path.fd, buffer, buffer_size);
10839 else if (follow_symlinks)
10840 length = listxattr(name, buffer, buffer_size);
10841 else
10842 length = llistxattr(name, buffer, buffer_size);
10843 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010844
Larry Hastings9cf065c2012-06-22 16:30:09 -070010845 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010846 if (errno == ERANGE) {
10847 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010848 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010849 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010850 }
Victor Stinner292c8352012-10-30 02:17:38 +010010851 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010852 break;
10853 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010854
Larry Hastings9cf065c2012-06-22 16:30:09 -070010855 result = PyList_New(0);
10856 if (!result) {
10857 goto exit;
10858 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010859
Larry Hastings9cf065c2012-06-22 16:30:09 -070010860 end = buffer + length;
10861 for (trace = start = buffer; trace != end; trace++) {
10862 if (!*trace) {
10863 int error;
10864 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10865 trace - start);
10866 if (!attribute) {
10867 Py_DECREF(result);
10868 result = NULL;
10869 goto exit;
10870 }
10871 error = PyList_Append(result, attribute);
10872 Py_DECREF(attribute);
10873 if (error) {
10874 Py_DECREF(result);
10875 result = NULL;
10876 goto exit;
10877 }
10878 start = trace + 1;
10879 }
10880 }
10881 break;
10882 }
10883exit:
10884 path_cleanup(&path);
10885 if (buffer)
10886 PyMem_FREE(buffer);
10887 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010888}
10889
Benjamin Peterson9428d532011-09-14 11:45:52 -040010890#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010891
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010892
Georg Brandl2fb477c2012-02-21 00:33:36 +010010893PyDoc_STRVAR(posix_urandom__doc__,
10894"urandom(n) -> str\n\n\
10895Return n random bytes suitable for cryptographic use.");
10896
10897static PyObject *
10898posix_urandom(PyObject *self, PyObject *args)
10899{
10900 Py_ssize_t size;
10901 PyObject *result;
10902 int ret;
10903
10904 /* Read arguments */
10905 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10906 return NULL;
10907 if (size < 0)
10908 return PyErr_Format(PyExc_ValueError,
10909 "negative argument not allowed");
10910 result = PyBytes_FromStringAndSize(NULL, size);
10911 if (result == NULL)
10912 return NULL;
10913
10914 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10915 PyBytes_GET_SIZE(result));
10916 if (ret == -1) {
10917 Py_DECREF(result);
10918 return NULL;
10919 }
10920 return result;
10921}
10922
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010923/* Terminal size querying */
10924
10925static PyTypeObject TerminalSizeType;
10926
10927PyDoc_STRVAR(TerminalSize_docstring,
10928 "A tuple of (columns, lines) for holding terminal window size");
10929
10930static PyStructSequence_Field TerminalSize_fields[] = {
10931 {"columns", "width of the terminal window in characters"},
10932 {"lines", "height of the terminal window in characters"},
10933 {NULL, NULL}
10934};
10935
10936static PyStructSequence_Desc TerminalSize_desc = {
10937 "os.terminal_size",
10938 TerminalSize_docstring,
10939 TerminalSize_fields,
10940 2,
10941};
10942
10943#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10944PyDoc_STRVAR(termsize__doc__,
10945 "Return the size of the terminal window as (columns, lines).\n" \
10946 "\n" \
10947 "The optional argument fd (default standard output) specifies\n" \
10948 "which file descriptor should be queried.\n" \
10949 "\n" \
10950 "If the file descriptor is not connected to a terminal, an OSError\n" \
10951 "is thrown.\n" \
10952 "\n" \
10953 "This function will only be defined if an implementation is\n" \
10954 "available for this system.\n" \
10955 "\n" \
10956 "shutil.get_terminal_size is the high-level function which should \n" \
10957 "normally be used, os.get_terminal_size is the low-level implementation.");
10958
10959static PyObject*
10960get_terminal_size(PyObject *self, PyObject *args)
10961{
10962 int columns, lines;
10963 PyObject *termsize;
10964
10965 int fd = fileno(stdout);
10966 /* Under some conditions stdout may not be connected and
10967 * fileno(stdout) may point to an invalid file descriptor. For example
10968 * GUI apps don't have valid standard streams by default.
10969 *
10970 * If this happens, and the optional fd argument is not present,
10971 * the ioctl below will fail returning EBADF. This is what we want.
10972 */
10973
10974 if (!PyArg_ParseTuple(args, "|i", &fd))
10975 return NULL;
10976
10977#ifdef TERMSIZE_USE_IOCTL
10978 {
10979 struct winsize w;
10980 if (ioctl(fd, TIOCGWINSZ, &w))
10981 return PyErr_SetFromErrno(PyExc_OSError);
10982 columns = w.ws_col;
10983 lines = w.ws_row;
10984 }
10985#endif /* TERMSIZE_USE_IOCTL */
10986
10987#ifdef TERMSIZE_USE_CONIO
10988 {
10989 DWORD nhandle;
10990 HANDLE handle;
10991 CONSOLE_SCREEN_BUFFER_INFO csbi;
10992 switch (fd) {
10993 case 0: nhandle = STD_INPUT_HANDLE;
10994 break;
10995 case 1: nhandle = STD_OUTPUT_HANDLE;
10996 break;
10997 case 2: nhandle = STD_ERROR_HANDLE;
10998 break;
10999 default:
11000 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11001 }
11002 handle = GetStdHandle(nhandle);
11003 if (handle == NULL)
11004 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11005 if (handle == INVALID_HANDLE_VALUE)
11006 return PyErr_SetFromWindowsErr(0);
11007
11008 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11009 return PyErr_SetFromWindowsErr(0);
11010
11011 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11012 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11013 }
11014#endif /* TERMSIZE_USE_CONIO */
11015
11016 termsize = PyStructSequence_New(&TerminalSizeType);
11017 if (termsize == NULL)
11018 return NULL;
11019 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11020 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11021 if (PyErr_Occurred()) {
11022 Py_DECREF(termsize);
11023 return NULL;
11024 }
11025 return termsize;
11026}
11027#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11028
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011029PyDoc_STRVAR(posix_cpu_count__doc__,
11030"cpu_count() -> integer\n\n\
11031Return the number of CPUs in the system, or None if this value cannot be\n\
11032established.");
11033
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011034static PyObject *
11035posix_cpu_count(PyObject *self)
11036{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011037 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011038#ifdef MS_WINDOWS
11039 SYSTEM_INFO sysinfo;
11040 GetSystemInfo(&sysinfo);
11041 ncpu = sysinfo.dwNumberOfProcessors;
11042#elif defined(__hpux)
11043 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11044#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11045 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011046#elif defined(__DragonFly__) || \
11047 defined(__OpenBSD__) || \
11048 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011049 defined(__NetBSD__) || \
11050 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011051 int mib[2];
11052 size_t len = sizeof(ncpu);
11053 mib[0] = CTL_HW;
11054 mib[1] = HW_NCPU;
11055 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11056 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011057#endif
11058 if (ncpu >= 1)
11059 return PyLong_FromLong(ncpu);
11060 else
11061 Py_RETURN_NONE;
11062}
11063
Victor Stinnerdaf45552013-08-28 00:53:59 +020011064PyDoc_STRVAR(get_inheritable__doc__,
11065 "get_inheritable(fd) -> bool\n" \
11066 "\n" \
11067 "Get the close-on-exe flag of the specified file descriptor.");
11068
11069static PyObject*
11070posix_get_inheritable(PyObject *self, PyObject *args)
11071{
11072 int fd;
11073 int inheritable;
11074
11075 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd))
11076 return NULL;
11077
11078 if (!_PyVerify_fd(fd))
11079 return posix_error();
11080
11081 inheritable = _Py_get_inheritable(fd);
11082 if (inheritable < 0)
11083 return NULL;
11084 return PyBool_FromLong(inheritable);
11085}
11086
11087PyDoc_STRVAR(set_inheritable__doc__,
11088 "set_inheritable(fd, inheritable)\n" \
11089 "\n" \
11090 "Set the inheritable flag of the specified file descriptor.");
11091
11092static PyObject*
11093posix_set_inheritable(PyObject *self, PyObject *args)
11094{
11095 int fd, inheritable;
11096
11097 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable))
11098 return NULL;
11099
11100 if (!_PyVerify_fd(fd))
11101 return posix_error();
11102
11103 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
11104 return NULL;
11105 Py_RETURN_NONE;
11106}
11107
11108
11109#ifdef MS_WINDOWS
11110PyDoc_STRVAR(get_handle_inheritable__doc__,
11111 "get_handle_inheritable(fd) -> bool\n" \
11112 "\n" \
11113 "Get the close-on-exe flag of the specified file descriptor.");
11114
11115static PyObject*
11116posix_get_handle_inheritable(PyObject *self, PyObject *args)
11117{
11118 Py_intptr_t handle;
11119 DWORD flags;
11120
11121 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle))
11122 return NULL;
11123
11124 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11125 PyErr_SetFromWindowsErr(0);
11126 return NULL;
11127 }
11128
11129 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT);
11130}
11131
11132PyDoc_STRVAR(set_handle_inheritable__doc__,
11133 "set_handle_inheritable(fd, inheritable)\n" \
11134 "\n" \
11135 "Set the inheritable flag of the specified handle.");
11136
11137static PyObject*
11138posix_set_handle_inheritable(PyObject *self, PyObject *args)
11139{
11140 int inheritable = 1;
11141 Py_intptr_t handle;
11142 DWORD flags;
11143
11144 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable",
11145 &handle, &inheritable))
11146 return NULL;
11147
11148 if (inheritable)
11149 flags = HANDLE_FLAG_INHERIT;
11150 else
11151 flags = 0;
11152 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11153 PyErr_SetFromWindowsErr(0);
11154 return NULL;
11155 }
11156 Py_RETURN_NONE;
11157}
11158#endif /* MS_WINDOWS */
11159
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011160
Larry Hastings7726ac92014-01-31 22:03:12 -080011161/*[clinic input]
11162dump buffer
11163[clinic start generated code]*/
11164
11165#ifndef OS_TTYNAME_METHODDEF
11166 #define OS_TTYNAME_METHODDEF
11167#endif /* !defined(OS_TTYNAME_METHODDEF) */
11168/*[clinic end generated code: output=5d071bbc8f49ea12 input=524ce2e021e4eba6]*/
11169
Larry Hastings31826802013-10-19 00:09:25 -070011170
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011171static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070011172
11173 OS_STAT_METHODDEF
11174 OS_ACCESS_METHODDEF
11175 OS_TTYNAME_METHODDEF
11176
Larry Hastings9cf065c2012-06-22 16:30:09 -070011177 {"chdir", (PyCFunction)posix_chdir,
11178 METH_VARARGS | METH_KEYWORDS,
11179 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011180#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011181 {"chflags", (PyCFunction)posix_chflags,
11182 METH_VARARGS | METH_KEYWORDS,
11183 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011184#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011185 {"chmod", (PyCFunction)posix_chmod,
11186 METH_VARARGS | METH_KEYWORDS,
11187 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011188#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011189 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011190#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011191#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070011192 {"chown", (PyCFunction)posix_chown,
11193 METH_VARARGS | METH_KEYWORDS,
11194 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011195#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000011196#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011197 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011198#endif /* HAVE_LCHMOD */
11199#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011200 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011201#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000011202#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011203 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011204#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011205#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011206 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011207#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000011208#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000011209 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000011210#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011211#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000011212 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011213#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 {"getcwd", (PyCFunction)posix_getcwd_unicode,
11215 METH_NOARGS, posix_getcwd__doc__},
11216 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
11217 METH_NOARGS, posix_getcwdb__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011218#if defined(HAVE_LINK) || defined(MS_WINDOWS)
11219 {"link", (PyCFunction)posix_link,
11220 METH_VARARGS | METH_KEYWORDS,
11221 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011222#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011223 {"listdir", (PyCFunction)posix_listdir,
11224 METH_VARARGS | METH_KEYWORDS,
11225 posix_listdir__doc__},
11226 {"lstat", (PyCFunction)posix_lstat,
11227 METH_VARARGS | METH_KEYWORDS,
11228 posix_lstat__doc__},
11229 {"mkdir", (PyCFunction)posix_mkdir,
11230 METH_VARARGS | METH_KEYWORDS,
11231 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011232#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011233 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011234#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011235#ifdef HAVE_GETPRIORITY
11236 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11237#endif /* HAVE_GETPRIORITY */
11238#ifdef HAVE_SETPRIORITY
11239 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11240#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011241#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011242 {"readlink", (PyCFunction)posix_readlink,
11243 METH_VARARGS | METH_KEYWORDS,
11244 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011245#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011246#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011247 {"readlink", (PyCFunction)win_readlink,
11248 METH_VARARGS | METH_KEYWORDS,
11249 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011250#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011251 {"rename", (PyCFunction)posix_rename,
11252 METH_VARARGS | METH_KEYWORDS,
11253 posix_rename__doc__},
11254 {"replace", (PyCFunction)posix_replace,
11255 METH_VARARGS | METH_KEYWORDS,
11256 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011257 {"rmdir", (PyCFunction)posix_rmdir,
11258 METH_VARARGS | METH_KEYWORDS,
11259 posix_rmdir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011260 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011261#if defined(HAVE_SYMLINK)
11262 {"symlink", (PyCFunction)posix_symlink,
11263 METH_VARARGS | METH_KEYWORDS,
11264 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011265#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011266#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011267 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011268#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011269 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011270#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011271 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011272#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011273 {"unlink", (PyCFunction)posix_unlink,
11274 METH_VARARGS | METH_KEYWORDS,
11275 posix_unlink__doc__},
11276 {"remove", (PyCFunction)posix_unlink,
11277 METH_VARARGS | METH_KEYWORDS,
11278 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011279 {"utime", (PyCFunction)posix_utime,
11280 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011281#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011282 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011283#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011284 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011285#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011287 {"execve", (PyCFunction)posix_execve,
11288 METH_VARARGS | METH_KEYWORDS,
11289 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011290#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011291#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11293 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000011294#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011295#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011296 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011297#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011298#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011299 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011300#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011301#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011302#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011303 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11304 {"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 +020011305#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011306#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011307 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011308#endif
11309#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011310 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011311#endif
11312#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011313 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011314#endif
11315#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011316 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011317#endif
11318#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011319 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011320#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011321 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011322#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011323 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11324 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11325#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011326#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011327#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011328 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011329#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011330#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011331 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011332#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011333#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011334 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011335#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011336#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011338#endif /* HAVE_GETEUID */
11339#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011340 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011341#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011342#ifdef HAVE_GETGROUPLIST
11343 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11344#endif
Fred Drakec9680921999-12-13 16:37:25 +000011345#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011346 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011347#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011348 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011349#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011350 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011351#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011352#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011353 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011354#endif /* HAVE_GETPPID */
11355#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011356 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011357#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011358#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011359 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011360#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011361#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011362 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011363#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011364#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011365 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011366#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011367#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011368 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011369#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011370#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011371 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11372 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011373#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011374#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011376#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011377#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011378 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011379#endif /* HAVE_SETEUID */
11380#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011382#endif /* HAVE_SETEGID */
11383#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011384 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011385#endif /* HAVE_SETREUID */
11386#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011388#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011389#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011391#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011392#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011394#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011395#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011396 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011397#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011398#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011399 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011400#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011401#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011402 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011403#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011404#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011405 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011406#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011407#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011408 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011409#endif /* HAVE_WAIT3 */
11410#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011411 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011412#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011413#if defined(HAVE_WAITID) && !defined(__APPLE__)
11414 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11415#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011416#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011417 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011418#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011419#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011420 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011421#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011422#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011424#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011425#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011426 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011427#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011428#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011429 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011430#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011431#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011432 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011433#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011434 {"open", (PyCFunction)posix_open,\
11435 METH_VARARGS | METH_KEYWORDS,
11436 posix_open__doc__},
Benjamin Peterson932bba32014-02-11 10:16:16 -050011437 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011438 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11439 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11440 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011441 {"dup2", (PyCFunction)posix_dup2,
11442 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011443#ifdef HAVE_LOCKF
11444 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11445#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011446 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11447 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011448#ifdef HAVE_READV
11449 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11450#endif
11451#ifdef HAVE_PREAD
11452 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11453#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011455#ifdef HAVE_WRITEV
11456 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11457#endif
11458#ifdef HAVE_PWRITE
11459 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11460#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011461#ifdef HAVE_SENDFILE
11462 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11463 posix_sendfile__doc__},
11464#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011465 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011466 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011467#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011468 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011469#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011470#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011471 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011472#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011473#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011474 {"mkfifo", (PyCFunction)posix_mkfifo,
11475 METH_VARARGS | METH_KEYWORDS,
11476 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011477#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011478#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011479 {"mknod", (PyCFunction)posix_mknod,
11480 METH_VARARGS | METH_KEYWORDS,
11481 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011482#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011483#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011484 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11485 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11486 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011487#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011488#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011489 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011490#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011491#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011492 {"truncate", (PyCFunction)posix_truncate,
11493 METH_VARARGS | METH_KEYWORDS,
11494 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011495#endif
Victor Stinnerd6b17692014-09-30 12:20:05 +020011496#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011497 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11498#endif
Victor Stinnerd6b17692014-09-30 12:20:05 +020011499#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011500 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11501#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011502#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011503 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011504#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011505#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011506 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011507#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011508 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011509#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011510 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011511#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011512#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011513 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011514#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011515#ifdef HAVE_SYNC
11516 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11517#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011518#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011519 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011520#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011521#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011522#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011523 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011524#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011525#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011526 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011527#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011528#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011529 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011530#endif /* WIFSTOPPED */
11531#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011532 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011533#endif /* WIFSIGNALED */
11534#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011535 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011536#endif /* WIFEXITED */
11537#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011538 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011539#endif /* WEXITSTATUS */
11540#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011541 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011542#endif /* WTERMSIG */
11543#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011544 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011545#endif /* WSTOPSIG */
11546#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011547#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011549#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011550#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011551 {"statvfs", (PyCFunction)posix_statvfs,
11552 METH_VARARGS | METH_KEYWORDS,
11553 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011554#endif
Fred Drakec9680921999-12-13 16:37:25 +000011555#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011556 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011557#endif
11558#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011559 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011560#endif
11561#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011562 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011563#endif
11564#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011565 {"pathconf", (PyCFunction)posix_pathconf,
11566 METH_VARARGS | METH_KEYWORDS,
11567 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011568#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011569 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011570#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011571 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011572 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011573 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011574 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011575 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011576#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011577#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011578 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011579#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011580 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011581#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011582 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011583#endif
11584#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011585 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011586#endif
11587#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011588 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011589#endif
11590#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011591 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011592#endif
11593
Benjamin Peterson9428d532011-09-14 11:45:52 -040011594#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011595 {"setxattr", (PyCFunction)posix_setxattr,
11596 METH_VARARGS | METH_KEYWORDS,
11597 posix_setxattr__doc__},
11598 {"getxattr", (PyCFunction)posix_getxattr,
11599 METH_VARARGS | METH_KEYWORDS,
11600 posix_getxattr__doc__},
11601 {"removexattr", (PyCFunction)posix_removexattr,
11602 METH_VARARGS | METH_KEYWORDS,
11603 posix_removexattr__doc__},
11604 {"listxattr", (PyCFunction)posix_listxattr,
11605 METH_VARARGS | METH_KEYWORDS,
11606 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011607#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011608#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11609 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11610#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011611 {"cpu_count", (PyCFunction)posix_cpu_count,
11612 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011613 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__},
11614 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__},
11615#ifdef MS_WINDOWS
11616 {"get_handle_inheritable", posix_get_handle_inheritable,
11617 METH_VARARGS, get_handle_inheritable__doc__},
11618 {"set_handle_inheritable", posix_set_handle_inheritable,
11619 METH_VARARGS, set_handle_inheritable__doc__},
11620#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011621 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011622};
11623
11624
Brian Curtin52173d42010-12-02 18:29:18 +000011625#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011626static int
Brian Curtin52173d42010-12-02 18:29:18 +000011627enable_symlink()
11628{
11629 HANDLE tok;
11630 TOKEN_PRIVILEGES tok_priv;
11631 LUID luid;
11632 int meth_idx = 0;
11633
11634 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011635 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011636
11637 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011638 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011639
11640 tok_priv.PrivilegeCount = 1;
11641 tok_priv.Privileges[0].Luid = luid;
11642 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11643
11644 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11645 sizeof(TOKEN_PRIVILEGES),
11646 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011647 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011648
Brian Curtin3b4499c2010-12-28 14:31:47 +000011649 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11650 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011651}
11652#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11653
Barry Warsaw4a342091996-12-19 23:50:02 +000011654static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011655all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011656{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011657#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011658 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011659#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011660#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011661 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011662#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011663#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011664 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011665#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011666#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011667 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011668#endif
Fred Drakec9680921999-12-13 16:37:25 +000011669#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011670 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011671#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011672#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011673 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011674#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011675#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011676 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011677#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011678#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011679 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011680#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011681#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011682 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011683#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011684#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011685 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011686#endif
11687#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011688 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011689#endif
11690#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011691 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011692#endif
11693#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011694 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011695#endif
11696#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011697 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011698#endif
11699#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011700 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011701#endif
11702#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011703 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011704#endif
11705#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011706 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011707#endif
11708#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011709 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011710#endif
11711#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011712 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011713#endif
11714#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011715 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011716#endif
11717#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011718 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011719#endif
11720#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011721 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011722#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011723#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011724 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011725#endif
11726#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011727 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011728#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011729#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011730 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011731#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011732#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011733 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011734#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011735#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011736 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011737#endif
11738#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011739 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011740#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011741#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011742 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011743#endif
11744#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011745 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011746#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011747#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011748 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011749#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011750#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011751 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011752#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011753#ifdef O_TMPFILE
11754 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11755#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011756#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011757 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011758#endif
11759#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011760 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011761#endif
11762#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011763 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011764#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011765#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011766 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011767#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011768#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011769 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011770#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011771
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011772
Jesus Cea94363612012-06-22 18:32:07 +020011773#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011774 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011775#endif
11776#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011777 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011778#endif
11779
Tim Peters5aa91602002-01-30 05:46:57 +000011780/* MS Windows */
11781#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011782 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011783 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011784#endif
11785#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011786 /* Optimize for short life (keep in memory). */
11787 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011788 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011789#endif
11790#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011791 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011792 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011793#endif
11794#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011795 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011796 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011797#endif
11798#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011799 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011800 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011801#endif
11802
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011803/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011804#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011805 /* Send a SIGIO signal whenever input or output
11806 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011807 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011808#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011809#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011810 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011811 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011812#endif
11813#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011814 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011815 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011816#endif
11817#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011818 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011819 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011820#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011821#ifdef O_NOLINKS
11822 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011823 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011824#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011825#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011826 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011827 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011828#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011829
Victor Stinner8c62be82010-05-06 00:08:46 +000011830 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011831#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011832 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011833#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011834#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011835 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011836#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011837#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011838 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011839#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011840#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011841 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011842#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011843#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011844 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011845#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011846#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011847 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011848#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011849#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011850 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011851#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011852#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011853 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011854#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011855#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011856 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011857#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011858#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011859 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011860#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011861#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011862 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011863#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011864#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011865 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011866#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011867#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011868 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011869#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011870#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011871 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011872#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011873#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011874 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011875#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011876#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011877 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011878#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011879#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011880 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011881#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011882
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011883 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011884#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011885 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011886#endif /* ST_RDONLY */
11887#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011888 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011889#endif /* ST_NOSUID */
11890
doko@ubuntu.comca616a22013-12-08 15:23:07 +010011891 /* GNU extensions */
11892#ifdef ST_NODEV
11893 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
11894#endif /* ST_NODEV */
11895#ifdef ST_NOEXEC
11896 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
11897#endif /* ST_NOEXEC */
11898#ifdef ST_SYNCHRONOUS
11899 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
11900#endif /* ST_SYNCHRONOUS */
11901#ifdef ST_MANDLOCK
11902 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
11903#endif /* ST_MANDLOCK */
11904#ifdef ST_WRITE
11905 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
11906#endif /* ST_WRITE */
11907#ifdef ST_APPEND
11908 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
11909#endif /* ST_APPEND */
11910#ifdef ST_NOATIME
11911 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
11912#endif /* ST_NOATIME */
11913#ifdef ST_NODIRATIME
11914 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
11915#endif /* ST_NODIRATIME */
11916#ifdef ST_RELATIME
11917 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
11918#endif /* ST_RELATIME */
11919
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011920 /* FreeBSD sendfile() constants */
11921#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011922 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011923#endif
11924#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011925 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011926#endif
11927#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011928 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011929#endif
11930
Ross Lagerwall7807c352011-03-17 20:20:30 +020011931 /* constants for posix_fadvise */
11932#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011933 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011934#endif
11935#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011936 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011937#endif
11938#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011939 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011940#endif
11941#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011942 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011943#endif
11944#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011945 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011946#endif
11947#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011948 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011949#endif
11950
11951 /* constants for waitid */
11952#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011953 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11954 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
11955 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011956#endif
11957#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011958 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011959#endif
11960#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011961 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011962#endif
11963#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011964 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011965#endif
11966#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011967 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011968#endif
11969#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011970 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011971#endif
11972#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011973 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011974#endif
11975#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011976 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011977#endif
11978
11979 /* constants for lockf */
11980#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011981 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011982#endif
11983#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011984 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011985#endif
11986#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011987 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011988#endif
11989#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011990 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011991#endif
11992
Guido van Rossum246bc171999-02-01 23:54:31 +000011993#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011994 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
11995 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
11996 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
11997 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
11998 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011999#endif
12000
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012001#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012002 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12003 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12004 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012005#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012006 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012007#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012008#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012009 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012010#endif
12011#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012012 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012013#endif
12014#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012015 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012016#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012017#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012018 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012019#endif
12020#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012021 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012022#endif
12023#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012024 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012025#endif
12026#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012027 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012028#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012029#endif
12030
Benjamin Peterson9428d532011-09-14 11:45:52 -040012031#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012032 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12033 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12034 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012035#endif
12036
Victor Stinner8b905bd2011-10-25 13:34:04 +020012037#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012038 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012039#endif
12040#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012041 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012042#endif
12043#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012044 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012045#endif
12046#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012047 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012048#endif
12049#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012050 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012051#endif
12052#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012053 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012054#endif
12055#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012056 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012057#endif
12058
Victor Stinner8c62be82010-05-06 00:08:46 +000012059 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012060}
12061
12062
Tim Peters5aa91602002-01-30 05:46:57 +000012063#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000012064#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012065#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000012066
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000012067#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000012068#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012069#define MODNAME "posix"
12070#endif
12071
Martin v. Löwis1a214512008-06-11 05:26:20 +000012072static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012073 PyModuleDef_HEAD_INIT,
12074 MODNAME,
12075 posix__doc__,
12076 -1,
12077 posix_methods,
12078 NULL,
12079 NULL,
12080 NULL,
12081 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012082};
12083
12084
Larry Hastings9cf065c2012-06-22 16:30:09 -070012085static char *have_functions[] = {
12086
12087#ifdef HAVE_FACCESSAT
12088 "HAVE_FACCESSAT",
12089#endif
12090
12091#ifdef HAVE_FCHDIR
12092 "HAVE_FCHDIR",
12093#endif
12094
12095#ifdef HAVE_FCHMOD
12096 "HAVE_FCHMOD",
12097#endif
12098
12099#ifdef HAVE_FCHMODAT
12100 "HAVE_FCHMODAT",
12101#endif
12102
12103#ifdef HAVE_FCHOWN
12104 "HAVE_FCHOWN",
12105#endif
12106
Larry Hastings00964ed2013-08-12 13:49:30 -040012107#ifdef HAVE_FCHOWNAT
12108 "HAVE_FCHOWNAT",
12109#endif
12110
Larry Hastings9cf065c2012-06-22 16:30:09 -070012111#ifdef HAVE_FEXECVE
12112 "HAVE_FEXECVE",
12113#endif
12114
12115#ifdef HAVE_FDOPENDIR
12116 "HAVE_FDOPENDIR",
12117#endif
12118
Georg Brandl306336b2012-06-24 12:55:33 +020012119#ifdef HAVE_FPATHCONF
12120 "HAVE_FPATHCONF",
12121#endif
12122
Larry Hastings9cf065c2012-06-22 16:30:09 -070012123#ifdef HAVE_FSTATAT
12124 "HAVE_FSTATAT",
12125#endif
12126
12127#ifdef HAVE_FSTATVFS
12128 "HAVE_FSTATVFS",
12129#endif
12130
Georg Brandl306336b2012-06-24 12:55:33 +020012131#ifdef HAVE_FTRUNCATE
12132 "HAVE_FTRUNCATE",
12133#endif
12134
Larry Hastings9cf065c2012-06-22 16:30:09 -070012135#ifdef HAVE_FUTIMENS
12136 "HAVE_FUTIMENS",
12137#endif
12138
12139#ifdef HAVE_FUTIMES
12140 "HAVE_FUTIMES",
12141#endif
12142
12143#ifdef HAVE_FUTIMESAT
12144 "HAVE_FUTIMESAT",
12145#endif
12146
12147#ifdef HAVE_LINKAT
12148 "HAVE_LINKAT",
12149#endif
12150
12151#ifdef HAVE_LCHFLAGS
12152 "HAVE_LCHFLAGS",
12153#endif
12154
12155#ifdef HAVE_LCHMOD
12156 "HAVE_LCHMOD",
12157#endif
12158
12159#ifdef HAVE_LCHOWN
12160 "HAVE_LCHOWN",
12161#endif
12162
12163#ifdef HAVE_LSTAT
12164 "HAVE_LSTAT",
12165#endif
12166
12167#ifdef HAVE_LUTIMES
12168 "HAVE_LUTIMES",
12169#endif
12170
12171#ifdef HAVE_MKDIRAT
12172 "HAVE_MKDIRAT",
12173#endif
12174
12175#ifdef HAVE_MKFIFOAT
12176 "HAVE_MKFIFOAT",
12177#endif
12178
12179#ifdef HAVE_MKNODAT
12180 "HAVE_MKNODAT",
12181#endif
12182
12183#ifdef HAVE_OPENAT
12184 "HAVE_OPENAT",
12185#endif
12186
12187#ifdef HAVE_READLINKAT
12188 "HAVE_READLINKAT",
12189#endif
12190
12191#ifdef HAVE_RENAMEAT
12192 "HAVE_RENAMEAT",
12193#endif
12194
12195#ifdef HAVE_SYMLINKAT
12196 "HAVE_SYMLINKAT",
12197#endif
12198
12199#ifdef HAVE_UNLINKAT
12200 "HAVE_UNLINKAT",
12201#endif
12202
12203#ifdef HAVE_UTIMENSAT
12204 "HAVE_UTIMENSAT",
12205#endif
12206
12207#ifdef MS_WINDOWS
12208 "MS_WINDOWS",
12209#endif
12210
12211 NULL
12212};
12213
12214
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012215PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012216INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012217{
Victor Stinner8c62be82010-05-06 00:08:46 +000012218 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012219 PyObject *list;
12220 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012221
Brian Curtin52173d42010-12-02 18:29:18 +000012222#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012223 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012224#endif
12225
Victor Stinner8c62be82010-05-06 00:08:46 +000012226 m = PyModule_Create(&posixmodule);
12227 if (m == NULL)
12228 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012229
Victor Stinner8c62be82010-05-06 00:08:46 +000012230 /* Initialize environ dictionary */
12231 v = convertenviron();
12232 Py_XINCREF(v);
12233 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12234 return NULL;
12235 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012236
Victor Stinner8c62be82010-05-06 00:08:46 +000012237 if (all_ins(m))
12238 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012239
Victor Stinner8c62be82010-05-06 00:08:46 +000012240 if (setup_confname_tables(m))
12241 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012242
Victor Stinner8c62be82010-05-06 00:08:46 +000012243 Py_INCREF(PyExc_OSError);
12244 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012245
Guido van Rossumb3d39562000-01-31 18:41:26 +000012246#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012247 if (posix_putenv_garbage == NULL)
12248 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012249#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012250
Victor Stinner8c62be82010-05-06 00:08:46 +000012251 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012252#if defined(HAVE_WAITID) && !defined(__APPLE__)
12253 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012254 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12255 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012256#endif
12257
Christian Heimes25827622013-10-12 01:27:08 +020012258 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012259 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12260 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12261 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012262 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12263 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012264 structseq_new = StatResultType.tp_new;
12265 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012266
Christian Heimes25827622013-10-12 01:27:08 +020012267 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012268 if (PyStructSequence_InitType2(&StatVFSResultType,
12269 &statvfs_result_desc) < 0)
12270 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012271#ifdef NEED_TICKS_PER_SECOND
12272# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012273 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012274# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012275 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012276# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012277 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012278# endif
12279#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012280
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012281#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012282 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012283 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12284 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012285 SchedParamType.tp_new = sched_param_new;
12286#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012287
12288 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012289 if (PyStructSequence_InitType2(&TerminalSizeType,
12290 &TerminalSize_desc) < 0)
12291 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012292 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012293#if defined(HAVE_WAITID) && !defined(__APPLE__)
12294 Py_INCREF((PyObject*) &WaitidResultType);
12295 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12296#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012297 Py_INCREF((PyObject*) &StatResultType);
12298 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12299 Py_INCREF((PyObject*) &StatVFSResultType);
12300 PyModule_AddObject(m, "statvfs_result",
12301 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012302
12303#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012304 Py_INCREF(&SchedParamType);
12305 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012306#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012307
Larry Hastings605a62d2012-06-24 04:33:36 -070012308 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012309 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12310 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012311 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12312
12313 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012314 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12315 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012316 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12317
Thomas Wouters477c8d52006-05-27 19:21:47 +000012318#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012319 /*
12320 * Step 2 of weak-linking support on Mac OS X.
12321 *
12322 * The code below removes functions that are not available on the
12323 * currently active platform.
12324 *
12325 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012326 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012327 * OSX 10.4.
12328 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012329#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012330 if (fstatvfs == NULL) {
12331 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12332 return NULL;
12333 }
12334 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012335#endif /* HAVE_FSTATVFS */
12336
12337#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012338 if (statvfs == NULL) {
12339 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12340 return NULL;
12341 }
12342 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012343#endif /* HAVE_STATVFS */
12344
12345# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012346 if (lchown == NULL) {
12347 if (PyObject_DelAttrString(m, "lchown") == -1) {
12348 return NULL;
12349 }
12350 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012351#endif /* HAVE_LCHOWN */
12352
12353
12354#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012355
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012356 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012357 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12358
Larry Hastings6fe20b32012-04-19 15:07:49 -070012359 billion = PyLong_FromLong(1000000000);
12360 if (!billion)
12361 return NULL;
12362
Larry Hastings9cf065c2012-06-22 16:30:09 -070012363 /* suppress "function not used" warnings */
12364 {
12365 int ignored;
12366 fd_specified("", -1);
12367 follow_symlinks_specified("", 1);
12368 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12369 dir_fd_converter(Py_None, &ignored);
12370 dir_fd_unavailable(Py_None, &ignored);
12371 }
12372
12373 /*
12374 * provide list of locally available functions
12375 * so os.py can populate support_* lists
12376 */
12377 list = PyList_New(0);
12378 if (!list)
12379 return NULL;
12380 for (trace = have_functions; *trace; trace++) {
12381 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12382 if (!unicode)
12383 return NULL;
12384 if (PyList_Append(list, unicode))
12385 return NULL;
12386 Py_DECREF(unicode);
12387 }
12388 PyModule_AddObject(m, "_have_functions", list);
12389
12390 initialized = 1;
12391
Victor Stinner8c62be82010-05-06 00:08:46 +000012392 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000012393}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012394
12395#ifdef __cplusplus
12396}
12397#endif