blob: d45f59e5f1b6763eb71d14df31b5c488ca61a119 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Jesus Ceaab70e2a2012-10-05 01:48:08 +02009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020028#ifndef MS_WINDOWS
29#include "posixmodule.h"
30#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000031
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000032#ifdef __cplusplus
33extern "C" {
34#endif
35
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000036PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000037"This module provides access to operating system functionality that is\n\
38standardized by the C Standard and the POSIX standard (a thinly\n\
39disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000040corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000042
Ross Lagerwall4d076da2011-03-18 06:56:53 +020043#ifdef HAVE_SYS_UIO_H
44#include <sys/uio.h>
45#endif
46
Thomas Wouters0e3f5912006-08-11 14:57:12 +000047#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000048#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049#endif /* HAVE_SYS_TYPES_H */
50
51#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000052#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000053#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000054
Guido van Rossum36bc6801995-06-14 22:54:23 +000055#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000056#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000057#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000058
Thomas Wouters0e3f5912006-08-11 14:57:12 +000059#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000060#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000061#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000062
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#ifdef HAVE_FCNTL_H
64#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000065#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000066
Guido van Rossuma6535fd2001-10-18 19:44:10 +000067#ifdef HAVE_GRP_H
68#include <grp.h>
69#endif
70
Barry Warsaw5676bd12003-01-07 20:57:09 +000071#ifdef HAVE_SYSEXITS_H
72#include <sysexits.h>
73#endif /* HAVE_SYSEXITS_H */
74
Anthony Baxter8a560de2004-10-13 15:30:56 +000075#ifdef HAVE_SYS_LOADAVG_H
76#include <sys/loadavg.h>
77#endif
78
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000079#ifdef HAVE_LANGINFO_H
80#include <langinfo.h>
81#endif
82
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000083#ifdef HAVE_SYS_SENDFILE_H
84#include <sys/sendfile.h>
85#endif
86
Benjamin Peterson94b580d2011-08-02 17:30:04 -050087#ifdef HAVE_SCHED_H
88#include <sched.h>
89#endif
90
Benjamin Peterson2dbda072012-03-16 10:12:55 -050091#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050092#undef HAVE_SCHED_SETAFFINITY
93#endif
94
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +020095#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -040096#define USE_XATTRS
97#endif
98
99#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400100#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400101#endif
102
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000103#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
104#ifdef HAVE_SYS_SOCKET_H
105#include <sys/socket.h>
106#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000107#endif
108
Victor Stinner8b905bd2011-10-25 13:34:04 +0200109#ifdef HAVE_DLFCN_H
110#include <dlfcn.h>
111#endif
112
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200113#ifdef __hpux
114#include <sys/mpctl.h>
115#endif
116
117#if defined(__DragonFly__) || \
118 defined(__OpenBSD__) || \
119 defined(__FreeBSD__) || \
120 defined(__NetBSD__) || \
121 defined(__APPLE__)
122#include <sys/sysctl.h>
123#endif
124
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100125#if defined(MS_WINDOWS)
126# define TERMSIZE_USE_CONIO
127#elif defined(HAVE_SYS_IOCTL_H)
128# include <sys/ioctl.h>
129# if defined(HAVE_TERMIOS_H)
130# include <termios.h>
131# endif
132# if defined(TIOCGWINSZ)
133# define TERMSIZE_USE_IOCTL
134# endif
135#endif /* MS_WINDOWS */
136
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000138/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000139#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000141#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142#include <process.h>
143#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#define HAVE_EXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#define HAVE_OPENDIR 1
147#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000148#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_WAIT 1
150#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000152#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000153#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000154#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#define HAVE_EXECV 1
156#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000157#define HAVE_SYSTEM 1
158#define HAVE_CWAIT 1
159#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000160#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000161#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162/* Unix functions that the configure script doesn't check for */
163#define HAVE_EXECV 1
164#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000166#define HAVE_FORK1 1
167#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#define HAVE_GETEGID 1
169#define HAVE_GETEUID 1
170#define HAVE_GETGID 1
171#define HAVE_GETPPID 1
172#define HAVE_GETUID 1
173#define HAVE_KILL 1
174#define HAVE_OPENDIR 1
175#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000176#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000178#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000179#endif /* _MSC_VER */
180#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000181#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000182
Victor Stinnera2f7c002012-02-08 03:36:25 +0100183
Larry Hastings61272b72014-01-07 12:41:53 -0800184/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800185module os
Larry Hastings61272b72014-01-07 12:41:53 -0800186[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -0800187/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8cff096d1133288f]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100188
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000189#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000190
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000191#if defined(__sgi)&&_COMPILER_VERSION>=700
192/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
193 (default) */
194extern char *ctermid_r(char *);
195#endif
196
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000197#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000198#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000199extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000200#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000201#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000202extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000205#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#endif
207#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int chdir(char *);
209extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000210#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000211extern int chdir(const char *);
212extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000213#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000214#ifdef __BORLANDC__
215extern int chmod(const char *, int);
216#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000218#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000219/*#ifdef HAVE_FCHMOD
220extern int fchmod(int, mode_t);
221#endif*/
222/*#ifdef HAVE_LCHMOD
223extern int lchmod(const char *, mode_t);
224#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int chown(const char *, uid_t, gid_t);
226extern char *getcwd(char *, int);
227extern char *strerror(int);
228extern int link(const char *, const char *);
229extern int rename(const char *, const char *);
230extern int stat(const char *, struct stat *);
231extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000233extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000234#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000236extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000237#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000239
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#ifdef HAVE_UTIME_H
243#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000246#ifdef HAVE_SYS_UTIME_H
247#include <sys/utime.h>
248#define HAVE_UTIME_H /* pretend we do for the rest of this file */
249#endif /* HAVE_SYS_UTIME_H */
250
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#ifdef HAVE_SYS_TIMES_H
252#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
255#ifdef HAVE_SYS_PARAM_H
256#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258
259#ifdef HAVE_SYS_UTSNAME_H
260#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000261#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000263#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000265#define NAMLEN(dirent) strlen((dirent)->d_name)
266#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000267#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000268#include <direct.h>
269#define NAMLEN(dirent) strlen((dirent)->d_name)
270#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000273#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#endif
277#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000279#endif
280#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#endif
283#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000285#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000286#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000288#endif
289#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000291#endif
292#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000295#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000296#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000297#endif
298#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000299#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000300#endif
301#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000302#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000303#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000304#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000305#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000306#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000307#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000308#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000309#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
310#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000311static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000312#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000313#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000314
Tim Petersbc2e10e2002-03-03 23:17:02 +0000315#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000316#if defined(PATH_MAX) && PATH_MAX > 1024
317#define MAXPATHLEN PATH_MAX
318#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000319#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000321#endif /* MAXPATHLEN */
322
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000323#ifdef UNION_WAIT
324/* Emulate some macros on systems that have a union instead of macros */
325
326#ifndef WIFEXITED
327#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
328#endif
329
330#ifndef WEXITSTATUS
331#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
332#endif
333
334#ifndef WTERMSIG
335#define WTERMSIG(u_wait) ((u_wait).w_termsig)
336#endif
337
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000338#define WAIT_TYPE union wait
339#define WAIT_STATUS_INT(s) (s.w_status)
340
341#else /* !UNION_WAIT */
342#define WAIT_TYPE int
343#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000344#endif /* UNION_WAIT */
345
Greg Wardb48bc172000-03-01 21:51:56 +0000346/* Don't use the "_r" form if we don't need it (also, won't have a
347 prototype for it, at least on Solaris -- maybe others as well?). */
348#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
349#define USE_CTERMID_R
350#endif
351
Fred Drake699f3522000-06-29 21:12:41 +0000352/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000353#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000354#undef FSTAT
355#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200356#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000357# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700358# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000359# define FSTAT win32_fstat
360# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000361#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000362# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700363# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000364# define FSTAT fstat
365# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000366#endif
367
Tim Peters11b23062003-04-23 02:39:17 +0000368#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000369#include <sys/mkdev.h>
370#else
371#if defined(MAJOR_IN_SYSMACROS)
372#include <sys/sysmacros.h>
373#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000374#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
375#include <sys/mkdev.h>
376#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000377#endif
Fred Drake699f3522000-06-29 21:12:41 +0000378
Victor Stinner6edddfa2013-11-24 19:22:57 +0100379#define DWORD_MAX 4294967295U
380
Larry Hastings9cf065c2012-06-22 16:30:09 -0700381
382#ifdef MS_WINDOWS
383static int
384win32_warn_bytes_api()
385{
386 return PyErr_WarnEx(PyExc_DeprecationWarning,
387 "The Windows bytes API has been deprecated, "
388 "use Unicode filenames instead",
389 1);
390}
391#endif
392
393
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200394#ifndef MS_WINDOWS
395PyObject *
396_PyLong_FromUid(uid_t uid)
397{
398 if (uid == (uid_t)-1)
399 return PyLong_FromLong(-1);
400 return PyLong_FromUnsignedLong(uid);
401}
402
403PyObject *
404_PyLong_FromGid(gid_t gid)
405{
406 if (gid == (gid_t)-1)
407 return PyLong_FromLong(-1);
408 return PyLong_FromUnsignedLong(gid);
409}
410
411int
412_Py_Uid_Converter(PyObject *obj, void *p)
413{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700414 uid_t uid;
415 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200416 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200417 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700418 unsigned long uresult;
419
420 index = PyNumber_Index(obj);
421 if (index == NULL) {
422 PyErr_Format(PyExc_TypeError,
423 "uid should be integer, not %.200s",
424 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200425 return 0;
426 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700427
428 /*
429 * Handling uid_t is complicated for two reasons:
430 * * Although uid_t is (always?) unsigned, it still
431 * accepts -1.
432 * * We don't know its size in advance--it may be
433 * bigger than an int, or it may be smaller than
434 * a long.
435 *
436 * So a bit of defensive programming is in order.
437 * Start with interpreting the value passed
438 * in as a signed long and see if it works.
439 */
440
441 result = PyLong_AsLongAndOverflow(index, &overflow);
442
443 if (!overflow) {
444 uid = (uid_t)result;
445
446 if (result == -1) {
447 if (PyErr_Occurred())
448 goto fail;
449 /* It's a legitimate -1, we're done. */
450 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200451 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700452
453 /* Any other negative number is disallowed. */
454 if (result < 0)
455 goto underflow;
456
457 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200458 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700459 (long)uid != result)
460 goto underflow;
461 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200462 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700463
464 if (overflow < 0)
465 goto underflow;
466
467 /*
468 * Okay, the value overflowed a signed long. If it
469 * fits in an *unsigned* long, it may still be okay,
470 * as uid_t may be unsigned long on this platform.
471 */
472 uresult = PyLong_AsUnsignedLong(index);
473 if (PyErr_Occurred()) {
474 if (PyErr_ExceptionMatches(PyExc_OverflowError))
475 goto overflow;
476 goto fail;
477 }
478
479 uid = (uid_t)uresult;
480
481 /*
482 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
483 * but this value would get interpreted as (uid_t)-1 by chown
484 * and its siblings. That's not what the user meant! So we
485 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100486 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700487 */
488 if (uid == (uid_t)-1)
489 goto overflow;
490
491 /* Ensure the value wasn't truncated. */
492 if (sizeof(uid_t) < sizeof(long) &&
493 (unsigned long)uid != uresult)
494 goto overflow;
495 /* fallthrough */
496
497success:
498 Py_DECREF(index);
499 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200500 return 1;
501
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700502underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200503 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700504 "uid is less than minimum");
505 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200506
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700507overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200508 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700509 "uid is greater than maximum");
510 /* fallthrough */
511
512fail:
513 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200514 return 0;
515}
516
517int
518_Py_Gid_Converter(PyObject *obj, void *p)
519{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700520 gid_t gid;
521 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200522 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200523 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524 unsigned long uresult;
525
526 index = PyNumber_Index(obj);
527 if (index == NULL) {
528 PyErr_Format(PyExc_TypeError,
529 "gid should be integer, not %.200s",
530 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200531 return 0;
532 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533
534 /*
535 * Handling gid_t is complicated for two reasons:
536 * * Although gid_t is (always?) unsigned, it still
537 * accepts -1.
538 * * We don't know its size in advance--it may be
539 * bigger than an int, or it may be smaller than
540 * a long.
541 *
542 * So a bit of defensive programming is in order.
543 * Start with interpreting the value passed
544 * in as a signed long and see if it works.
545 */
546
547 result = PyLong_AsLongAndOverflow(index, &overflow);
548
549 if (!overflow) {
550 gid = (gid_t)result;
551
552 if (result == -1) {
553 if (PyErr_Occurred())
554 goto fail;
555 /* It's a legitimate -1, we're done. */
556 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200557 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700558
559 /* Any other negative number is disallowed. */
560 if (result < 0) {
561 goto underflow;
562 }
563
564 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200565 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700566 (long)gid != result)
567 goto underflow;
568 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200569 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700570
571 if (overflow < 0)
572 goto underflow;
573
574 /*
575 * Okay, the value overflowed a signed long. If it
576 * fits in an *unsigned* long, it may still be okay,
577 * as gid_t may be unsigned long on this platform.
578 */
579 uresult = PyLong_AsUnsignedLong(index);
580 if (PyErr_Occurred()) {
581 if (PyErr_ExceptionMatches(PyExc_OverflowError))
582 goto overflow;
583 goto fail;
584 }
585
586 gid = (gid_t)uresult;
587
588 /*
589 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
590 * but this value would get interpreted as (gid_t)-1 by chown
591 * and its siblings. That's not what the user meant! So we
592 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100593 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700594 */
595 if (gid == (gid_t)-1)
596 goto overflow;
597
598 /* Ensure the value wasn't truncated. */
599 if (sizeof(gid_t) < sizeof(long) &&
600 (unsigned long)gid != uresult)
601 goto overflow;
602 /* fallthrough */
603
604success:
605 Py_DECREF(index);
606 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200607 return 1;
608
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700609underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200610 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700611 "gid is less than minimum");
612 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200613
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700614overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200615 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616 "gid is greater than maximum");
617 /* fallthrough */
618
619fail:
620 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200621 return 0;
622}
623#endif /* MS_WINDOWS */
624
625
Gregory P. Smith702dada2015-01-28 16:07:52 -0800626#ifdef HAVE_LONG_LONG
627# define _PyLong_FromDev PyLong_FromLongLong
628#else
629# define _PyLong_FromDev PyLong_FromLong
630#endif
631
632
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200633#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
634static int
635_Py_Dev_Converter(PyObject *obj, void *p)
636{
637#ifdef HAVE_LONG_LONG
638 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
639#else
640 *((dev_t *)p) = PyLong_AsUnsignedLong(obj);
641#endif
642 if (PyErr_Occurred())
643 return 0;
644 return 1;
645}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800646#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200647
648
Larry Hastings9cf065c2012-06-22 16:30:09 -0700649#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400650/*
651 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
652 * without the int cast, the value gets interpreted as uint (4291925331),
653 * which doesn't play nicely with all the initializer lines in this file that
654 * look like this:
655 * int dir_fd = DEFAULT_DIR_FD;
656 */
657#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700658#else
659#define DEFAULT_DIR_FD (-100)
660#endif
661
662static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200663_fd_converter(PyObject *o, int *p, const char *allowed)
664{
665 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700666 long long_value;
667
668 PyObject *index = PyNumber_Index(o);
669 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200670 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700671 "argument should be %s, not %.200s",
672 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700673 return 0;
674 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700675
676 long_value = PyLong_AsLongAndOverflow(index, &overflow);
677 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200678 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700679 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700681 return 0;
682 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200683 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700684 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700685 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700686 return 0;
687 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700688
Larry Hastings9cf065c2012-06-22 16:30:09 -0700689 *p = (int)long_value;
690 return 1;
691}
692
693static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200694dir_fd_converter(PyObject *o, void *p)
695{
696 if (o == Py_None) {
697 *(int *)p = DEFAULT_DIR_FD;
698 return 1;
699 }
700 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700701}
702
703
704
705/*
706 * A PyArg_ParseTuple "converter" function
707 * that handles filesystem paths in the manner
708 * preferred by the os module.
709 *
710 * path_converter accepts (Unicode) strings and their
711 * subclasses, and bytes and their subclasses. What
712 * it does with the argument depends on the platform:
713 *
714 * * On Windows, if we get a (Unicode) string we
715 * extract the wchar_t * and return it; if we get
716 * bytes we extract the char * and return that.
717 *
718 * * On all other platforms, strings are encoded
719 * to bytes using PyUnicode_FSConverter, then we
720 * extract the char * from the bytes object and
721 * return that.
722 *
723 * path_converter also optionally accepts signed
724 * integers (representing open file descriptors) instead
725 * of path strings.
726 *
727 * Input fields:
728 * path.nullable
729 * If nonzero, the path is permitted to be None.
730 * path.allow_fd
731 * If nonzero, the path is permitted to be a file handle
732 * (a signed int) instead of a string.
733 * path.function_name
734 * If non-NULL, path_converter will use that as the name
735 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700736 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700737 * path.argument_name
738 * If non-NULL, path_converter will use that as the name
739 * of the parameter in error messages.
740 * (If path.argument_name is NULL it uses "path".)
741 *
742 * Output fields:
743 * path.wide
744 * Points to the path if it was expressed as Unicode
745 * and was not encoded. (Only used on Windows.)
746 * path.narrow
747 * Points to the path if it was expressed as bytes,
748 * or it was Unicode and was encoded to bytes.
749 * path.fd
750 * Contains a file descriptor if path.accept_fd was true
751 * and the caller provided a signed integer instead of any
752 * sort of string.
753 *
754 * WARNING: if your "path" parameter is optional, and is
755 * unspecified, path_converter will never get called.
756 * So if you set allow_fd, you *MUST* initialize path.fd = -1
757 * yourself!
758 * path.length
759 * The length of the path in characters, if specified as
760 * a string.
761 * path.object
762 * The original object passed in.
763 * path.cleanup
764 * For internal use only. May point to a temporary object.
765 * (Pay no attention to the man behind the curtain.)
766 *
767 * At most one of path.wide or path.narrow will be non-NULL.
768 * If path was None and path.nullable was set,
769 * or if path was an integer and path.allow_fd was set,
770 * both path.wide and path.narrow will be NULL
771 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200772 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700773 * path_converter takes care to not write to the path_t
774 * unless it's successful. However it must reset the
775 * "cleanup" field each time it's called.
776 *
777 * Use as follows:
778 * path_t path;
779 * memset(&path, 0, sizeof(path));
780 * PyArg_ParseTuple(args, "O&", path_converter, &path);
781 * // ... use values from path ...
782 * path_cleanup(&path);
783 *
784 * (Note that if PyArg_Parse fails you don't need to call
785 * path_cleanup(). However it is safe to do so.)
786 */
787typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100788 const char *function_name;
789 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700790 int nullable;
791 int allow_fd;
792 wchar_t *wide;
793 char *narrow;
794 int fd;
795 Py_ssize_t length;
796 PyObject *object;
797 PyObject *cleanup;
798} path_t;
799
Larry Hastings31826802013-10-19 00:09:25 -0700800#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \
801 {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL}
802
Larry Hastings9cf065c2012-06-22 16:30:09 -0700803static void
804path_cleanup(path_t *path) {
805 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200806 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700807 }
808}
809
810static int
811path_converter(PyObject *o, void *p) {
812 path_t *path = (path_t *)p;
813 PyObject *unicode, *bytes;
814 Py_ssize_t length;
815 char *narrow;
816
817#define FORMAT_EXCEPTION(exc, fmt) \
818 PyErr_Format(exc, "%s%s" fmt, \
819 path->function_name ? path->function_name : "", \
820 path->function_name ? ": " : "", \
821 path->argument_name ? path->argument_name : "path")
822
823 /* Py_CLEANUP_SUPPORTED support */
824 if (o == NULL) {
825 path_cleanup(path);
826 return 1;
827 }
828
829 /* ensure it's always safe to call path_cleanup() */
830 path->cleanup = NULL;
831
832 if (o == Py_None) {
833 if (!path->nullable) {
834 FORMAT_EXCEPTION(PyExc_TypeError,
835 "can't specify None for %s argument");
836 return 0;
837 }
838 path->wide = NULL;
839 path->narrow = NULL;
840 path->length = 0;
841 path->object = o;
842 path->fd = -1;
843 return 1;
844 }
845
846 unicode = PyUnicode_FromObject(o);
847 if (unicode) {
848#ifdef MS_WINDOWS
849 wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100850
851 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
852 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700853 Py_DECREF(unicode);
854 return 0;
855 }
Victor Stinner59799a82013-11-13 14:17:30 +0100856 if (length > 32767) {
857 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700858 Py_DECREF(unicode);
859 return 0;
860 }
861
862 path->wide = wide;
863 path->narrow = NULL;
864 path->length = length;
865 path->object = o;
866 path->fd = -1;
867 path->cleanup = unicode;
868 return Py_CLEANUP_SUPPORTED;
869#else
870 int converted = PyUnicode_FSConverter(unicode, &bytes);
871 Py_DECREF(unicode);
872 if (!converted)
873 bytes = NULL;
874#endif
875 }
876 else {
877 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200878 if (PyObject_CheckBuffer(o))
879 bytes = PyBytes_FromObject(o);
880 else
881 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700882 if (!bytes) {
883 PyErr_Clear();
884 if (path->allow_fd) {
885 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200886 int result = _fd_converter(o, &fd,
887 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700888 if (result) {
889 path->wide = NULL;
890 path->narrow = NULL;
891 path->length = 0;
892 path->object = o;
893 path->fd = fd;
894 return result;
895 }
896 }
897 }
898 }
899
900 if (!bytes) {
901 if (!PyErr_Occurred())
902 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
903 return 0;
904 }
905
906#ifdef MS_WINDOWS
907 if (win32_warn_bytes_api()) {
908 Py_DECREF(bytes);
909 return 0;
910 }
911#endif
912
913 length = PyBytes_GET_SIZE(bytes);
914#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100915 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700916 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
917 Py_DECREF(bytes);
918 return 0;
919 }
920#endif
921
922 narrow = PyBytes_AS_STRING(bytes);
923 if (length != strlen(narrow)) {
924 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
925 Py_DECREF(bytes);
926 return 0;
927 }
928
929 path->wide = NULL;
930 path->narrow = narrow;
931 path->length = length;
932 path->object = o;
933 path->fd = -1;
934 path->cleanup = bytes;
935 return Py_CLEANUP_SUPPORTED;
936}
937
938static void
939argument_unavailable_error(char *function_name, char *argument_name) {
940 PyErr_Format(PyExc_NotImplementedError,
941 "%s%s%s unavailable on this platform",
942 (function_name != NULL) ? function_name : "",
943 (function_name != NULL) ? ": ": "",
944 argument_name);
945}
946
947static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200948dir_fd_unavailable(PyObject *o, void *p)
949{
950 int dir_fd;
951 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700952 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200953 if (dir_fd != DEFAULT_DIR_FD) {
954 argument_unavailable_error(NULL, "dir_fd");
955 return 0;
956 }
957 *(int *)p = dir_fd;
958 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700959}
960
961static int
962fd_specified(char *function_name, int fd) {
963 if (fd == -1)
964 return 0;
965
966 argument_unavailable_error(function_name, "fd");
967 return 1;
968}
969
970static int
971follow_symlinks_specified(char *function_name, int follow_symlinks) {
972 if (follow_symlinks)
973 return 0;
974
975 argument_unavailable_error(function_name, "follow_symlinks");
976 return 1;
977}
978
979static int
980path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
981 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
982 PyErr_Format(PyExc_ValueError,
983 "%s: can't specify dir_fd without matching path",
984 function_name);
985 return 1;
986 }
987 return 0;
988}
989
990static int
991dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
992 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
993 PyErr_Format(PyExc_ValueError,
994 "%s: can't specify both dir_fd and fd",
995 function_name);
996 return 1;
997 }
998 return 0;
999}
1000
1001static int
1002fd_and_follow_symlinks_invalid(char *function_name, int fd,
1003 int follow_symlinks) {
1004 if ((fd > 0) && (!follow_symlinks)) {
1005 PyErr_Format(PyExc_ValueError,
1006 "%s: cannot use fd and follow_symlinks together",
1007 function_name);
1008 return 1;
1009 }
1010 return 0;
1011}
1012
1013static int
1014dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
1015 int follow_symlinks) {
1016 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1017 PyErr_Format(PyExc_ValueError,
1018 "%s: cannot use dir_fd and follow_symlinks together",
1019 function_name);
1020 return 1;
1021 }
1022 return 0;
1023}
1024
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001025/* A helper used by a number of POSIX-only functions */
1026#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +00001027static int
1028_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001029{
1030#if !defined(HAVE_LARGEFILE_SUPPORT)
1031 *((off_t*)addr) = PyLong_AsLong(arg);
1032#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +00001033 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001034#endif
1035 if (PyErr_Occurred())
1036 return 0;
1037 return 1;
1038}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001039#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001040
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001041#if defined _MSC_VER && _MSC_VER >= 1400
1042/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +02001043 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001044 * Normally, an invalid fd is likely to be a C program error and therefore
1045 * an assertion can be useful, but it does contradict the POSIX standard
1046 * which for write(2) states:
1047 * "Otherwise, -1 shall be returned and errno set to indicate the error."
1048 * "[EBADF] The fildes argument is not a valid file descriptor open for
1049 * writing."
1050 * Furthermore, python allows the user to enter any old integer
1051 * as a fd and should merely raise a python exception on error.
1052 * The Microsoft CRT doesn't provide an official way to check for the
1053 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +00001054 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001055 * internal structures involved.
1056 * The structures below must be updated for each version of visual studio
1057 * according to the file internal.h in the CRT source, until MS comes
1058 * up with a less hacky way to do this.
1059 * (all of this is to avoid globally modifying the CRT behaviour using
1060 * _set_invalid_parameter_handler() and _CrtSetReportMode())
1061 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001062/* The actual size of the structure is determined at runtime.
1063 * Only the first items must be present.
1064 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001065typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +00001066 intptr_t osfhnd;
1067 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001068} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001069
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001070extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001071#define IOINFO_L2E 5
1072#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
1073#define IOINFO_ARRAYS 64
1074#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
1075#define FOPEN 0x01
1076#define _NO_CONSOLE_FILENO (intptr_t)-2
1077
1078/* This function emulates what the windows CRT does to validate file handles */
1079int
1080_PyVerify_fd(int fd)
1081{
Victor Stinner8c62be82010-05-06 00:08:46 +00001082 const int i1 = fd >> IOINFO_L2E;
1083 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001084
Antoine Pitrou22e41552010-08-15 18:07:50 +00001085 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001086
Victor Stinner8c62be82010-05-06 00:08:46 +00001087 /* Determine the actual size of the ioinfo structure,
1088 * as used by the CRT loaded in memory
1089 */
1090 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
1091 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
1092 }
1093 if (sizeof_ioinfo == 0) {
1094 /* This should not happen... */
1095 goto fail;
1096 }
1097
1098 /* See that it isn't a special CLEAR fileno */
1099 if (fd != _NO_CONSOLE_FILENO) {
1100 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
1101 * we check pointer validity and other info
1102 */
1103 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
1104 /* finally, check that the file is open */
1105 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
1106 if (info->osfile & FOPEN) {
1107 return 1;
1108 }
1109 }
1110 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001111 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001112 errno = EBADF;
1113 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001114}
1115
1116/* the special case of checking dup2. The target fd must be in a sensible range */
1117static int
1118_PyVerify_fd_dup2(int fd1, int fd2)
1119{
Victor Stinner8c62be82010-05-06 00:08:46 +00001120 if (!_PyVerify_fd(fd1))
1121 return 0;
1122 if (fd2 == _NO_CONSOLE_FILENO)
1123 return 0;
1124 if ((unsigned)fd2 < _NHANDLE_)
1125 return 1;
1126 else
1127 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001128}
1129#else
1130/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1131#define _PyVerify_fd_dup2(A, B) (1)
1132#endif
1133
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001134#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001135/* The following structure was copied from
1136 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1137 include doesn't seem to be present in the Windows SDK (at least as included
1138 with Visual Studio Express). */
1139typedef struct _REPARSE_DATA_BUFFER {
1140 ULONG ReparseTag;
1141 USHORT ReparseDataLength;
1142 USHORT Reserved;
1143 union {
1144 struct {
1145 USHORT SubstituteNameOffset;
1146 USHORT SubstituteNameLength;
1147 USHORT PrintNameOffset;
1148 USHORT PrintNameLength;
1149 ULONG Flags;
1150 WCHAR PathBuffer[1];
1151 } SymbolicLinkReparseBuffer;
1152
1153 struct {
1154 USHORT SubstituteNameOffset;
1155 USHORT SubstituteNameLength;
1156 USHORT PrintNameOffset;
1157 USHORT PrintNameLength;
1158 WCHAR PathBuffer[1];
1159 } MountPointReparseBuffer;
1160
1161 struct {
1162 UCHAR DataBuffer[1];
1163 } GenericReparseBuffer;
1164 };
1165} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1166
1167#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1168 GenericReparseBuffer)
1169#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1170
1171static int
Brian Curtind25aef52011-06-13 15:16:04 -05001172win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001173{
1174 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1175 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1176 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001177
1178 if (0 == DeviceIoControl(
1179 reparse_point_handle,
1180 FSCTL_GET_REPARSE_POINT,
1181 NULL, 0, /* in buffer */
1182 target_buffer, sizeof(target_buffer),
1183 &n_bytes_returned,
1184 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001185 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001186
1187 if (reparse_tag)
1188 *reparse_tag = rdb->ReparseTag;
1189
Brian Curtind25aef52011-06-13 15:16:04 -05001190 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001191}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001192
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001193#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001194
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001195/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001196#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001197/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001198** environ directly, we must obtain it with _NSGetEnviron(). See also
1199** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001200*/
1201#include <crt_externs.h>
1202static char **environ;
1203#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001204extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001205#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001206
Barry Warsaw53699e91996-12-10 23:23:01 +00001207static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001208convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001209{
Victor Stinner8c62be82010-05-06 00:08:46 +00001210 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001211#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001212 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001213#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001214 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001215#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001216
Victor Stinner8c62be82010-05-06 00:08:46 +00001217 d = PyDict_New();
1218 if (d == NULL)
1219 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001220#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001221 if (environ == NULL)
1222 environ = *_NSGetEnviron();
1223#endif
1224#ifdef MS_WINDOWS
1225 /* _wenviron must be initialized in this way if the program is started
1226 through main() instead of wmain(). */
1227 _wgetenv(L"");
1228 if (_wenviron == NULL)
1229 return d;
1230 /* This part ignores errors */
1231 for (e = _wenviron; *e != NULL; e++) {
1232 PyObject *k;
1233 PyObject *v;
1234 wchar_t *p = wcschr(*e, L'=');
1235 if (p == NULL)
1236 continue;
1237 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1238 if (k == NULL) {
1239 PyErr_Clear();
1240 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001241 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001242 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1243 if (v == NULL) {
1244 PyErr_Clear();
1245 Py_DECREF(k);
1246 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001247 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001248 if (PyDict_GetItem(d, k) == NULL) {
1249 if (PyDict_SetItem(d, k, v) != 0)
1250 PyErr_Clear();
1251 }
1252 Py_DECREF(k);
1253 Py_DECREF(v);
1254 }
1255#else
1256 if (environ == NULL)
1257 return d;
1258 /* This part ignores errors */
1259 for (e = environ; *e != NULL; e++) {
1260 PyObject *k;
1261 PyObject *v;
1262 char *p = strchr(*e, '=');
1263 if (p == NULL)
1264 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001265 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001266 if (k == NULL) {
1267 PyErr_Clear();
1268 continue;
1269 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001270 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001271 if (v == NULL) {
1272 PyErr_Clear();
1273 Py_DECREF(k);
1274 continue;
1275 }
1276 if (PyDict_GetItem(d, k) == NULL) {
1277 if (PyDict_SetItem(d, k, v) != 0)
1278 PyErr_Clear();
1279 }
1280 Py_DECREF(k);
1281 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001282 }
1283#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001284 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001285}
1286
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001287/* Set a POSIX-specific error from errno, and return NULL */
1288
Barry Warsawd58d7641998-07-23 16:14:40 +00001289static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001290posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001291{
Victor Stinner8c62be82010-05-06 00:08:46 +00001292 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001293}
Mark Hammondef8b6542001-05-13 08:04:26 +00001294
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001295#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001296static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001297win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001298{
Victor Stinner8c62be82010-05-06 00:08:46 +00001299 /* XXX We should pass the function name along in the future.
1300 (winreg.c also wants to pass the function name.)
1301 This would however require an additional param to the
1302 Windows error object, which is non-trivial.
1303 */
1304 errno = GetLastError();
1305 if (filename)
1306 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1307 else
1308 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001309}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001310
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001311static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001312win32_error_object(char* function, PyObject* filename)
1313{
1314 /* XXX - see win32_error for comments on 'function' */
1315 errno = GetLastError();
1316 if (filename)
1317 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001318 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001319 errno,
1320 filename);
1321 else
1322 return PyErr_SetFromWindowsErr(errno);
1323}
1324
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001325#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001326
Larry Hastings9cf065c2012-06-22 16:30:09 -07001327static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001328path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001329{
1330#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001331 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1332 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001333#else
Victor Stinner292c8352012-10-30 02:17:38 +01001334 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001335#endif
1336}
1337
Larry Hastings31826802013-10-19 00:09:25 -07001338
Larry Hastingsb0827312014-02-09 22:05:19 -08001339static PyObject *
1340path_error2(path_t *path, path_t *path2)
1341{
1342#ifdef MS_WINDOWS
1343 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1344 0, path->object, path2->object);
1345#else
1346 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1347 path->object, path2->object);
1348#endif
1349}
1350
1351
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001352/* POSIX generic methods */
1353
Barry Warsaw53699e91996-12-10 23:23:01 +00001354static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001355posix_fildes(PyObject *fdobj, int (*func)(int))
1356{
Victor Stinner8c62be82010-05-06 00:08:46 +00001357 int fd;
1358 int res;
1359 fd = PyObject_AsFileDescriptor(fdobj);
1360 if (fd < 0)
1361 return NULL;
1362 if (!_PyVerify_fd(fd))
1363 return posix_error();
1364 Py_BEGIN_ALLOW_THREADS
1365 res = (*func)(fd);
1366 Py_END_ALLOW_THREADS
1367 if (res < 0)
1368 return posix_error();
1369 Py_INCREF(Py_None);
1370 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001371}
Guido van Rossum21142a01999-01-08 21:05:37 +00001372
1373static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001374posix_1str(const char *func_name, PyObject *args, char *format,
1375 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001376{
Victor Stinner292c8352012-10-30 02:17:38 +01001377 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001378 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001379 memset(&path, 0, sizeof(path));
1380 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001381 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001382 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001383 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001384 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001385 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001386 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001387 if (res < 0) {
1388 path_error(&path);
1389 path_cleanup(&path);
1390 return NULL;
1391 }
1392 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001393 Py_INCREF(Py_None);
1394 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001395}
1396
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001397
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001398#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001399/* This is a reimplementation of the C library's chdir function,
1400 but one that produces Win32 errors instead of DOS error codes.
1401 chdir is essentially a wrapper around SetCurrentDirectory; however,
1402 it also needs to set "magic" environment variables indicating
1403 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001404static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001405win32_chdir(LPCSTR path)
1406{
Victor Stinner75875072013-11-24 19:23:25 +01001407 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001408 int result;
1409 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001410
Victor Stinner8c62be82010-05-06 00:08:46 +00001411 if(!SetCurrentDirectoryA(path))
1412 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001413 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001414 if (!result)
1415 return FALSE;
1416 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001417 than MAX_PATH-1 (not including the final null character). */
1418 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001419 if (strncmp(new_path, "\\\\", 2) == 0 ||
1420 strncmp(new_path, "//", 2) == 0)
1421 /* UNC path, nothing to do. */
1422 return TRUE;
1423 env[1] = new_path[0];
1424 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001425}
1426
1427/* The Unicode version differs from the ANSI version
1428 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001429static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001430win32_wchdir(LPCWSTR path)
1431{
Victor Stinner75875072013-11-24 19:23:25 +01001432 wchar_t _new_path[MAX_PATH], *new_path = _new_path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001433 int result;
1434 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001435
Victor Stinner8c62be82010-05-06 00:08:46 +00001436 if(!SetCurrentDirectoryW(path))
1437 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001438 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001439 if (!result)
1440 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001441 if (result > Py_ARRAY_LENGTH(new_path)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001442 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001443 if (!new_path) {
1444 SetLastError(ERROR_OUTOFMEMORY);
1445 return FALSE;
1446 }
1447 result = GetCurrentDirectoryW(result, new_path);
1448 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001449 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001450 return FALSE;
1451 }
1452 }
1453 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1454 wcsncmp(new_path, L"//", 2) == 0)
1455 /* UNC path, nothing to do. */
1456 return TRUE;
1457 env[1] = new_path[0];
1458 result = SetEnvironmentVariableW(env, new_path);
1459 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001460 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001461 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001462}
1463#endif
1464
Martin v. Löwis14694662006-02-03 12:54:16 +00001465#ifdef MS_WINDOWS
1466/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1467 - time stamps are restricted to second resolution
1468 - file modification times suffer from forth-and-back conversions between
1469 UTC and local time
1470 Therefore, we implement our own stat, based on the Win32 API directly.
1471*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001472#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001473
1474struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001475 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001476 __int64 st_ino;
1477 unsigned short st_mode;
1478 int st_nlink;
1479 int st_uid;
1480 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001481 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001482 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001483 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001484 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001485 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001486 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001487 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001488 int st_ctime_nsec;
1489};
1490
1491static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1492
1493static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001494FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001495{
Victor Stinner8c62be82010-05-06 00:08:46 +00001496 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1497 /* Cannot simply cast and dereference in_ptr,
1498 since it might not be aligned properly */
1499 __int64 in;
1500 memcpy(&in, in_ptr, sizeof(in));
1501 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001502 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001503}
1504
Thomas Wouters477c8d52006-05-27 19:21:47 +00001505static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001506time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001507{
Victor Stinner8c62be82010-05-06 00:08:46 +00001508 /* XXX endianness */
1509 __int64 out;
1510 out = time_in + secs_between_epochs;
1511 out = out * 10000000 + nsec_in / 100;
1512 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001513}
1514
Martin v. Löwis14694662006-02-03 12:54:16 +00001515/* Below, we *know* that ugo+r is 0444 */
1516#if _S_IREAD != 0400
1517#error Unsupported C library
1518#endif
1519static int
1520attributes_to_mode(DWORD attr)
1521{
Victor Stinner8c62be82010-05-06 00:08:46 +00001522 int m = 0;
1523 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1524 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1525 else
1526 m |= _S_IFREG;
1527 if (attr & FILE_ATTRIBUTE_READONLY)
1528 m |= 0444;
1529 else
1530 m |= 0666;
1531 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001532}
1533
1534static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001535attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001536{
Victor Stinner8c62be82010-05-06 00:08:46 +00001537 memset(result, 0, sizeof(*result));
1538 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1539 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001540 result->st_dev = info->dwVolumeSerialNumber;
1541 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001542 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1543 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1544 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001545 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001546 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001547 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1548 /* first clear the S_IFMT bits */
Christian Heimes99d61352013-06-23 23:56:05 +02001549 result->st_mode ^= (result->st_mode & S_IFMT);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001550 /* now set the bits that make this a symlink */
Christian Heimes99d61352013-06-23 23:56:05 +02001551 result->st_mode |= S_IFLNK;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001552 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001553
Victor Stinner8c62be82010-05-06 00:08:46 +00001554 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001555}
1556
Guido van Rossumd8faa362007-04-27 19:54:29 +00001557static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001558attributes_from_dir(LPCSTR 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_DATAA FileData;
1562 hFindFile = FindFirstFileA(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
1580static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001581attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001582{
Victor Stinner8c62be82010-05-06 00:08:46 +00001583 HANDLE hFindFile;
1584 WIN32_FIND_DATAW FileData;
1585 hFindFile = FindFirstFileW(pszFile, &FileData);
1586 if (hFindFile == INVALID_HANDLE_VALUE)
1587 return FALSE;
1588 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001589 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001590 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001591 info->dwFileAttributes = FileData.dwFileAttributes;
1592 info->ftCreationTime = FileData.ftCreationTime;
1593 info->ftLastAccessTime = FileData.ftLastAccessTime;
1594 info->ftLastWriteTime = FileData.ftLastWriteTime;
1595 info->nFileSizeHigh = FileData.nFileSizeHigh;
1596 info->nFileSizeLow = FileData.nFileSizeLow;
1597/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001598 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1599 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001600 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001601}
1602
Brian Curtind25aef52011-06-13 15:16:04 -05001603/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001604static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001605static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1606 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001607static int
Brian Curtind25aef52011-06-13 15:16:04 -05001608check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001609{
Brian Curtind25aef52011-06-13 15:16:04 -05001610 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001611 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1612 DWORD);
1613
Brian Curtind25aef52011-06-13 15:16:04 -05001614 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001615 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001616 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001617 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001618 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1619 "GetFinalPathNameByHandleA");
1620 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1621 "GetFinalPathNameByHandleW");
1622 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1623 Py_GetFinalPathNameByHandleW;
1624 }
1625 return has_GetFinalPathNameByHandle;
1626}
1627
1628static BOOL
1629get_target_path(HANDLE hdl, wchar_t **target_path)
1630{
1631 int buf_size, result_length;
1632 wchar_t *buf;
1633
1634 /* We have a good handle to the target, use it to determine
1635 the target path name (then we'll call lstat on it). */
1636 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1637 VOLUME_NAME_DOS);
1638 if(!buf_size)
1639 return FALSE;
1640
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02001641 buf = PyMem_New(wchar_t, buf_size+1);
Brian Curtinc8be8402011-06-14 09:52:50 -05001642 if (!buf) {
1643 SetLastError(ERROR_OUTOFMEMORY);
1644 return FALSE;
1645 }
1646
Brian Curtind25aef52011-06-13 15:16:04 -05001647 result_length = Py_GetFinalPathNameByHandleW(hdl,
1648 buf, buf_size, VOLUME_NAME_DOS);
1649
1650 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001651 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001652 return FALSE;
1653 }
1654
1655 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001656 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001657 return FALSE;
1658 }
1659
1660 buf[result_length] = 0;
1661
1662 *target_path = buf;
1663 return TRUE;
1664}
1665
1666static int
1667win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1668 BOOL traverse);
1669static int
1670win32_xstat_impl(const char *path, struct win32_stat *result,
1671 BOOL traverse)
1672{
Victor Stinner26de69d2011-06-17 15:15:38 +02001673 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001674 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001675 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001676 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001677 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001678 const char *dot;
1679
Brian Curtind25aef52011-06-13 15:16:04 -05001680 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001681 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1682 traverse reparse point. */
1683 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001684 }
1685
Brian Curtinf5e76d02010-11-24 13:14:05 +00001686 hFile = CreateFileA(
1687 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001688 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001689 0, /* share mode */
1690 NULL, /* security attributes */
1691 OPEN_EXISTING,
1692 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001693 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1694 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001695 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001696 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1697 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001698 NULL);
1699
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001700 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001701 /* Either the target doesn't exist, or we don't have access to
1702 get a handle to it. If the former, we need to return an error.
1703 If the latter, we can use attributes_from_dir. */
1704 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001705 return -1;
1706 /* Could not get attributes on open file. Fall back to
1707 reading the directory. */
1708 if (!attributes_from_dir(path, &info, &reparse_tag))
1709 /* Very strange. This should not fail now */
1710 return -1;
1711 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1712 if (traverse) {
1713 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001714 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001715 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001716 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001717 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001718 } else {
1719 if (!GetFileInformationByHandle(hFile, &info)) {
1720 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001721 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001722 }
1723 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001724 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1725 return -1;
1726
1727 /* Close the outer open file handle now that we're about to
1728 reopen it with different flags. */
1729 if (!CloseHandle(hFile))
1730 return -1;
1731
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001732 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001733 /* In order to call GetFinalPathNameByHandle we need to open
1734 the file without the reparse handling flag set. */
1735 hFile2 = CreateFileA(
1736 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1737 NULL, OPEN_EXISTING,
1738 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1739 NULL);
1740 if (hFile2 == INVALID_HANDLE_VALUE)
1741 return -1;
1742
1743 if (!get_target_path(hFile2, &target_path))
1744 return -1;
1745
1746 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001747 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001748 return code;
1749 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001750 } else
1751 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001752 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001753 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001754
1755 /* Set S_IEXEC if it is an .exe, .bat, ... */
1756 dot = strrchr(path, '.');
1757 if (dot) {
1758 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1759 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1760 result->st_mode |= 0111;
1761 }
1762 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001763}
1764
1765static int
Brian Curtind25aef52011-06-13 15:16:04 -05001766win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1767 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001768{
1769 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001770 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001771 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001772 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001773 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001774 const wchar_t *dot;
1775
Brian Curtind25aef52011-06-13 15:16:04 -05001776 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001777 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1778 traverse reparse point. */
1779 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001780 }
1781
Brian Curtinf5e76d02010-11-24 13:14:05 +00001782 hFile = CreateFileW(
1783 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001784 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001785 0, /* share mode */
1786 NULL, /* security attributes */
1787 OPEN_EXISTING,
1788 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001789 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1790 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001791 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001792 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001793 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001794 NULL);
1795
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001796 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001797 /* Either the target doesn't exist, or we don't have access to
1798 get a handle to it. If the former, we need to return an error.
1799 If the latter, we can use attributes_from_dir. */
1800 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001801 return -1;
1802 /* Could not get attributes on open file. Fall back to
1803 reading the directory. */
1804 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1805 /* Very strange. This should not fail now */
1806 return -1;
1807 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1808 if (traverse) {
1809 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001810 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001811 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001812 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001813 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001814 } else {
1815 if (!GetFileInformationByHandle(hFile, &info)) {
1816 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001817 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001818 }
1819 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001820 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1821 return -1;
1822
1823 /* Close the outer open file handle now that we're about to
1824 reopen it with different flags. */
1825 if (!CloseHandle(hFile))
1826 return -1;
1827
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001828 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001829 /* In order to call GetFinalPathNameByHandle we need to open
1830 the file without the reparse handling flag set. */
1831 hFile2 = CreateFileW(
1832 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1833 NULL, OPEN_EXISTING,
1834 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1835 NULL);
1836 if (hFile2 == INVALID_HANDLE_VALUE)
1837 return -1;
1838
1839 if (!get_target_path(hFile2, &target_path))
1840 return -1;
1841
1842 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001843 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001844 return code;
1845 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001846 } else
1847 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001848 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001849 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001850
1851 /* Set S_IEXEC if it is an .exe, .bat, ... */
1852 dot = wcsrchr(path, '.');
1853 if (dot) {
1854 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1855 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1856 result->st_mode |= 0111;
1857 }
1858 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001859}
1860
1861static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001862win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001863{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001864 /* Protocol violation: we explicitly clear errno, instead of
1865 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001866 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001867 errno = 0;
1868 return code;
1869}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001870
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001871static int
1872win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1873{
1874 /* Protocol violation: we explicitly clear errno, instead of
1875 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001876 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001877 errno = 0;
1878 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001879}
Brian Curtind25aef52011-06-13 15:16:04 -05001880/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001881
1882 In Posix, stat automatically traverses symlinks and returns the stat
1883 structure for the target. In Windows, the equivalent GetFileAttributes by
1884 default does not traverse symlinks and instead returns attributes for
1885 the symlink.
1886
1887 Therefore, win32_lstat will get the attributes traditionally, and
1888 win32_stat will first explicitly resolve the symlink target and then will
1889 call win32_lstat on that result.
1890
Ezio Melotti4969f702011-03-15 05:59:46 +02001891 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001892
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001893static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001894win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001895{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001896 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001897}
1898
Victor Stinner8c62be82010-05-06 00:08:46 +00001899static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001900win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001901{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001902 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001903}
1904
1905static int
1906win32_stat(const char* path, struct win32_stat *result)
1907{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001908 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001909}
1910
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001911static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001912win32_stat_w(const wchar_t* path, struct win32_stat *result)
1913{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001914 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001915}
1916
1917static int
1918win32_fstat(int file_number, struct win32_stat *result)
1919{
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 BY_HANDLE_FILE_INFORMATION info;
1921 HANDLE h;
1922 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001923
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001924 if (!_PyVerify_fd(file_number))
1925 h = INVALID_HANDLE_VALUE;
1926 else
1927 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001928
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 /* Protocol violation: we explicitly clear errno, instead of
1930 setting it to a POSIX error. Callers should use GetLastError. */
1931 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001932
Victor Stinner8c62be82010-05-06 00:08:46 +00001933 if (h == INVALID_HANDLE_VALUE) {
1934 /* This is really a C library error (invalid file handle).
1935 We set the Win32 error to the closes one matching. */
1936 SetLastError(ERROR_INVALID_HANDLE);
1937 return -1;
1938 }
1939 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001940
Victor Stinner8c62be82010-05-06 00:08:46 +00001941 type = GetFileType(h);
1942 if (type == FILE_TYPE_UNKNOWN) {
1943 DWORD error = GetLastError();
1944 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001945 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001946 }
1947 /* else: valid but unknown file */
1948 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001949
Victor Stinner8c62be82010-05-06 00:08:46 +00001950 if (type != FILE_TYPE_DISK) {
1951 if (type == FILE_TYPE_CHAR)
1952 result->st_mode = _S_IFCHR;
1953 else if (type == FILE_TYPE_PIPE)
1954 result->st_mode = _S_IFIFO;
1955 return 0;
1956 }
1957
1958 if (!GetFileInformationByHandle(h, &info)) {
1959 return -1;
1960 }
1961
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001962 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001963 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001964 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1965 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001966}
1967
1968#endif /* MS_WINDOWS */
1969
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001970PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001971"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001972This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001973 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001974or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1975\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001976Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1977or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001978\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001979See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001980
1981static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 {"st_mode", "protection bits"},
1983 {"st_ino", "inode"},
1984 {"st_dev", "device"},
1985 {"st_nlink", "number of hard links"},
1986 {"st_uid", "user ID of owner"},
1987 {"st_gid", "group ID of owner"},
1988 {"st_size", "total size, in bytes"},
1989 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1990 {NULL, "integer time of last access"},
1991 {NULL, "integer time of last modification"},
1992 {NULL, "integer time of last change"},
1993 {"st_atime", "time of last access"},
1994 {"st_mtime", "time of last modification"},
1995 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001996 {"st_atime_ns", "time of last access in nanoseconds"},
1997 {"st_mtime_ns", "time of last modification in nanoseconds"},
1998 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001999#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002000 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002001#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002002#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002003 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002004#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002005#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002006 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002007#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002008#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002009 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002010#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002011#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002012 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002013#endif
2014#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002015 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002016#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002017 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002018};
2019
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002020#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002021#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002022#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002023#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002024#endif
2025
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002026#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002027#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2028#else
2029#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2030#endif
2031
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002032#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002033#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2034#else
2035#define ST_RDEV_IDX ST_BLOCKS_IDX
2036#endif
2037
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002038#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2039#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2040#else
2041#define ST_FLAGS_IDX ST_RDEV_IDX
2042#endif
2043
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002044#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002045#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002046#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002047#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002048#endif
2049
2050#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2051#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2052#else
2053#define ST_BIRTHTIME_IDX ST_GEN_IDX
2054#endif
2055
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002056static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002057 "stat_result", /* name */
2058 stat_result__doc__, /* doc */
2059 stat_result_fields,
2060 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002061};
2062
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002063PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002064"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2065This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002066 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002067or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002068\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002069See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002070
2071static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002072 {"f_bsize", },
2073 {"f_frsize", },
2074 {"f_blocks", },
2075 {"f_bfree", },
2076 {"f_bavail", },
2077 {"f_files", },
2078 {"f_ffree", },
2079 {"f_favail", },
2080 {"f_flag", },
2081 {"f_namemax",},
2082 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002083};
2084
2085static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002086 "statvfs_result", /* name */
2087 statvfs_result__doc__, /* doc */
2088 statvfs_result_fields,
2089 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002090};
2091
Ross Lagerwall7807c352011-03-17 20:20:30 +02002092#if defined(HAVE_WAITID) && !defined(__APPLE__)
2093PyDoc_STRVAR(waitid_result__doc__,
2094"waitid_result: Result from waitid.\n\n\
2095This object may be accessed either as a tuple of\n\
2096 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2097or via the attributes si_pid, si_uid, and so on.\n\
2098\n\
2099See os.waitid for more information.");
2100
2101static PyStructSequence_Field waitid_result_fields[] = {
2102 {"si_pid", },
2103 {"si_uid", },
2104 {"si_signo", },
2105 {"si_status", },
2106 {"si_code", },
2107 {0}
2108};
2109
2110static PyStructSequence_Desc waitid_result_desc = {
2111 "waitid_result", /* name */
2112 waitid_result__doc__, /* doc */
2113 waitid_result_fields,
2114 5
2115};
2116static PyTypeObject WaitidResultType;
2117#endif
2118
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002119static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002120static PyTypeObject StatResultType;
2121static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002122#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002123static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002124#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002125static newfunc structseq_new;
2126
2127static PyObject *
2128statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2129{
Victor Stinner8c62be82010-05-06 00:08:46 +00002130 PyStructSequence *result;
2131 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002132
Victor Stinner8c62be82010-05-06 00:08:46 +00002133 result = (PyStructSequence*)structseq_new(type, args, kwds);
2134 if (!result)
2135 return NULL;
2136 /* If we have been initialized from a tuple,
2137 st_?time might be set to None. Initialize it
2138 from the int slots. */
2139 for (i = 7; i <= 9; i++) {
2140 if (result->ob_item[i+3] == Py_None) {
2141 Py_DECREF(Py_None);
2142 Py_INCREF(result->ob_item[i]);
2143 result->ob_item[i+3] = result->ob_item[i];
2144 }
2145 }
2146 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002147}
2148
2149
2150
2151/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002152static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002153
2154PyDoc_STRVAR(stat_float_times__doc__,
2155"stat_float_times([newval]) -> oldval\n\n\
2156Determine whether os.[lf]stat represents time stamps as float objects.\n\
2157If newval is True, future calls to stat() return floats, if it is False,\n\
2158future calls return ints. \n\
2159If newval is omitted, return the current setting.\n");
2160
2161static PyObject*
2162stat_float_times(PyObject* self, PyObject *args)
2163{
Victor Stinner8c62be82010-05-06 00:08:46 +00002164 int newval = -1;
2165 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2166 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002167 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2168 "stat_float_times() is deprecated",
2169 1))
2170 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002171 if (newval == -1)
2172 /* Return old value */
2173 return PyBool_FromLong(_stat_float_times);
2174 _stat_float_times = newval;
2175 Py_INCREF(Py_None);
2176 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002177}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002178
Larry Hastings6fe20b32012-04-19 15:07:49 -07002179static PyObject *billion = NULL;
2180
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002181static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002182fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002183{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002184 PyObject *s = _PyLong_FromTime_t(sec);
2185 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2186 PyObject *s_in_ns = NULL;
2187 PyObject *ns_total = NULL;
2188 PyObject *float_s = NULL;
2189
2190 if (!(s && ns_fractional))
2191 goto exit;
2192
2193 s_in_ns = PyNumber_Multiply(s, billion);
2194 if (!s_in_ns)
2195 goto exit;
2196
2197 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2198 if (!ns_total)
2199 goto exit;
2200
Victor Stinner4195b5c2012-02-08 23:03:19 +01002201 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002202 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2203 if (!float_s)
2204 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002205 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002206 else {
2207 float_s = s;
2208 Py_INCREF(float_s);
2209 }
2210
2211 PyStructSequence_SET_ITEM(v, index, s);
2212 PyStructSequence_SET_ITEM(v, index+3, float_s);
2213 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2214 s = NULL;
2215 float_s = NULL;
2216 ns_total = NULL;
2217exit:
2218 Py_XDECREF(s);
2219 Py_XDECREF(ns_fractional);
2220 Py_XDECREF(s_in_ns);
2221 Py_XDECREF(ns_total);
2222 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002223}
2224
Tim Peters5aa91602002-01-30 05:46:57 +00002225/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002226 (used by posix_stat() and posix_fstat()) */
2227static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002228_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002229{
Victor Stinner8c62be82010-05-06 00:08:46 +00002230 unsigned long ansec, mnsec, cnsec;
2231 PyObject *v = PyStructSequence_New(&StatResultType);
2232 if (v == NULL)
2233 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002234
Victor Stinner8c62be82010-05-06 00:08:46 +00002235 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002236#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002237 PyStructSequence_SET_ITEM(v, 1,
2238 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002239#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002240 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002241#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002242#ifdef MS_WINDOWS
2243 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002244#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002245 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002246#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002247 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002248#if defined(MS_WINDOWS)
2249 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2250 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2251#else
2252 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2253 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2254#endif
Fred Drake699f3522000-06-29 21:12:41 +00002255#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002256 PyStructSequence_SET_ITEM(v, 6,
2257 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002258#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002259 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002260#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002261
Martin v. Löwis14694662006-02-03 12:54:16 +00002262#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002263 ansec = st->st_atim.tv_nsec;
2264 mnsec = st->st_mtim.tv_nsec;
2265 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002266#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002267 ansec = st->st_atimespec.tv_nsec;
2268 mnsec = st->st_mtimespec.tv_nsec;
2269 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002270#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002271 ansec = st->st_atime_nsec;
2272 mnsec = st->st_mtime_nsec;
2273 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002274#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002275 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002276#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002277 fill_time(v, 7, st->st_atime, ansec);
2278 fill_time(v, 8, st->st_mtime, mnsec);
2279 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002280
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002281#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002282 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2283 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002284#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002285#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002286 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2287 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002288#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002289#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002290 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2291 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002292#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002293#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002294 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2295 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002296#endif
2297#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002299 PyObject *val;
2300 unsigned long bsec,bnsec;
2301 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002302#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002303 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002304#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002305 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002306#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002307 if (_stat_float_times) {
2308 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2309 } else {
2310 val = PyLong_FromLong((long)bsec);
2311 }
2312 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2313 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002314 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002315#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002316#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002317 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2318 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002319#endif
Fred Drake699f3522000-06-29 21:12:41 +00002320
Victor Stinner8c62be82010-05-06 00:08:46 +00002321 if (PyErr_Occurred()) {
2322 Py_DECREF(v);
2323 return NULL;
2324 }
Fred Drake699f3522000-06-29 21:12:41 +00002325
Victor Stinner8c62be82010-05-06 00:08:46 +00002326 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002327}
2328
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002329/* POSIX methods */
2330
Guido van Rossum94f6f721999-01-06 18:42:14 +00002331
2332static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002333posix_do_stat(char *function_name, path_t *path,
2334 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002335{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002336 STRUCT_STAT st;
2337 int result;
2338
2339#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2340 if (follow_symlinks_specified(function_name, follow_symlinks))
2341 return NULL;
2342#endif
2343
2344 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2345 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2346 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2347 return NULL;
2348
2349 Py_BEGIN_ALLOW_THREADS
2350 if (path->fd != -1)
2351 result = FSTAT(path->fd, &st);
2352 else
2353#ifdef MS_WINDOWS
2354 if (path->wide) {
2355 if (follow_symlinks)
2356 result = win32_stat_w(path->wide, &st);
2357 else
2358 result = win32_lstat_w(path->wide, &st);
2359 }
2360 else
2361#endif
2362#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2363 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2364 result = LSTAT(path->narrow, &st);
2365 else
2366#endif
2367#ifdef HAVE_FSTATAT
2368 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2369 result = fstatat(dir_fd, path->narrow, &st,
2370 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2371 else
2372#endif
2373 result = STAT(path->narrow, &st);
2374 Py_END_ALLOW_THREADS
2375
Victor Stinner292c8352012-10-30 02:17:38 +01002376 if (result != 0) {
2377 return path_error(path);
2378 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002379
2380 return _pystat_fromstructstat(&st);
2381}
2382
Larry Hastings31826802013-10-19 00:09:25 -07002383#ifdef HAVE_FSTATAT
2384 #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter
2385#else
2386 #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable
2387#endif
2388
2389
Larry Hastings61272b72014-01-07 12:41:53 -08002390/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002391
2392class path_t_converter(CConverter):
2393
2394 type = "path_t"
2395 impl_by_reference = True
2396 parse_by_reference = True
2397
2398 converter = 'path_converter'
2399
2400 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002401 # right now path_t doesn't support default values.
2402 # to support a default value, you'll need to override initialize().
Larry Hastings7726ac92014-01-31 22:03:12 -08002403 if self.default is not unspecified:
2404 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002405
Larry Hastings7726ac92014-01-31 22:03:12 -08002406 if self.c_default is not None:
2407 fail("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002408
2409 self.nullable = nullable
2410 self.allow_fd = allow_fd
2411
Larry Hastings7726ac92014-01-31 22:03:12 -08002412 def pre_render(self):
2413 def strify(value):
2414 return str(int(bool(value)))
2415
2416 # add self.py_name here when merging with posixmodule conversion
Larry Hastings31826802013-10-19 00:09:25 -07002417 self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format(
2418 self.function.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002419 strify(self.nullable),
2420 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002421 )
2422
2423 def cleanup(self):
2424 return "path_cleanup(&" + self.name + ");\n"
2425
2426
2427class dir_fd_converter(CConverter):
2428 type = 'int'
2429 converter = 'OS_STAT_DIR_FD_CONVERTER'
2430
2431 def converter_init(self):
2432 if self.default in (unspecified, None):
2433 self.c_default = 'DEFAULT_DIR_FD'
2434
2435
Larry Hastings61272b72014-01-07 12:41:53 -08002436[python start generated code]*/
Larry Hastings7726ac92014-01-31 22:03:12 -08002437/*[python end generated code: output=da39a3ee5e6b4b0d input=5c9f456f53244fc3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002438
Larry Hastings61272b72014-01-07 12:41:53 -08002439/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002440
Larry Hastings2a727912014-01-16 11:32:01 -08002441os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002442
2443 path : path_t(allow_fd=True)
2444 Path to be examined; can be string, bytes, or open-file-descriptor int.
2445
2446 *
2447
2448 dir_fd : dir_fd = None
2449 If not None, it should be a file descriptor open to a directory,
2450 and path should be a relative string; path will then be relative to
2451 that directory.
2452
2453 follow_symlinks: bool = True
2454 If False, and the last element of the path is a symbolic link,
2455 stat will examine the symbolic link itself instead of the file
2456 the link points to.
2457
2458Perform a stat system call on the given path.
2459
2460dir_fd and follow_symlinks may not be implemented
2461 on your platform. If they are unavailable, using them will raise a
2462 NotImplementedError.
2463
2464It's an error to use dir_fd or follow_symlinks when specifying path as
2465 an open file descriptor.
2466
Larry Hastings61272b72014-01-07 12:41:53 -08002467[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002468
2469PyDoc_STRVAR(os_stat__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002470"stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n"
2471"--\n"
2472"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002473"Perform a stat system call on the given path.\n"
2474"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002475" path\n"
2476" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
2477" dir_fd\n"
2478" If not None, it should be a file descriptor open to a directory,\n"
2479" and path should be a relative string; path will then be relative to\n"
2480" that directory.\n"
2481" follow_symlinks\n"
2482" If False, and the last element of the path is a symbolic link,\n"
2483" stat will examine the symbolic link itself instead of the file\n"
2484" the link points to.\n"
2485"\n"
2486"dir_fd and follow_symlinks may not be implemented\n"
2487" on your platform. If they are unavailable, using them will raise a\n"
2488" NotImplementedError.\n"
2489"\n"
2490"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n"
2491" an open file descriptor.");
2492
2493#define OS_STAT_METHODDEF \
2494 {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002495
2496static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002497os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002498
2499static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002500os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002501{
Larry Hastings31826802013-10-19 00:09:25 -07002502 PyObject *return_value = NULL;
2503 static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2504 path_t path = PATH_T_INITIALIZE("stat", 0, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002505 int dir_fd = DEFAULT_DIR_FD;
2506 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002507
Larry Hastings31826802013-10-19 00:09:25 -07002508 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2509 "O&|$O&p:stat", _keywords,
2510 path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
2511 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002512 return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002513
2514exit:
2515 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002516 path_cleanup(&path);
Larry Hastings31826802013-10-19 00:09:25 -07002517
Larry Hastings9cf065c2012-06-22 16:30:09 -07002518 return return_value;
2519}
2520
Larry Hastings31826802013-10-19 00:09:25 -07002521static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002522os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002523/*[clinic end generated code: output=f1dcaa5e24db9882 input=5ae155bd475fd20a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002524{
2525 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2526}
2527
Larry Hastings9cf065c2012-06-22 16:30:09 -07002528PyDoc_STRVAR(posix_lstat__doc__,
2529"lstat(path, *, dir_fd=None) -> stat result\n\n\
2530Like stat(), but do not follow symbolic links.\n\
2531Equivalent to stat(path, follow_symlinks=False).");
2532
2533static PyObject *
2534posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2535{
2536 static char *keywords[] = {"path", "dir_fd", NULL};
2537 path_t path;
2538 int dir_fd = DEFAULT_DIR_FD;
2539 int follow_symlinks = 0;
2540 PyObject *return_value;
2541
2542 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002543 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002544 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2545 path_converter, &path,
2546#ifdef HAVE_FSTATAT
2547 dir_fd_converter, &dir_fd
2548#else
2549 dir_fd_unavailable, &dir_fd
2550#endif
2551 ))
2552 return NULL;
Larry Hastings31826802013-10-19 00:09:25 -07002553 return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002554 path_cleanup(&path);
2555 return return_value;
2556}
2557
Larry Hastings31826802013-10-19 00:09:25 -07002558
2559#ifdef HAVE_FACCESSAT
2560 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter
2561#else
2562 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable
2563#endif
Larry Hastings61272b72014-01-07 12:41:53 -08002564/*[clinic input]
Larry Hastings2a727912014-01-16 11:32:01 -08002565os.access
Larry Hastings31826802013-10-19 00:09:25 -07002566
2567 path: path_t(allow_fd=True)
2568 Path to be tested; can be string, bytes, or open-file-descriptor int.
2569
2570 mode: int
2571 Operating-system mode bitfield. Can be F_OK to test existence,
2572 or the inclusive-OR of R_OK, W_OK, and X_OK.
2573
2574 *
2575
2576 dir_fd : dir_fd = None
2577 If not None, it should be a file descriptor open to a directory,
2578 and path should be relative; path will then be relative to that
2579 directory.
2580
2581 effective_ids: bool = False
2582 If True, access will use the effective uid/gid instead of
2583 the real uid/gid.
2584
2585 follow_symlinks: bool = True
2586 If False, and the last element of the path is a symbolic link,
2587 access will examine the symbolic link itself instead of the file
2588 the link points to.
2589
2590Use the real uid/gid to test for access to a path.
2591
2592{parameters}
2593dir_fd, effective_ids, and follow_symlinks may not be implemented
2594 on your platform. If they are unavailable, using them will raise a
2595 NotImplementedError.
2596
2597Note that most operations will use the effective uid/gid, therefore this
2598 routine can be used in a suid/sgid environment to test if the invoking user
2599 has the specified access to the path.
2600
Larry Hastings61272b72014-01-07 12:41:53 -08002601[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002602
2603PyDoc_STRVAR(os_access__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002604"access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n"
2605" follow_symlinks=True)\n"
2606"--\n"
2607"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002608"Use the real uid/gid to test for access to a path.\n"
2609"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002610" path\n"
2611" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
2612" mode\n"
2613" Operating-system mode bitfield. Can be F_OK to test existence,\n"
2614" or the inclusive-OR of R_OK, W_OK, and X_OK.\n"
2615" dir_fd\n"
2616" If not None, it should be a file descriptor open to a directory,\n"
2617" and path should be relative; path will then be relative to that\n"
2618" directory.\n"
2619" effective_ids\n"
2620" If True, access will use the effective uid/gid instead of\n"
2621" the real uid/gid.\n"
2622" follow_symlinks\n"
2623" If False, and the last element of the path is a symbolic link,\n"
2624" access will examine the symbolic link itself instead of the file\n"
2625" the link points to.\n"
2626"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002627"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
2628" on your platform. If they are unavailable, using them will raise a\n"
2629" NotImplementedError.\n"
2630"\n"
2631"Note that most operations will use the effective uid/gid, therefore this\n"
2632" routine can be used in a suid/sgid environment to test if the invoking user\n"
2633" has the specified access to the path.");
2634
2635#define OS_ACCESS_METHODDEF \
2636 {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002637
2638static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002639os_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 -07002640
2641static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002642os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002643{
Larry Hastings31826802013-10-19 00:09:25 -07002644 PyObject *return_value = NULL;
2645 static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL};
2646 path_t path = PATH_T_INITIALIZE("access", 0, 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00002647 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002648 int dir_fd = DEFAULT_DIR_FD;
2649 int effective_ids = 0;
2650 int follow_symlinks = 1;
Larry Hastings31826802013-10-19 00:09:25 -07002651
2652 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2653 "O&i|$O&pp:access", _keywords,
2654 path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks))
2655 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002656 return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002657
2658exit:
2659 /* Cleanup for path */
2660 path_cleanup(&path);
2661
2662 return return_value;
2663}
2664
2665static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002666os_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 -08002667/*[clinic end generated code: output=a6ed4f151be9df0f input=2e2e7594371f5b7e]*/
Larry Hastings31826802013-10-19 00:09:25 -07002668{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002669 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002670
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002671#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002672 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002673#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002674 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002675#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002676
Larry Hastings9cf065c2012-06-22 16:30:09 -07002677#ifndef HAVE_FACCESSAT
2678 if (follow_symlinks_specified("access", follow_symlinks))
2679 goto exit;
2680
2681 if (effective_ids) {
2682 argument_unavailable_error("access", "effective_ids");
2683 goto exit;
2684 }
2685#endif
2686
2687#ifdef MS_WINDOWS
2688 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002689 if (path->wide != NULL)
2690 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002691 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002692 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002693 Py_END_ALLOW_THREADS
2694
2695 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002696 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002697 * * we didn't get a -1, and
2698 * * write access wasn't requested,
2699 * * or the file isn't read-only,
2700 * * or it's a directory.
2701 * (Directories cannot be read-only on Windows.)
2702 */
2703 return_value = PyBool_FromLong(
Tim Golden23005082013-10-25 11:22:37 +01002704 (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002705 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002706 !(attr & FILE_ATTRIBUTE_READONLY) ||
2707 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2708#else
2709
2710 Py_BEGIN_ALLOW_THREADS
2711#ifdef HAVE_FACCESSAT
2712 if ((dir_fd != DEFAULT_DIR_FD) ||
2713 effective_ids ||
2714 !follow_symlinks) {
2715 int flags = 0;
2716 if (!follow_symlinks)
2717 flags |= AT_SYMLINK_NOFOLLOW;
2718 if (effective_ids)
2719 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002720 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002721 }
2722 else
2723#endif
Larry Hastings31826802013-10-19 00:09:25 -07002724 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002725 Py_END_ALLOW_THREADS
2726 return_value = PyBool_FromLong(!result);
2727#endif
2728
2729#ifndef HAVE_FACCESSAT
2730exit:
2731#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002732 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002733}
2734
Guido van Rossumd371ff11999-01-25 16:12:23 +00002735#ifndef F_OK
2736#define F_OK 0
2737#endif
2738#ifndef R_OK
2739#define R_OK 4
2740#endif
2741#ifndef W_OK
2742#define W_OK 2
2743#endif
2744#ifndef X_OK
2745#define X_OK 1
2746#endif
2747
Larry Hastings31826802013-10-19 00:09:25 -07002748
Guido van Rossumd371ff11999-01-25 16:12:23 +00002749#ifdef HAVE_TTYNAME
Larry Hastings31826802013-10-19 00:09:25 -07002750
Larry Hastings61272b72014-01-07 12:41:53 -08002751/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002752os.ttyname -> DecodeFSDefault
2753
2754 fd: int
2755 Integer file descriptor handle.
2756
2757 /
2758
2759Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002760[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002761
2762PyDoc_STRVAR(os_ttyname__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002763"ttyname($module, fd, /)\n"
2764"--\n"
2765"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002766"Return the name of the terminal device connected to \'fd\'.\n"
2767"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002768" fd\n"
2769" Integer file descriptor handle.");
2770
2771#define OS_TTYNAME_METHODDEF \
2772 {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__},
2773
2774static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002775os_ttyname_impl(PyModuleDef *module, int fd);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002776
2777static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002778os_ttyname(PyModuleDef *module, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002779{
Larry Hastings31826802013-10-19 00:09:25 -07002780 PyObject *return_value = NULL;
2781 int fd;
2782 char *_return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002783
Larry Hastings31826802013-10-19 00:09:25 -07002784 if (!PyArg_ParseTuple(args,
2785 "i:ttyname",
2786 &fd))
2787 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002788 _return_value = os_ttyname_impl(module, fd);
Larry Hastings31826802013-10-19 00:09:25 -07002789 if (_return_value == NULL)
2790 goto exit;
2791 return_value = PyUnicode_DecodeFSDefault(_return_value);
2792
2793exit:
2794 return return_value;
2795}
2796
2797static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002798os_ttyname_impl(PyModuleDef *module, int fd)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002799/*[clinic end generated code: output=cee7bc4cffec01a2 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002800{
2801 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002802
Larry Hastings31826802013-10-19 00:09:25 -07002803 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002804 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002805 posix_error();
2806 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002807}
Larry Hastings31826802013-10-19 00:09:25 -07002808#else
2809#define OS_TTYNAME_METHODDEF
Guido van Rossumd371ff11999-01-25 16:12:23 +00002810#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002811
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002812#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002813PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002814"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002815Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002816
2817static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002818posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002819{
Victor Stinner8c62be82010-05-06 00:08:46 +00002820 char *ret;
2821 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002822
Greg Wardb48bc172000-03-01 21:51:56 +00002823#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002824 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002825#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002826 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002827#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002828 if (ret == NULL)
2829 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002830 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002831}
2832#endif
2833
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002834PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002835"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002836Change the current working directory to the specified path.\n\
2837\n\
2838path may always be specified as a string.\n\
2839On some platforms, path may also be specified as an open file descriptor.\n\
2840 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002841
Barry Warsaw53699e91996-12-10 23:23:01 +00002842static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002843posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002844{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002845 path_t path;
2846 int result;
2847 PyObject *return_value = NULL;
2848 static char *keywords[] = {"path", NULL};
2849
2850 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002851 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002852#ifdef HAVE_FCHDIR
2853 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002854#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2856 path_converter, &path
2857 ))
2858 return NULL;
2859
2860 Py_BEGIN_ALLOW_THREADS
2861#ifdef MS_WINDOWS
2862 if (path.wide)
2863 result = win32_wchdir(path.wide);
2864 else
2865 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002866 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002867#else
2868#ifdef HAVE_FCHDIR
2869 if (path.fd != -1)
2870 result = fchdir(path.fd);
2871 else
2872#endif
2873 result = chdir(path.narrow);
2874#endif
2875 Py_END_ALLOW_THREADS
2876
2877 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002878 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002879 goto exit;
2880 }
2881
2882 return_value = Py_None;
2883 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002884
Larry Hastings9cf065c2012-06-22 16:30:09 -07002885exit:
2886 path_cleanup(&path);
2887 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002888}
2889
Fred Drake4d1e64b2002-04-15 19:40:07 +00002890#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002891PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002892"fchdir(fd)\n\n\
2893Change to the directory of the given file descriptor. fd must be\n\
2894opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002895
2896static PyObject *
2897posix_fchdir(PyObject *self, PyObject *fdobj)
2898{
Victor Stinner8c62be82010-05-06 00:08:46 +00002899 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002900}
2901#endif /* HAVE_FCHDIR */
2902
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002903
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002904PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002905"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2906Change the access permissions of a file.\n\
2907\n\
2908path may always be specified as a string.\n\
2909On some platforms, path may also be specified as an open file descriptor.\n\
2910 If this functionality is unavailable, using it raises an exception.\n\
2911If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2912 and path should be relative; path will then be relative to that directory.\n\
2913If follow_symlinks is False, and the last element of the path is a symbolic\n\
2914 link, chmod will modify the symbolic link itself instead of the file the\n\
2915 link points to.\n\
2916It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2917 an open file descriptor.\n\
2918dir_fd and follow_symlinks may not be implemented on your platform.\n\
2919 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002920
Barry Warsaw53699e91996-12-10 23:23:01 +00002921static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002922posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002923{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002924 path_t path;
2925 int mode;
2926 int dir_fd = DEFAULT_DIR_FD;
2927 int follow_symlinks = 1;
2928 int result;
2929 PyObject *return_value = NULL;
2930 static char *keywords[] = {"path", "mode", "dir_fd",
2931 "follow_symlinks", NULL};
2932
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002933#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002934 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002935#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002936
Larry Hastings9cf065c2012-06-22 16:30:09 -07002937#ifdef HAVE_FCHMODAT
2938 int fchmodat_nofollow_unsupported = 0;
2939#endif
2940
2941 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002942 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002943#ifdef HAVE_FCHMOD
2944 path.allow_fd = 1;
2945#endif
2946 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2947 path_converter, &path,
2948 &mode,
2949#ifdef HAVE_FCHMODAT
2950 dir_fd_converter, &dir_fd,
2951#else
2952 dir_fd_unavailable, &dir_fd,
2953#endif
2954 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002955 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002956
2957#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2958 if (follow_symlinks_specified("chmod", follow_symlinks))
2959 goto exit;
2960#endif
2961
2962#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002963 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002964 if (path.wide)
2965 attr = GetFileAttributesW(path.wide);
2966 else
2967 attr = GetFileAttributesA(path.narrow);
Tim Golden23005082013-10-25 11:22:37 +01002968 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002969 result = 0;
2970 else {
2971 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002972 attr &= ~FILE_ATTRIBUTE_READONLY;
2973 else
2974 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002975 if (path.wide)
2976 result = SetFileAttributesW(path.wide, attr);
2977 else
2978 result = SetFileAttributesA(path.narrow, attr);
2979 }
2980 Py_END_ALLOW_THREADS
2981
2982 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002983 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002984 goto exit;
2985 }
2986#else /* MS_WINDOWS */
2987 Py_BEGIN_ALLOW_THREADS
2988#ifdef HAVE_FCHMOD
2989 if (path.fd != -1)
2990 result = fchmod(path.fd, mode);
2991 else
2992#endif
2993#ifdef HAVE_LCHMOD
2994 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2995 result = lchmod(path.narrow, mode);
2996 else
2997#endif
2998#ifdef HAVE_FCHMODAT
2999 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
3000 /*
3001 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3002 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003003 * and then says it isn't implemented yet.
3004 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003005 *
3006 * Once it is supported, os.chmod will automatically
3007 * support dir_fd and follow_symlinks=False. (Hopefully.)
3008 * Until then, we need to be careful what exception we raise.
3009 */
3010 result = fchmodat(dir_fd, path.narrow, mode,
3011 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3012 /*
3013 * But wait! We can't throw the exception without allowing threads,
3014 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3015 */
3016 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003017 result &&
3018 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3019 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00003020 }
3021 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00003022#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003023 result = chmod(path.narrow, mode);
3024 Py_END_ALLOW_THREADS
3025
3026 if (result) {
3027#ifdef HAVE_FCHMODAT
3028 if (fchmodat_nofollow_unsupported) {
3029 if (dir_fd != DEFAULT_DIR_FD)
3030 dir_fd_and_follow_symlinks_invalid("chmod",
3031 dir_fd, follow_symlinks);
3032 else
3033 follow_symlinks_specified("chmod", follow_symlinks);
3034 }
3035 else
3036#endif
Victor Stinner292c8352012-10-30 02:17:38 +01003037 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003038 goto exit;
3039 }
3040#endif
3041
3042 Py_INCREF(Py_None);
3043 return_value = Py_None;
3044exit:
3045 path_cleanup(&path);
3046 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003047}
3048
Larry Hastings9cf065c2012-06-22 16:30:09 -07003049
Christian Heimes4e30a842007-11-30 22:12:06 +00003050#ifdef HAVE_FCHMOD
3051PyDoc_STRVAR(posix_fchmod__doc__,
3052"fchmod(fd, mode)\n\n\
3053Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003054descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003055
3056static PyObject *
3057posix_fchmod(PyObject *self, PyObject *args)
3058{
Victor Stinner8c62be82010-05-06 00:08:46 +00003059 int fd, mode, res;
3060 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
3061 return NULL;
3062 Py_BEGIN_ALLOW_THREADS
3063 res = fchmod(fd, mode);
3064 Py_END_ALLOW_THREADS
3065 if (res < 0)
3066 return posix_error();
3067 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003068}
3069#endif /* HAVE_FCHMOD */
3070
3071#ifdef HAVE_LCHMOD
3072PyDoc_STRVAR(posix_lchmod__doc__,
3073"lchmod(path, mode)\n\n\
3074Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003075affects the link itself rather than the target.\n\
3076Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003077
3078static PyObject *
3079posix_lchmod(PyObject *self, PyObject *args)
3080{
Victor Stinner292c8352012-10-30 02:17:38 +01003081 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003082 int i;
3083 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003084 memset(&path, 0, sizeof(path));
3085 path.function_name = "lchmod";
3086 if (!PyArg_ParseTuple(args, "O&i:lchmod",
3087 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00003088 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003089 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003090 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00003091 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003092 if (res < 0) {
3093 path_error(&path);
3094 path_cleanup(&path);
3095 return NULL;
3096 }
3097 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003098 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003099}
3100#endif /* HAVE_LCHMOD */
3101
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003102
Thomas Wouterscf297e42007-02-23 15:07:44 +00003103#ifdef HAVE_CHFLAGS
3104PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003105"chflags(path, flags, *, follow_symlinks=True)\n\n\
3106Set file flags.\n\
3107\n\
3108If follow_symlinks is False, and the last element of the path is a symbolic\n\
3109 link, chflags will change flags on the symbolic link itself instead of the\n\
3110 file the link points to.\n\
3111follow_symlinks may not be implemented on your platform. If it is\n\
3112unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003113
3114static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003115posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003116{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003117 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003118 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003119 int follow_symlinks = 1;
3120 int result;
Victor Stinner45e90392013-07-18 23:57:35 +02003121 PyObject *return_value = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003122 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
3123
3124 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003125 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003126 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
3127 path_converter, &path,
3128 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003129 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003130
3131#ifndef HAVE_LCHFLAGS
3132 if (follow_symlinks_specified("chflags", follow_symlinks))
3133 goto exit;
3134#endif
3135
Victor Stinner8c62be82010-05-06 00:08:46 +00003136 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003137#ifdef HAVE_LCHFLAGS
3138 if (!follow_symlinks)
3139 result = lchflags(path.narrow, flags);
3140 else
3141#endif
3142 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003143 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003144
3145 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003146 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003147 goto exit;
3148 }
3149
3150 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003151 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003152
3153exit:
3154 path_cleanup(&path);
3155 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003156}
3157#endif /* HAVE_CHFLAGS */
3158
3159#ifdef HAVE_LCHFLAGS
3160PyDoc_STRVAR(posix_lchflags__doc__,
3161"lchflags(path, flags)\n\n\
3162Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003163This function will not follow symbolic links.\n\
3164Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003165
3166static PyObject *
3167posix_lchflags(PyObject *self, PyObject *args)
3168{
Victor Stinner292c8352012-10-30 02:17:38 +01003169 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003170 unsigned long flags;
3171 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003172 memset(&path, 0, sizeof(path));
3173 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00003174 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01003175 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00003176 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003177 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003178 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003179 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003180 if (res < 0) {
3181 path_error(&path);
3182 path_cleanup(&path);
3183 return NULL;
3184 }
3185 path_cleanup(&path);
3186 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003187}
3188#endif /* HAVE_LCHFLAGS */
3189
Martin v. Löwis244edc82001-10-04 22:44:26 +00003190#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003191PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003192"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003193Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00003194
3195static PyObject *
3196posix_chroot(PyObject *self, PyObject *args)
3197{
Victor Stinner292c8352012-10-30 02:17:38 +01003198 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00003199}
3200#endif
3201
Guido van Rossum21142a01999-01-08 21:05:37 +00003202#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003203PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003204"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003205force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003206
3207static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003208posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003209{
Stefan Krah0e803b32010-11-26 16:16:47 +00003210 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003211}
3212#endif /* HAVE_FSYNC */
3213
Ross Lagerwall7807c352011-03-17 20:20:30 +02003214#ifdef HAVE_SYNC
3215PyDoc_STRVAR(posix_sync__doc__,
3216"sync()\n\n\
3217Force write of everything to disk.");
3218
3219static PyObject *
3220posix_sync(PyObject *self, PyObject *noargs)
3221{
3222 Py_BEGIN_ALLOW_THREADS
3223 sync();
3224 Py_END_ALLOW_THREADS
3225 Py_RETURN_NONE;
3226}
3227#endif
3228
Guido van Rossum21142a01999-01-08 21:05:37 +00003229#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00003230
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003231#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003232extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3233#endif
3234
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003235PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003236"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003237force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003238 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003239
3240static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003241posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003242{
Stefan Krah0e803b32010-11-26 16:16:47 +00003243 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003244}
3245#endif /* HAVE_FDATASYNC */
3246
3247
Fredrik Lundh10723342000-07-10 16:38:09 +00003248#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003249PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003250"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3251Change the owner and group id of path to the numeric uid and gid.\n\
3252\n\
3253path may always be specified as a string.\n\
3254On some platforms, path may also be specified as an open file descriptor.\n\
3255 If this functionality is unavailable, using it raises an exception.\n\
3256If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3257 and path should be relative; path will then be relative to that directory.\n\
3258If follow_symlinks is False, and the last element of the path is a symbolic\n\
3259 link, chown will modify the symbolic link itself instead of the file the\n\
3260 link points to.\n\
3261It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3262 an open file descriptor.\n\
3263dir_fd and follow_symlinks may not be implemented on your platform.\n\
3264 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003265
Barry Warsaw53699e91996-12-10 23:23:01 +00003266static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003267posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003268{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003269 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003270 uid_t uid;
3271 gid_t gid;
3272 int dir_fd = DEFAULT_DIR_FD;
3273 int follow_symlinks = 1;
3274 int result;
3275 PyObject *return_value = NULL;
3276 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3277 "follow_symlinks", NULL};
3278
3279 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003280 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003281#ifdef HAVE_FCHOWN
3282 path.allow_fd = 1;
3283#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003284 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003285 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003286 _Py_Uid_Converter, &uid,
3287 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003288#ifdef HAVE_FCHOWNAT
3289 dir_fd_converter, &dir_fd,
3290#else
3291 dir_fd_unavailable, &dir_fd,
3292#endif
3293 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003294 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003295
3296#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3297 if (follow_symlinks_specified("chown", follow_symlinks))
3298 goto exit;
3299#endif
3300 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3301 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3302 goto exit;
3303
3304#ifdef __APPLE__
3305 /*
3306 * This is for Mac OS X 10.3, which doesn't have lchown.
3307 * (But we still have an lchown symbol because of weak-linking.)
3308 * It doesn't have fchownat either. So there's no possibility
3309 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003310 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003311 if ((!follow_symlinks) && (lchown == NULL)) {
3312 follow_symlinks_specified("chown", follow_symlinks);
3313 goto exit;
3314 }
3315#endif
3316
Victor Stinner8c62be82010-05-06 00:08:46 +00003317 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003318#ifdef HAVE_FCHOWN
3319 if (path.fd != -1)
3320 result = fchown(path.fd, uid, gid);
3321 else
3322#endif
3323#ifdef HAVE_LCHOWN
3324 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3325 result = lchown(path.narrow, uid, gid);
3326 else
3327#endif
3328#ifdef HAVE_FCHOWNAT
3329 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3330 result = fchownat(dir_fd, path.narrow, uid, gid,
3331 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3332 else
3333#endif
3334 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003335 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003336
3337 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003338 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003339 goto exit;
3340 }
3341
3342 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003343 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003344
3345exit:
3346 path_cleanup(&path);
3347 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003348}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003349#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003350
Christian Heimes4e30a842007-11-30 22:12:06 +00003351#ifdef HAVE_FCHOWN
3352PyDoc_STRVAR(posix_fchown__doc__,
3353"fchown(fd, uid, gid)\n\n\
3354Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003355fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003356
3357static PyObject *
3358posix_fchown(PyObject *self, PyObject *args)
3359{
Victor Stinner8c62be82010-05-06 00:08:46 +00003360 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003361 uid_t uid;
3362 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003364 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3365 _Py_Uid_Converter, &uid,
3366 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003367 return NULL;
3368 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003369 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 Py_END_ALLOW_THREADS
3371 if (res < 0)
3372 return posix_error();
3373 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003374}
3375#endif /* HAVE_FCHOWN */
3376
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003377#ifdef HAVE_LCHOWN
3378PyDoc_STRVAR(posix_lchown__doc__,
3379"lchown(path, uid, gid)\n\n\
3380Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003381This function will not follow symbolic links.\n\
3382Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003383
3384static PyObject *
3385posix_lchown(PyObject *self, PyObject *args)
3386{
Victor Stinner292c8352012-10-30 02:17:38 +01003387 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003388 uid_t uid;
3389 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003390 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003391 memset(&path, 0, sizeof(path));
3392 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003393 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003394 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003395 _Py_Uid_Converter, &uid,
3396 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003397 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003398 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003399 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003400 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003401 if (res < 0) {
3402 path_error(&path);
3403 path_cleanup(&path);
3404 return NULL;
3405 }
3406 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 Py_INCREF(Py_None);
3408 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003409}
3410#endif /* HAVE_LCHOWN */
3411
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003412
Barry Warsaw53699e91996-12-10 23:23:01 +00003413static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003414posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003415{
Victor Stinner8c62be82010-05-06 00:08:46 +00003416 char buf[1026];
3417 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003418
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003419#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003420 if (!use_bytes) {
3421 wchar_t wbuf[1026];
3422 wchar_t *wbuf2 = wbuf;
3423 PyObject *resobj;
3424 DWORD len;
3425 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003426 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003427 /* If the buffer is large enough, len does not include the
3428 terminating \0. If the buffer is too small, len includes
3429 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003430 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003431 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003432 if (wbuf2)
3433 len = GetCurrentDirectoryW(len, wbuf2);
3434 }
3435 Py_END_ALLOW_THREADS
3436 if (!wbuf2) {
3437 PyErr_NoMemory();
3438 return NULL;
3439 }
3440 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003441 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003442 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003443 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003444 }
3445 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003446 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003447 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003448 return resobj;
3449 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003450
3451 if (win32_warn_bytes_api())
3452 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003453#endif
3454
Victor Stinner8c62be82010-05-06 00:08:46 +00003455 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003457 Py_END_ALLOW_THREADS
3458 if (res == NULL)
3459 return posix_error();
3460 if (use_bytes)
3461 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003462 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003463}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003464
3465PyDoc_STRVAR(posix_getcwd__doc__,
3466"getcwd() -> path\n\n\
3467Return a unicode string representing the current working directory.");
3468
3469static PyObject *
3470posix_getcwd_unicode(PyObject *self)
3471{
3472 return posix_getcwd(0);
3473}
3474
3475PyDoc_STRVAR(posix_getcwdb__doc__,
3476"getcwdb() -> path\n\n\
3477Return a bytes string representing the current working directory.");
3478
3479static PyObject *
3480posix_getcwd_bytes(PyObject *self)
3481{
3482 return posix_getcwd(1);
3483}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003484
Larry Hastings9cf065c2012-06-22 16:30:09 -07003485#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3486#define HAVE_LINK 1
3487#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003488
Guido van Rossumb6775db1994-08-01 11:34:53 +00003489#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003490PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003491"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3492Create a hard link to a file.\n\
3493\n\
3494If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3495 descriptor open to a directory, and the respective path string (src or dst)\n\
3496 should be relative; the path will then be relative to that directory.\n\
3497If follow_symlinks is False, and the last element of src is a symbolic\n\
3498 link, link will create a link to the symbolic link itself instead of the\n\
3499 file the link points to.\n\
3500src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3501 platform. If they are unavailable, using them will raise a\n\
3502 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003503
Barry Warsaw53699e91996-12-10 23:23:01 +00003504static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003505posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003506{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003507 path_t src, dst;
3508 int src_dir_fd = DEFAULT_DIR_FD;
3509 int dst_dir_fd = DEFAULT_DIR_FD;
3510 int follow_symlinks = 1;
3511 PyObject *return_value = NULL;
3512 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3513 "follow_symlinks", NULL};
3514#ifdef MS_WINDOWS
3515 BOOL result;
3516#else
3517 int result;
3518#endif
3519
3520 memset(&src, 0, sizeof(src));
3521 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003522 src.function_name = "link";
3523 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003524 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3525 path_converter, &src,
3526 path_converter, &dst,
3527 dir_fd_converter, &src_dir_fd,
3528 dir_fd_converter, &dst_dir_fd,
3529 &follow_symlinks))
3530 return NULL;
3531
3532#ifndef HAVE_LINKAT
3533 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3534 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3535 goto exit;
3536 }
3537#endif
3538
3539 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3540 PyErr_SetString(PyExc_NotImplementedError,
3541 "link: src and dst must be the same type");
3542 goto exit;
3543 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003544
Brian Curtin1b9df392010-11-24 20:24:31 +00003545#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546 Py_BEGIN_ALLOW_THREADS
3547 if (src.wide)
3548 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3549 else
3550 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3551 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003552
Larry Hastings9cf065c2012-06-22 16:30:09 -07003553 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08003554 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003555 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003556 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557#else
3558 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003559#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3561 (dst_dir_fd != DEFAULT_DIR_FD) ||
3562 (!follow_symlinks))
3563 result = linkat(src_dir_fd, src.narrow,
3564 dst_dir_fd, dst.narrow,
3565 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3566 else
3567#endif
3568 result = link(src.narrow, dst.narrow);
3569 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003570
Larry Hastings9cf065c2012-06-22 16:30:09 -07003571 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08003572 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003574 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575#endif
3576
3577 return_value = Py_None;
3578 Py_INCREF(Py_None);
3579
3580exit:
3581 path_cleanup(&src);
3582 path_cleanup(&dst);
3583 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003584}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003585#endif
3586
Brian Curtin1b9df392010-11-24 20:24:31 +00003587
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003588
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003589PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003590"listdir(path='.') -> list_of_filenames\n\n\
3591Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003592The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003593entries '.' and '..' even if they are present in the directory.\n\
3594\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003595path can be specified as either str or bytes. If path is bytes,\n\
3596 the filenames returned will also be bytes; in all other circumstances\n\
3597 the filenames returned will be str.\n\
3598On some platforms, path may also be specified as an open file descriptor;\n\
3599 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003600 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003601
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003602#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003603static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003604_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003605{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003607 PyObject *v;
3608 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3609 BOOL result;
3610 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003611 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003612 char *bufptr = namebuf;
3613 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003614 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003615 PyObject *po = NULL;
3616 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003617
Gregory P. Smith40a21602013-03-20 20:52:50 -07003618 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003619 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003620 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003621
Gregory P. Smith40a21602013-03-20 20:52:50 -07003622 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003623 po_wchars = L".";
3624 len = 1;
3625 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003626 po_wchars = path->wide;
3627 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003628 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003629 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003630 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003631 if (!wnamebuf) {
3632 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003633 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003634 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003635 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003636 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003637 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003638 if (wch != SEP && wch != ALTSEP && wch != L':')
3639 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003640 wcscpy(wnamebuf + len, L"*.*");
3641 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003642 if ((list = PyList_New(0)) == NULL) {
3643 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003644 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003645 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003646 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003647 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003648 if (hFindFile == INVALID_HANDLE_VALUE) {
3649 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003650 if (error == ERROR_FILE_NOT_FOUND)
3651 goto exit;
3652 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003653 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003654 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003655 }
3656 do {
3657 /* Skip over . and .. */
3658 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3659 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003660 v = PyUnicode_FromWideChar(wFileData.cFileName,
3661 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003662 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003663 Py_DECREF(list);
3664 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003665 break;
3666 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003667 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003668 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003669 Py_DECREF(list);
3670 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 break;
3672 }
3673 Py_DECREF(v);
3674 }
3675 Py_BEGIN_ALLOW_THREADS
3676 result = FindNextFileW(hFindFile, &wFileData);
3677 Py_END_ALLOW_THREADS
3678 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3679 it got to the end of the directory. */
3680 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003681 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003682 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003683 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 }
3685 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003686
Larry Hastings9cf065c2012-06-22 16:30:09 -07003687 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003688 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003689 strcpy(namebuf, path->narrow);
3690 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003691 if (len > 0) {
3692 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003693 if (ch != '\\' && ch != '/' && ch != ':')
3694 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 strcpy(namebuf + len, "*.*");
3696 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003697
Larry Hastings9cf065c2012-06-22 16:30:09 -07003698 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003699 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003700
Antoine Pitroub73caab2010-08-09 23:39:31 +00003701 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003702 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003703 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003704 if (hFindFile == INVALID_HANDLE_VALUE) {
3705 int error = GetLastError();
3706 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003707 goto exit;
3708 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003709 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003711 }
3712 do {
3713 /* Skip over . and .. */
3714 if (strcmp(FileData.cFileName, ".") != 0 &&
3715 strcmp(FileData.cFileName, "..") != 0) {
3716 v = PyBytes_FromString(FileData.cFileName);
3717 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003718 Py_DECREF(list);
3719 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003720 break;
3721 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003722 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003723 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003724 Py_DECREF(list);
3725 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003726 break;
3727 }
3728 Py_DECREF(v);
3729 }
3730 Py_BEGIN_ALLOW_THREADS
3731 result = FindNextFile(hFindFile, &FileData);
3732 Py_END_ALLOW_THREADS
3733 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3734 it got to the end of the directory. */
3735 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003736 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003737 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003738 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003739 }
3740 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003741
Larry Hastings9cf065c2012-06-22 16:30:09 -07003742exit:
3743 if (hFindFile != INVALID_HANDLE_VALUE) {
3744 if (FindClose(hFindFile) == FALSE) {
3745 if (list != NULL) {
3746 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003747 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003748 }
3749 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003750 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003751 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003752
Larry Hastings9cf065c2012-06-22 16:30:09 -07003753 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003754} /* end of _listdir_windows_no_opendir */
3755
3756#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3757
3758static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003759_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003760{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003761 PyObject *v;
3762 DIR *dirp = NULL;
3763 struct dirent *ep;
3764 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003765#ifdef HAVE_FDOPENDIR
3766 int fd = -1;
3767#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003768
Victor Stinner8c62be82010-05-06 00:08:46 +00003769 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003770#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003771 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003772 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003773 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003774 if (fd == -1)
3775 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003776
Larry Hastingsfdaea062012-06-25 04:42:23 -07003777 return_str = 1;
3778
Larry Hastings9cf065c2012-06-22 16:30:09 -07003779 Py_BEGIN_ALLOW_THREADS
3780 dirp = fdopendir(fd);
3781 Py_END_ALLOW_THREADS
3782 }
3783 else
3784#endif
3785 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003786 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003787 if (path->narrow) {
3788 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003789 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003790 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003791 }
3792 else {
3793 name = ".";
3794 return_str = 1;
3795 }
3796
Larry Hastings9cf065c2012-06-22 16:30:09 -07003797 Py_BEGIN_ALLOW_THREADS
3798 dirp = opendir(name);
3799 Py_END_ALLOW_THREADS
3800 }
3801
3802 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003803 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003804#ifdef HAVE_FDOPENDIR
3805 if (fd != -1) {
3806 Py_BEGIN_ALLOW_THREADS
3807 close(fd);
3808 Py_END_ALLOW_THREADS
3809 }
3810#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003811 goto exit;
3812 }
3813 if ((list = PyList_New(0)) == NULL) {
3814 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003815 }
3816 for (;;) {
3817 errno = 0;
3818 Py_BEGIN_ALLOW_THREADS
3819 ep = readdir(dirp);
3820 Py_END_ALLOW_THREADS
3821 if (ep == NULL) {
3822 if (errno == 0) {
3823 break;
3824 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003825 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003826 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003827 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003828 }
3829 }
3830 if (ep->d_name[0] == '.' &&
3831 (NAMLEN(ep) == 1 ||
3832 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3833 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003834 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003835 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3836 else
3837 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003838 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003839 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003840 break;
3841 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003842 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003843 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003844 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003845 break;
3846 }
3847 Py_DECREF(v);
3848 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003849
Larry Hastings9cf065c2012-06-22 16:30:09 -07003850exit:
3851 if (dirp != NULL) {
3852 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003853#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003854 if (fd > -1)
3855 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003856#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003857 closedir(dirp);
3858 Py_END_ALLOW_THREADS
3859 }
3860
Larry Hastings9cf065c2012-06-22 16:30:09 -07003861 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003862} /* end of _posix_listdir */
3863#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003864
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003865static PyObject *
3866posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3867{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003868 path_t path;
3869 PyObject *list = NULL;
3870 static char *keywords[] = {"path", NULL};
3871 PyObject *return_value;
3872
3873 memset(&path, 0, sizeof(path));
3874 path.function_name = "listdir";
3875 path.nullable = 1;
3876#ifdef HAVE_FDOPENDIR
3877 path.allow_fd = 1;
3878 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003879#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003880
3881 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3882 path_converter, &path)) {
3883 return NULL;
3884 }
3885
3886#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3887 return_value = _listdir_windows_no_opendir(&path, list);
3888#else
3889 return_value = _posix_listdir(&path, list);
3890#endif
3891 path_cleanup(&path);
3892 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003893}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003894
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003895#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003896/* A helper function for abspath on win32 */
3897static PyObject *
3898posix__getfullpathname(PyObject *self, PyObject *args)
3899{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003900 const char *path;
Victor Stinner75875072013-11-24 19:23:25 +01003901 char outbuf[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00003902 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003903 PyObject *po;
3904
3905 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3906 {
3907 wchar_t *wpath;
Victor Stinner75875072013-11-24 19:23:25 +01003908 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003909 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003910 DWORD result;
3911 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003912
3913 wpath = PyUnicode_AsUnicode(po);
3914 if (wpath == NULL)
3915 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003916 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003917 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003918 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003919 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003920 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003921 if (!woutbufp)
3922 return PyErr_NoMemory();
3923 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3924 }
3925 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003926 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003927 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003928 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003929 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003930 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003931 return v;
3932 }
3933 /* Drop the argument parsing error as narrow strings
3934 are also valid. */
3935 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003936
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003937 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3938 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003939 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003940 if (win32_warn_bytes_api())
3941 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003942 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003943 outbuf, &temp)) {
3944 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003945 return NULL;
3946 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003947 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3948 return PyUnicode_Decode(outbuf, strlen(outbuf),
3949 Py_FileSystemDefaultEncoding, NULL);
3950 }
3951 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003952} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003953
Brian Curtind25aef52011-06-13 15:16:04 -05003954
Brian Curtinf5e76d02010-11-24 13:14:05 +00003955
Brian Curtind40e6f72010-07-08 21:39:08 +00003956/* A helper function for samepath on windows */
3957static PyObject *
3958posix__getfinalpathname(PyObject *self, PyObject *args)
3959{
3960 HANDLE hFile;
3961 int buf_size;
3962 wchar_t *target_path;
3963 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003964 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003965 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003966
Victor Stinnereb5657a2011-09-30 01:44:27 +02003967 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003968 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003969 path = PyUnicode_AsUnicode(po);
3970 if (path == NULL)
3971 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003972
3973 if(!check_GetFinalPathNameByHandle()) {
3974 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3975 NotImplementedError. */
3976 return PyErr_Format(PyExc_NotImplementedError,
3977 "GetFinalPathNameByHandle not available on this platform");
3978 }
3979
3980 hFile = CreateFileW(
3981 path,
3982 0, /* desired access */
3983 0, /* share mode */
3984 NULL, /* security attributes */
3985 OPEN_EXISTING,
3986 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3987 FILE_FLAG_BACKUP_SEMANTICS,
3988 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003989
Victor Stinnereb5657a2011-09-30 01:44:27 +02003990 if(hFile == INVALID_HANDLE_VALUE)
3991 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003992
3993 /* We have a good handle to the target, use it to determine the
3994 target path name. */
3995 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3996
3997 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003998 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003999
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004000 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00004001 if(!target_path)
4002 return PyErr_NoMemory();
4003
4004 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
4005 buf_size, VOLUME_NAME_DOS);
4006 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02004007 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00004008
4009 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02004010 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00004011
4012 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004013 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02004014 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004015 return result;
4016
4017} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00004018
Brian Curtin95d028f2011-06-09 09:10:38 -05004019PyDoc_STRVAR(posix__isdir__doc__,
4020"Return true if the pathname refers to an existing directory.");
4021
Brian Curtin9c669cc2011-06-08 18:17:18 -05004022static PyObject *
4023posix__isdir(PyObject *self, PyObject *args)
4024{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004025 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004026 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004027 DWORD attributes;
4028
4029 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02004030 wchar_t *wpath = PyUnicode_AsUnicode(po);
4031 if (wpath == NULL)
4032 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004033
4034 attributes = GetFileAttributesW(wpath);
4035 if (attributes == INVALID_FILE_ATTRIBUTES)
4036 Py_RETURN_FALSE;
4037 goto check;
4038 }
4039 /* Drop the argument parsing error as narrow strings
4040 are also valid. */
4041 PyErr_Clear();
4042
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004043 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05004044 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004045 if (win32_warn_bytes_api())
4046 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004047 attributes = GetFileAttributesA(path);
4048 if (attributes == INVALID_FILE_ATTRIBUTES)
4049 Py_RETURN_FALSE;
4050
4051check:
4052 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4053 Py_RETURN_TRUE;
4054 else
4055 Py_RETURN_FALSE;
4056}
Tim Golden6b528062013-08-01 12:44:00 +01004057
4058PyDoc_STRVAR(posix__getvolumepathname__doc__,
4059"Return volume mount point of the specified path.");
4060
4061/* A helper function for ismount on windows */
4062static PyObject *
4063posix__getvolumepathname(PyObject *self, PyObject *args)
4064{
4065 PyObject *po, *result;
4066 wchar_t *path, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004067 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004068 BOOL ret;
4069
4070 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
4071 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004072 path = PyUnicode_AsUnicodeAndSize(po, &buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004073 if (path == NULL)
4074 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004075 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01004076
4077 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01004078 buflen = Py_MAX(buflen, MAX_PATH);
4079
4080 if (buflen > DWORD_MAX) {
4081 PyErr_SetString(PyExc_OverflowError, "path too long");
4082 return NULL;
4083 }
4084
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004085 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004086 if (mountpath == NULL)
4087 return PyErr_NoMemory();
4088
4089 Py_BEGIN_ALLOW_THREADS
Christian Heimes85ba92a2013-11-18 10:30:42 +01004090 ret = GetVolumePathNameW(path, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004091 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004092 Py_END_ALLOW_THREADS
4093
4094 if (!ret) {
4095 result = win32_error_object("_getvolumepathname", po);
4096 goto exit;
4097 }
4098 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4099
4100exit:
4101 PyMem_Free(mountpath);
4102 return result;
4103}
4104/* end of posix__getvolumepathname */
4105
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004106#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004107
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004108PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004109"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4110Create a directory.\n\
4111\n\
4112If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4113 and path should be relative; path will then be relative to that directory.\n\
4114dir_fd may not be implemented on your platform.\n\
4115 If it is unavailable, using it will raise a NotImplementedError.\n\
4116\n\
4117The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004118
Barry Warsaw53699e91996-12-10 23:23:01 +00004119static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004120posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004121{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004123 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004124 int dir_fd = DEFAULT_DIR_FD;
4125 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
4126 PyObject *return_value = NULL;
4127 int result;
4128
4129 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004130 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004131 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4132 path_converter, &path, &mode,
4133#ifdef HAVE_MKDIRAT
4134 dir_fd_converter, &dir_fd
4135#else
4136 dir_fd_unavailable, &dir_fd
4137#endif
4138 ))
4139 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004140
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004141#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004142 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004143 if (path.wide)
4144 result = CreateDirectoryW(path.wide, NULL);
4145 else
4146 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004147 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004148
Larry Hastings9cf065c2012-06-22 16:30:09 -07004149 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004150 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004151 goto exit;
4152 }
4153#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004154 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004155#if HAVE_MKDIRAT
4156 if (dir_fd != DEFAULT_DIR_FD)
4157 result = mkdirat(dir_fd, path.narrow, mode);
4158 else
4159#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004160#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004161 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004162#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004163 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004164#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004165 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004166 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01004167 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004168 goto exit;
4169 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004170#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004171 return_value = Py_None;
4172 Py_INCREF(Py_None);
4173exit:
4174 path_cleanup(&path);
4175 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004176}
4177
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004178
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004179/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4180#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004181#include <sys/resource.h>
4182#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004183
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004184
4185#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004186PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004187"nice(inc) -> new_priority\n\n\
4188Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004189
Barry Warsaw53699e91996-12-10 23:23:01 +00004190static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004191posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004192{
Victor Stinner8c62be82010-05-06 00:08:46 +00004193 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004194
Victor Stinner8c62be82010-05-06 00:08:46 +00004195 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4196 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004197
Victor Stinner8c62be82010-05-06 00:08:46 +00004198 /* There are two flavours of 'nice': one that returns the new
4199 priority (as required by almost all standards out there) and the
4200 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4201 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004202
Victor Stinner8c62be82010-05-06 00:08:46 +00004203 If we are of the nice family that returns the new priority, we
4204 need to clear errno before the call, and check if errno is filled
4205 before calling posix_error() on a returnvalue of -1, because the
4206 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004207
Victor Stinner8c62be82010-05-06 00:08:46 +00004208 errno = 0;
4209 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004210#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004211 if (value == 0)
4212 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004213#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004214 if (value == -1 && errno != 0)
4215 /* either nice() or getpriority() returned an error */
4216 return posix_error();
4217 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004218}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004219#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004220
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004221
4222#ifdef HAVE_GETPRIORITY
4223PyDoc_STRVAR(posix_getpriority__doc__,
4224"getpriority(which, who) -> current_priority\n\n\
4225Get program scheduling priority.");
4226
4227static PyObject *
4228posix_getpriority(PyObject *self, PyObject *args)
4229{
4230 int which, who, retval;
4231
4232 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4233 return NULL;
4234 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004235 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004236 if (errno != 0)
4237 return posix_error();
4238 return PyLong_FromLong((long)retval);
4239}
4240#endif /* HAVE_GETPRIORITY */
4241
4242
4243#ifdef HAVE_SETPRIORITY
4244PyDoc_STRVAR(posix_setpriority__doc__,
4245"setpriority(which, who, prio) -> None\n\n\
4246Set program scheduling priority.");
4247
4248static PyObject *
4249posix_setpriority(PyObject *self, PyObject *args)
4250{
4251 int which, who, prio, retval;
4252
4253 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4254 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004255 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004256 if (retval == -1)
4257 return posix_error();
4258 Py_RETURN_NONE;
4259}
4260#endif /* HAVE_SETPRIORITY */
4261
4262
Barry Warsaw53699e91996-12-10 23:23:01 +00004263static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004264internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004265{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004266 char *function_name = is_replace ? "replace" : "rename";
4267 path_t src;
4268 path_t dst;
4269 int src_dir_fd = DEFAULT_DIR_FD;
4270 int dst_dir_fd = DEFAULT_DIR_FD;
4271 int dir_fd_specified;
4272 PyObject *return_value = NULL;
4273 char format[24];
4274 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4275
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004276#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004277 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004278 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004279#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004280 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004281#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004282
4283 memset(&src, 0, sizeof(src));
4284 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01004285 src.function_name = function_name;
4286 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004287 strcpy(format, "O&O&|$O&O&:");
4288 strcat(format, function_name);
4289 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4290 path_converter, &src,
4291 path_converter, &dst,
4292 dir_fd_converter, &src_dir_fd,
4293 dir_fd_converter, &dst_dir_fd))
4294 return NULL;
4295
4296 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4297 (dst_dir_fd != DEFAULT_DIR_FD);
4298#ifndef HAVE_RENAMEAT
4299 if (dir_fd_specified) {
4300 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4301 goto exit;
4302 }
4303#endif
4304
4305 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4306 PyErr_Format(PyExc_ValueError,
4307 "%s: src and dst must be the same type", function_name);
4308 goto exit;
4309 }
4310
4311#ifdef MS_WINDOWS
4312 Py_BEGIN_ALLOW_THREADS
4313 if (src.wide)
4314 result = MoveFileExW(src.wide, dst.wide, flags);
4315 else
4316 result = MoveFileExA(src.narrow, dst.narrow, flags);
4317 Py_END_ALLOW_THREADS
4318
4319 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08004320 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004321 goto exit;
4322 }
4323
4324#else
4325 Py_BEGIN_ALLOW_THREADS
4326#ifdef HAVE_RENAMEAT
4327 if (dir_fd_specified)
4328 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4329 else
4330#endif
4331 result = rename(src.narrow, dst.narrow);
4332 Py_END_ALLOW_THREADS
4333
4334 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08004335 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004336 goto exit;
4337 }
4338#endif
4339
4340 Py_INCREF(Py_None);
4341 return_value = Py_None;
4342exit:
4343 path_cleanup(&src);
4344 path_cleanup(&dst);
4345 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004346}
4347
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004348PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004349"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4350Rename a file or directory.\n\
4351\n\
4352If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4353 descriptor open to a directory, and the respective path string (src or dst)\n\
4354 should be relative; the path will then be relative to that directory.\n\
4355src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4356 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004357
4358static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004359posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004360{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004361 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004362}
4363
4364PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004365"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4366Rename a file or directory, overwriting the destination.\n\
4367\n\
4368If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4369 descriptor open to a directory, and the respective path string (src or dst)\n\
4370 should be relative; the path will then be relative to that directory.\n\
4371src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4372 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004373
4374static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004375posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004376{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004377 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004378}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004379
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004380PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004381"rmdir(path, *, dir_fd=None)\n\n\
4382Remove a directory.\n\
4383\n\
4384If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4385 and path should be relative; path will then be relative to that directory.\n\
4386dir_fd may not be implemented on your platform.\n\
4387 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004388
Barry Warsaw53699e91996-12-10 23:23:01 +00004389static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004390posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004391{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004392 path_t path;
4393 int dir_fd = DEFAULT_DIR_FD;
4394 static char *keywords[] = {"path", "dir_fd", NULL};
4395 int result;
4396 PyObject *return_value = NULL;
4397
4398 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004399 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004400 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4401 path_converter, &path,
4402#ifdef HAVE_UNLINKAT
4403 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004404#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004405 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004406#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004407 ))
4408 return NULL;
4409
4410 Py_BEGIN_ALLOW_THREADS
4411#ifdef MS_WINDOWS
4412 if (path.wide)
4413 result = RemoveDirectoryW(path.wide);
4414 else
4415 result = RemoveDirectoryA(path.narrow);
4416 result = !result; /* Windows, success=1, UNIX, success=0 */
4417#else
4418#ifdef HAVE_UNLINKAT
4419 if (dir_fd != DEFAULT_DIR_FD)
4420 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4421 else
4422#endif
4423 result = rmdir(path.narrow);
4424#endif
4425 Py_END_ALLOW_THREADS
4426
4427 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004428 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004429 goto exit;
4430 }
4431
4432 return_value = Py_None;
4433 Py_INCREF(Py_None);
4434
4435exit:
4436 path_cleanup(&path);
4437 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004438}
4439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004440
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004441#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004442PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004443"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004444Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004445
Barry Warsaw53699e91996-12-10 23:23:01 +00004446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004447posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004448{
Victor Stinner8c62be82010-05-06 00:08:46 +00004449 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004450#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004451 wchar_t *command;
4452 if (!PyArg_ParseTuple(args, "u:system", &command))
4453 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004454
Victor Stinner8c62be82010-05-06 00:08:46 +00004455 Py_BEGIN_ALLOW_THREADS
4456 sts = _wsystem(command);
4457 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004458#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004459 PyObject *command_obj;
4460 char *command;
4461 if (!PyArg_ParseTuple(args, "O&:system",
4462 PyUnicode_FSConverter, &command_obj))
4463 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004464
Victor Stinner8c62be82010-05-06 00:08:46 +00004465 command = PyBytes_AsString(command_obj);
4466 Py_BEGIN_ALLOW_THREADS
4467 sts = system(command);
4468 Py_END_ALLOW_THREADS
4469 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004470#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004471 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004472}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004473#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004474
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004475
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004476PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004477"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004478Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004479
Barry Warsaw53699e91996-12-10 23:23:01 +00004480static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004481posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004482{
Victor Stinner8c62be82010-05-06 00:08:46 +00004483 int i;
4484 if (!PyArg_ParseTuple(args, "i:umask", &i))
4485 return NULL;
4486 i = (int)umask(i);
4487 if (i < 0)
4488 return posix_error();
4489 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004490}
4491
Brian Curtind40e6f72010-07-08 21:39:08 +00004492#ifdef MS_WINDOWS
4493
4494/* override the default DeleteFileW behavior so that directory
4495symlinks can be removed with this function, the same as with
4496Unix symlinks */
4497BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4498{
4499 WIN32_FILE_ATTRIBUTE_DATA info;
4500 WIN32_FIND_DATAW find_data;
4501 HANDLE find_data_handle;
4502 int is_directory = 0;
4503 int is_link = 0;
4504
4505 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4506 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004507
Brian Curtind40e6f72010-07-08 21:39:08 +00004508 /* Get WIN32_FIND_DATA structure for the path to determine if
4509 it is a symlink */
4510 if(is_directory &&
4511 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4512 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4513
4514 if(find_data_handle != INVALID_HANDLE_VALUE) {
4515 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4516 FindClose(find_data_handle);
4517 }
4518 }
4519 }
4520
4521 if (is_directory && is_link)
4522 return RemoveDirectoryW(lpFileName);
4523
4524 return DeleteFileW(lpFileName);
4525}
4526#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004527
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004528PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004529"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004530Remove a file (same as remove()).\n\
4531\n\
4532If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4533 and path should be relative; path will then be relative to that directory.\n\
4534dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004535 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004536
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004537PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004538"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004539Remove a file (same as unlink()).\n\
4540\n\
4541If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4542 and path should be relative; path will then be relative to that directory.\n\
4543dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004544 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004545
Barry Warsaw53699e91996-12-10 23:23:01 +00004546static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004547posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004548{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004549 path_t path;
4550 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004551 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004552 int result;
4553 PyObject *return_value = NULL;
4554
4555 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004556 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004557 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004558 path_converter, &path,
4559#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004560 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004561#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004562 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004563#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004564 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004565 return NULL;
4566
4567 Py_BEGIN_ALLOW_THREADS
4568#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004569 if (path.wide)
4570 result = Py_DeleteFileW(path.wide);
4571 else
4572 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004573 result = !result; /* Windows, success=1, UNIX, success=0 */
4574#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004575#ifdef HAVE_UNLINKAT
4576 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004577 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004578 else
4579#endif /* HAVE_UNLINKAT */
4580 result = unlink(path.narrow);
4581#endif
4582 Py_END_ALLOW_THREADS
4583
4584 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004585 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004586 goto exit;
4587 }
4588
4589 return_value = Py_None;
4590 Py_INCREF(Py_None);
4591
4592exit:
4593 path_cleanup(&path);
4594 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004595}
4596
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004597
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004598PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004599"uname() -> uname_result\n\n\
4600Return an object identifying the current operating system.\n\
4601The object behaves like a named tuple with the following fields:\n\
4602 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004603
Larry Hastings605a62d2012-06-24 04:33:36 -07004604static PyStructSequence_Field uname_result_fields[] = {
4605 {"sysname", "operating system name"},
4606 {"nodename", "name of machine on network (implementation-defined)"},
4607 {"release", "operating system release"},
4608 {"version", "operating system version"},
4609 {"machine", "hardware identifier"},
4610 {NULL}
4611};
4612
4613PyDoc_STRVAR(uname_result__doc__,
4614"uname_result: Result from os.uname().\n\n\
4615This object may be accessed either as a tuple of\n\
4616 (sysname, nodename, release, version, machine),\n\
4617or via the attributes sysname, nodename, release, version, and machine.\n\
4618\n\
4619See os.uname for more information.");
4620
4621static PyStructSequence_Desc uname_result_desc = {
4622 "uname_result", /* name */
4623 uname_result__doc__, /* doc */
4624 uname_result_fields,
4625 5
4626};
4627
4628static PyTypeObject UnameResultType;
4629
4630
4631#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004632static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004633posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004634{
Victor Stinner8c62be82010-05-06 00:08:46 +00004635 struct utsname u;
4636 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004637 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004638
Victor Stinner8c62be82010-05-06 00:08:46 +00004639 Py_BEGIN_ALLOW_THREADS
4640 res = uname(&u);
4641 Py_END_ALLOW_THREADS
4642 if (res < 0)
4643 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004644
4645 value = PyStructSequence_New(&UnameResultType);
4646 if (value == NULL)
4647 return NULL;
4648
4649#define SET(i, field) \
4650 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004651 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004652 if (!o) { \
4653 Py_DECREF(value); \
4654 return NULL; \
4655 } \
4656 PyStructSequence_SET_ITEM(value, i, o); \
4657 } \
4658
4659 SET(0, u.sysname);
4660 SET(1, u.nodename);
4661 SET(2, u.release);
4662 SET(3, u.version);
4663 SET(4, u.machine);
4664
4665#undef SET
4666
4667 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004668}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004669#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004670
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004671
Larry Hastings9cf065c2012-06-22 16:30:09 -07004672PyDoc_STRVAR(posix_utime__doc__,
4673"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4674Set the access and modified time of path.\n\
4675\n\
4676path may always be specified as a string.\n\
4677On some platforms, path may also be specified as an open file descriptor.\n\
4678 If this functionality is unavailable, using it raises an exception.\n\
4679\n\
4680If times is not None, it must be a tuple (atime, mtime);\n\
4681 atime and mtime should be expressed as float seconds since the epoch.\n\
4682If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4683 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4684 since the epoch.\n\
4685If both times and ns are None, utime uses the current time.\n\
4686Specifying tuples for both times and ns is an error.\n\
4687\n\
4688If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4689 and path should be relative; path will then be relative to that directory.\n\
4690If follow_symlinks is False, and the last element of the path is a symbolic\n\
4691 link, utime will modify the symbolic link itself instead of the file the\n\
4692 link points to.\n\
4693It is an error to use dir_fd or follow_symlinks when specifying path\n\
4694 as an open file descriptor.\n\
4695dir_fd and follow_symlinks may not be available on your platform.\n\
4696 If they are unavailable, using them will raise a NotImplementedError.");
4697
4698typedef struct {
4699 int now;
4700 time_t atime_s;
4701 long atime_ns;
4702 time_t mtime_s;
4703 long mtime_ns;
4704} utime_t;
4705
4706/*
Victor Stinner484df002014-10-09 13:52:31 +02004707 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708 * they also intentionally leak the declaration of a pointer named "time"
4709 */
4710#define UTIME_TO_TIMESPEC \
4711 struct timespec ts[2]; \
4712 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004713 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004714 time = NULL; \
4715 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004716 ts[0].tv_sec = ut->atime_s; \
4717 ts[0].tv_nsec = ut->atime_ns; \
4718 ts[1].tv_sec = ut->mtime_s; \
4719 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004720 time = ts; \
4721 } \
4722
4723#define UTIME_TO_TIMEVAL \
4724 struct timeval tv[2]; \
4725 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004726 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727 time = NULL; \
4728 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004729 tv[0].tv_sec = ut->atime_s; \
4730 tv[0].tv_usec = ut->atime_ns / 1000; \
4731 tv[1].tv_sec = ut->mtime_s; \
4732 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004733 time = tv; \
4734 } \
4735
4736#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004737 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004738 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004739 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004740 time = NULL; \
4741 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004742 u.actime = ut->atime_s; \
4743 u.modtime = ut->mtime_s; \
4744 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 }
4746
4747#define UTIME_TO_TIME_T \
4748 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004749 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004750 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004751 time = NULL; \
4752 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004753 timet[0] = ut->atime_s; \
4754 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004755 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004756 } \
4757
4758
4759#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4760
4761#if UTIME_HAVE_DIR_FD
4762
4763static int
Victor Stinner484df002014-10-09 13:52:31 +02004764utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765{
4766#ifdef HAVE_UTIMENSAT
4767 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4768 UTIME_TO_TIMESPEC;
4769 return utimensat(dir_fd, path, time, flags);
4770#elif defined(HAVE_FUTIMESAT)
4771 UTIME_TO_TIMEVAL;
4772 /*
4773 * follow_symlinks will never be false here;
4774 * we only allow !follow_symlinks and dir_fd together
4775 * if we have utimensat()
4776 */
4777 assert(follow_symlinks);
4778 return futimesat(dir_fd, path, time);
4779#endif
4780}
4781
4782#endif
4783
4784#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4785
4786#if UTIME_HAVE_FD
4787
4788static int
Victor Stinner484df002014-10-09 13:52:31 +02004789utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004790{
4791#ifdef HAVE_FUTIMENS
4792 UTIME_TO_TIMESPEC;
4793 return futimens(fd, time);
4794#else
4795 UTIME_TO_TIMEVAL;
4796 return futimes(fd, time);
4797#endif
4798}
4799
4800#endif
4801
4802
4803#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4804 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4805
4806#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4807
4808static int
Victor Stinner484df002014-10-09 13:52:31 +02004809utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004810{
4811#ifdef HAVE_UTIMENSAT
4812 UTIME_TO_TIMESPEC;
4813 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4814#else
4815 UTIME_TO_TIMEVAL;
4816 return lutimes(path, time);
4817#endif
4818}
4819
4820#endif
4821
4822#ifndef MS_WINDOWS
4823
4824static int
Victor Stinner484df002014-10-09 13:52:31 +02004825utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004826{
4827#ifdef HAVE_UTIMENSAT
4828 UTIME_TO_TIMESPEC;
4829 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4830#elif defined(HAVE_UTIMES)
4831 UTIME_TO_TIMEVAL;
4832 return utimes(path, time);
4833#elif defined(HAVE_UTIME_H)
4834 UTIME_TO_UTIMBUF;
4835 return utime(path, time);
4836#else
4837 UTIME_TO_TIME_T;
4838 return utime(path, time);
4839#endif
4840}
4841
4842#endif
4843
Larry Hastings76ad59b2012-05-03 00:30:07 -07004844static int
4845split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4846{
4847 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004848 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004849 divmod = PyNumber_Divmod(py_long, billion);
4850 if (!divmod)
4851 goto exit;
4852 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4853 if ((*s == -1) && PyErr_Occurred())
4854 goto exit;
4855 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004856 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004857 goto exit;
4858
4859 result = 1;
4860exit:
4861 Py_XDECREF(divmod);
4862 return result;
4863}
4864
Larry Hastings9cf065c2012-06-22 16:30:09 -07004865static PyObject *
4866posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004867{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004868 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004869 PyObject *times = NULL;
4870 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004871 int dir_fd = DEFAULT_DIR_FD;
4872 int follow_symlinks = 1;
4873 char *keywords[] = {"path", "times", "ns", "dir_fd",
4874 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004875
Larry Hastings9cf065c2012-06-22 16:30:09 -07004876 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004877
Larry Hastings9cf065c2012-06-22 16:30:09 -07004878#ifdef MS_WINDOWS
4879 HANDLE hFile;
4880 FILETIME atime, mtime;
4881#else
4882 int result;
4883#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004884
Larry Hastings9cf065c2012-06-22 16:30:09 -07004885 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004886
Larry Hastings9cf065c2012-06-22 16:30:09 -07004887 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004888 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004889 memset(&utime, 0, sizeof(utime_t));
Larry Hastings9cf065c2012-06-22 16:30:09 -07004890#if UTIME_HAVE_FD
4891 path.allow_fd = 1;
4892#endif
4893 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4894 "O&|O$OO&p:utime", keywords,
4895 path_converter, &path,
4896 &times, &ns,
4897#if UTIME_HAVE_DIR_FD
4898 dir_fd_converter, &dir_fd,
4899#else
4900 dir_fd_unavailable, &dir_fd,
4901#endif
4902 &follow_symlinks
4903 ))
4904 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004905
Larry Hastings9cf065c2012-06-22 16:30:09 -07004906 if (times && (times != Py_None) && ns) {
4907 PyErr_SetString(PyExc_ValueError,
4908 "utime: you may specify either 'times'"
4909 " or 'ns' but not both");
4910 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004911 }
4912
4913 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004914 time_t a_sec, m_sec;
4915 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004916 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004917 PyErr_SetString(PyExc_TypeError,
4918 "utime: 'times' must be either"
4919 " a tuple of two ints or None");
4920 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004921 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004922 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004923 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004924 &a_sec, &a_nsec, _PyTime_ROUND_DOWN) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004925 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004926 &m_sec, &m_nsec, _PyTime_ROUND_DOWN) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004927 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004928 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004929 utime.atime_s = a_sec;
4930 utime.atime_ns = a_nsec;
4931 utime.mtime_s = m_sec;
4932 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004933 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004934 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004935 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004936 PyErr_SetString(PyExc_TypeError,
4937 "utime: 'ns' must be a tuple of two ints");
4938 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004939 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004940 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004941 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004942 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004943 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004944 &utime.mtime_s, &utime.mtime_ns)) {
4945 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004946 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004947 }
4948 else {
4949 /* times and ns are both None/unspecified. use "now". */
4950 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004951 }
4952
Larry Hastings9cf065c2012-06-22 16:30:09 -07004953#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4954 if (follow_symlinks_specified("utime", follow_symlinks))
4955 goto exit;
4956#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004957
Larry Hastings9cf065c2012-06-22 16:30:09 -07004958 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4959 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4960 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4961 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004962
Larry Hastings9cf065c2012-06-22 16:30:09 -07004963#if !defined(HAVE_UTIMENSAT)
4964 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004965 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004966 "utime: cannot use dir_fd and follow_symlinks "
4967 "together on this platform");
4968 goto exit;
4969 }
4970#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004971
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004972#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004973 Py_BEGIN_ALLOW_THREADS
4974 if (path.wide)
4975 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004976 NULL, OPEN_EXISTING,
4977 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004978 else
4979 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004980 NULL, OPEN_EXISTING,
4981 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004982 Py_END_ALLOW_THREADS
4983 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004984 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004986 }
4987
Larry Hastings9cf065c2012-06-22 16:30:09 -07004988 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004989 GetSystemTimeAsFileTime(&mtime);
4990 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004991 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004992 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004993 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4994 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004995 }
4996 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4997 /* Avoid putting the file name into the error here,
4998 as that may confuse the user into believing that
4999 something is wrong with the file, when it also
5000 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005001 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005002 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005003 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005004#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005005 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005006
Larry Hastings9cf065c2012-06-22 16:30:09 -07005007#if UTIME_HAVE_NOFOLLOW_SYMLINKS
5008 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
5009 result = utime_nofollow_symlinks(&utime, path.narrow);
5010 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005011#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005012
5013#if UTIME_HAVE_DIR_FD
5014 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
5015 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
5016 else
5017#endif
5018
5019#if UTIME_HAVE_FD
5020 if (path.fd != -1)
5021 result = utime_fd(&utime, path.fd);
5022 else
5023#endif
5024
5025 result = utime_default(&utime, path.narrow);
5026
5027 Py_END_ALLOW_THREADS
5028
5029 if (result < 0) {
5030 /* see previous comment about not putting filename in error here */
5031 return_value = posix_error();
5032 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005033 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005034
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005035#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005036
5037 Py_INCREF(Py_None);
5038 return_value = Py_None;
5039
5040exit:
5041 path_cleanup(&path);
5042#ifdef MS_WINDOWS
5043 if (hFile != INVALID_HANDLE_VALUE)
5044 CloseHandle(hFile);
5045#endif
5046 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005047}
5048
Guido van Rossum3b066191991-06-04 19:40:25 +00005049/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005050
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005051PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005052"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005053Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005054
Barry Warsaw53699e91996-12-10 23:23:01 +00005055static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005056posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005057{
Victor Stinner8c62be82010-05-06 00:08:46 +00005058 int sts;
5059 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5060 return NULL;
5061 _exit(sts);
5062 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005063}
5064
Martin v. Löwis114619e2002-10-07 06:44:21 +00005065#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5066static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00005067free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005068{
Victor Stinner8c62be82010-05-06 00:08:46 +00005069 Py_ssize_t i;
5070 for (i = 0; i < count; i++)
5071 PyMem_Free(array[i]);
5072 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005073}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005074
Antoine Pitrou69f71142009-05-24 21:25:49 +00005075static
Martin v. Löwis011e8422009-05-05 04:43:17 +00005076int fsconvert_strdup(PyObject *o, char**out)
5077{
Victor Stinner8c62be82010-05-06 00:08:46 +00005078 PyObject *bytes;
5079 Py_ssize_t size;
5080 if (!PyUnicode_FSConverter(o, &bytes))
5081 return 0;
5082 size = PyBytes_GET_SIZE(bytes);
5083 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01005084 if (!*out) {
5085 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00005086 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01005087 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005088 memcpy(*out, PyBytes_AsString(bytes), size+1);
5089 Py_DECREF(bytes);
5090 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005091}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005092#endif
5093
Ross Lagerwall7807c352011-03-17 20:20:30 +02005094#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005095static char**
5096parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5097{
Victor Stinner8c62be82010-05-06 00:08:46 +00005098 char **envlist;
5099 Py_ssize_t i, pos, envc;
5100 PyObject *keys=NULL, *vals=NULL;
5101 PyObject *key, *val, *key2, *val2;
5102 char *p, *k, *v;
5103 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005104
Victor Stinner8c62be82010-05-06 00:08:46 +00005105 i = PyMapping_Size(env);
5106 if (i < 0)
5107 return NULL;
5108 envlist = PyMem_NEW(char *, i + 1);
5109 if (envlist == NULL) {
5110 PyErr_NoMemory();
5111 return NULL;
5112 }
5113 envc = 0;
5114 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005115 if (!keys)
5116 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005117 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005118 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005119 goto error;
5120 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5121 PyErr_Format(PyExc_TypeError,
5122 "env.keys() or env.values() is not a list");
5123 goto error;
5124 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005125
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 for (pos = 0; pos < i; pos++) {
5127 key = PyList_GetItem(keys, pos);
5128 val = PyList_GetItem(vals, pos);
5129 if (!key || !val)
5130 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005131
Victor Stinner8c62be82010-05-06 00:08:46 +00005132 if (PyUnicode_FSConverter(key, &key2) == 0)
5133 goto error;
5134 if (PyUnicode_FSConverter(val, &val2) == 0) {
5135 Py_DECREF(key2);
5136 goto error;
5137 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005138
Victor Stinner8c62be82010-05-06 00:08:46 +00005139 k = PyBytes_AsString(key2);
5140 v = PyBytes_AsString(val2);
5141 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005142
Victor Stinner8c62be82010-05-06 00:08:46 +00005143 p = PyMem_NEW(char, len);
5144 if (p == NULL) {
5145 PyErr_NoMemory();
5146 Py_DECREF(key2);
5147 Py_DECREF(val2);
5148 goto error;
5149 }
5150 PyOS_snprintf(p, len, "%s=%s", k, v);
5151 envlist[envc++] = p;
5152 Py_DECREF(key2);
5153 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005154 }
5155 Py_DECREF(vals);
5156 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005157
Victor Stinner8c62be82010-05-06 00:08:46 +00005158 envlist[envc] = 0;
5159 *envc_ptr = envc;
5160 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005161
5162error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005163 Py_XDECREF(keys);
5164 Py_XDECREF(vals);
5165 while (--envc >= 0)
5166 PyMem_DEL(envlist[envc]);
5167 PyMem_DEL(envlist);
5168 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005169}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005170
Ross Lagerwall7807c352011-03-17 20:20:30 +02005171static char**
5172parse_arglist(PyObject* argv, Py_ssize_t *argc)
5173{
5174 int i;
5175 char **argvlist = PyMem_NEW(char *, *argc+1);
5176 if (argvlist == NULL) {
5177 PyErr_NoMemory();
5178 return NULL;
5179 }
5180 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005181 PyObject* item = PySequence_ITEM(argv, i);
5182 if (item == NULL)
5183 goto fail;
5184 if (!fsconvert_strdup(item, &argvlist[i])) {
5185 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005186 goto fail;
5187 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005188 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005189 }
5190 argvlist[*argc] = NULL;
5191 return argvlist;
5192fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005193 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005194 free_string_array(argvlist, *argc);
5195 return NULL;
5196}
5197#endif
5198
5199#ifdef HAVE_EXECV
5200PyDoc_STRVAR(posix_execv__doc__,
5201"execv(path, args)\n\n\
5202Execute an executable path with arguments, replacing current process.\n\
5203\n\
5204 path: path of executable file\n\
5205 args: tuple or list of strings");
5206
5207static PyObject *
5208posix_execv(PyObject *self, PyObject *args)
5209{
5210 PyObject *opath;
5211 char *path;
5212 PyObject *argv;
5213 char **argvlist;
5214 Py_ssize_t argc;
5215
5216 /* execv has two arguments: (path, argv), where
5217 argv is a list or tuple of strings. */
5218
5219 if (!PyArg_ParseTuple(args, "O&O:execv",
5220 PyUnicode_FSConverter,
5221 &opath, &argv))
5222 return NULL;
5223 path = PyBytes_AsString(opath);
5224 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5225 PyErr_SetString(PyExc_TypeError,
5226 "execv() arg 2 must be a tuple or list");
5227 Py_DECREF(opath);
5228 return NULL;
5229 }
5230 argc = PySequence_Size(argv);
5231 if (argc < 1) {
5232 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5233 Py_DECREF(opath);
5234 return NULL;
5235 }
5236
5237 argvlist = parse_arglist(argv, &argc);
5238 if (argvlist == NULL) {
5239 Py_DECREF(opath);
5240 return NULL;
5241 }
5242
5243 execv(path, argvlist);
5244
5245 /* If we get here it's definitely an error */
5246
5247 free_string_array(argvlist, argc);
5248 Py_DECREF(opath);
5249 return posix_error();
5250}
5251
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005252PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005253"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005254Execute a path with arguments and environment, replacing current process.\n\
5255\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005256 path: path of executable file\n\
5257 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005258 env: dictionary of strings mapping to strings\n\
5259\n\
5260On some platforms, you may specify an open file descriptor for path;\n\
5261 execve will execute the program the file descriptor is open to.\n\
5262 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005263
Barry Warsaw53699e91996-12-10 23:23:01 +00005264static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005265posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005266{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005267 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005268 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005269 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005270 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005271 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005272 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005273
Victor Stinner8c62be82010-05-06 00:08:46 +00005274 /* execve has three arguments: (path, argv, env), where
5275 argv is a list or tuple of strings and env is a dictionary
5276 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005277
Larry Hastings9cf065c2012-06-22 16:30:09 -07005278 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005279 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005280#ifdef HAVE_FEXECVE
5281 path.allow_fd = 1;
5282#endif
5283 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5284 path_converter, &path,
5285 &argv, &env
5286 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005287 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005288
Ross Lagerwall7807c352011-03-17 20:20:30 +02005289 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005290 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005291 "execve: argv must be a tuple or list");
5292 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005293 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005294 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005295 if (!PyMapping_Check(env)) {
5296 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005297 "execve: environment must be a mapping object");
5298 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005299 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005300
Ross Lagerwall7807c352011-03-17 20:20:30 +02005301 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005302 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005303 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005304 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005305
Victor Stinner8c62be82010-05-06 00:08:46 +00005306 envlist = parse_envlist(env, &envc);
5307 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005308 goto fail;
5309
Larry Hastings9cf065c2012-06-22 16:30:09 -07005310#ifdef HAVE_FEXECVE
5311 if (path.fd > -1)
5312 fexecve(path.fd, argvlist, envlist);
5313 else
5314#endif
5315 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005316
5317 /* If we get here it's definitely an error */
5318
Victor Stinner292c8352012-10-30 02:17:38 +01005319 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005320
5321 while (--envc >= 0)
5322 PyMem_DEL(envlist[envc]);
5323 PyMem_DEL(envlist);
5324 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005325 if (argvlist)
5326 free_string_array(argvlist, argc);
5327 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005328 return NULL;
5329}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005330#endif /* HAVE_EXECV */
5331
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005332
Guido van Rossuma1065681999-01-25 23:20:23 +00005333#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005334PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005335"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005336Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005337\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005338 mode: mode of process creation\n\
5339 path: path of executable file\n\
5340 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005341
5342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005343posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005344{
Victor Stinner8c62be82010-05-06 00:08:46 +00005345 PyObject *opath;
5346 char *path;
5347 PyObject *argv;
5348 char **argvlist;
5349 int mode, i;
5350 Py_ssize_t argc;
5351 Py_intptr_t spawnval;
5352 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005353
Victor Stinner8c62be82010-05-06 00:08:46 +00005354 /* spawnv has three arguments: (mode, path, argv), where
5355 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005356
Victor Stinner8c62be82010-05-06 00:08:46 +00005357 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5358 PyUnicode_FSConverter,
5359 &opath, &argv))
5360 return NULL;
5361 path = PyBytes_AsString(opath);
5362 if (PyList_Check(argv)) {
5363 argc = PyList_Size(argv);
5364 getitem = PyList_GetItem;
5365 }
5366 else if (PyTuple_Check(argv)) {
5367 argc = PyTuple_Size(argv);
5368 getitem = PyTuple_GetItem;
5369 }
5370 else {
5371 PyErr_SetString(PyExc_TypeError,
5372 "spawnv() arg 2 must be a tuple or list");
5373 Py_DECREF(opath);
5374 return NULL;
5375 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005376
Victor Stinner8c62be82010-05-06 00:08:46 +00005377 argvlist = PyMem_NEW(char *, argc+1);
5378 if (argvlist == NULL) {
5379 Py_DECREF(opath);
5380 return PyErr_NoMemory();
5381 }
5382 for (i = 0; i < argc; i++) {
5383 if (!fsconvert_strdup((*getitem)(argv, i),
5384 &argvlist[i])) {
5385 free_string_array(argvlist, i);
5386 PyErr_SetString(
5387 PyExc_TypeError,
5388 "spawnv() arg 2 must contain only strings");
5389 Py_DECREF(opath);
5390 return NULL;
5391 }
5392 }
5393 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005394
Victor Stinner8c62be82010-05-06 00:08:46 +00005395 if (mode == _OLD_P_OVERLAY)
5396 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005397
Victor Stinner8c62be82010-05-06 00:08:46 +00005398 Py_BEGIN_ALLOW_THREADS
5399 spawnval = _spawnv(mode, path, argvlist);
5400 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005401
Victor Stinner8c62be82010-05-06 00:08:46 +00005402 free_string_array(argvlist, argc);
5403 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005404
Victor Stinner8c62be82010-05-06 00:08:46 +00005405 if (spawnval == -1)
5406 return posix_error();
5407 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005408 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005409}
5410
5411
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005412PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005413"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005414Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005415\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005416 mode: mode of process creation\n\
5417 path: path of executable file\n\
5418 args: tuple or list of arguments\n\
5419 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005420
5421static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005422posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005423{
Victor Stinner8c62be82010-05-06 00:08:46 +00005424 PyObject *opath;
5425 char *path;
5426 PyObject *argv, *env;
5427 char **argvlist;
5428 char **envlist;
5429 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005430 int mode;
5431 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005432 Py_intptr_t spawnval;
5433 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5434 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005435
Victor Stinner8c62be82010-05-06 00:08:46 +00005436 /* spawnve has four arguments: (mode, path, argv, env), where
5437 argv is a list or tuple of strings and env is a dictionary
5438 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005439
Victor Stinner8c62be82010-05-06 00:08:46 +00005440 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5441 PyUnicode_FSConverter,
5442 &opath, &argv, &env))
5443 return NULL;
5444 path = PyBytes_AsString(opath);
5445 if (PyList_Check(argv)) {
5446 argc = PyList_Size(argv);
5447 getitem = PyList_GetItem;
5448 }
5449 else if (PyTuple_Check(argv)) {
5450 argc = PyTuple_Size(argv);
5451 getitem = PyTuple_GetItem;
5452 }
5453 else {
5454 PyErr_SetString(PyExc_TypeError,
5455 "spawnve() arg 2 must be a tuple or list");
5456 goto fail_0;
5457 }
5458 if (!PyMapping_Check(env)) {
5459 PyErr_SetString(PyExc_TypeError,
5460 "spawnve() arg 3 must be a mapping object");
5461 goto fail_0;
5462 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005463
Victor Stinner8c62be82010-05-06 00:08:46 +00005464 argvlist = PyMem_NEW(char *, argc+1);
5465 if (argvlist == NULL) {
5466 PyErr_NoMemory();
5467 goto fail_0;
5468 }
5469 for (i = 0; i < argc; i++) {
5470 if (!fsconvert_strdup((*getitem)(argv, i),
5471 &argvlist[i]))
5472 {
5473 lastarg = i;
5474 goto fail_1;
5475 }
5476 }
5477 lastarg = argc;
5478 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005479
Victor Stinner8c62be82010-05-06 00:08:46 +00005480 envlist = parse_envlist(env, &envc);
5481 if (envlist == NULL)
5482 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005483
Victor Stinner8c62be82010-05-06 00:08:46 +00005484 if (mode == _OLD_P_OVERLAY)
5485 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005486
Victor Stinner8c62be82010-05-06 00:08:46 +00005487 Py_BEGIN_ALLOW_THREADS
5488 spawnval = _spawnve(mode, path, argvlist, envlist);
5489 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005490
Victor Stinner8c62be82010-05-06 00:08:46 +00005491 if (spawnval == -1)
5492 (void) posix_error();
5493 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005494 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005495
Victor Stinner8c62be82010-05-06 00:08:46 +00005496 while (--envc >= 0)
5497 PyMem_DEL(envlist[envc]);
5498 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005499 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005500 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005501 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005502 Py_DECREF(opath);
5503 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005504}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005505
Guido van Rossuma1065681999-01-25 23:20:23 +00005506#endif /* HAVE_SPAWNV */
5507
5508
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005509#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005510PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005511"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005512Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5513\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005514Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005515
5516static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005517posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005518{
Victor Stinner8c62be82010-05-06 00:08:46 +00005519 pid_t pid;
5520 int result = 0;
5521 _PyImport_AcquireLock();
5522 pid = fork1();
5523 if (pid == 0) {
5524 /* child: this clobbers and resets the import lock. */
5525 PyOS_AfterFork();
5526 } else {
5527 /* parent: release the import lock. */
5528 result = _PyImport_ReleaseLock();
5529 }
5530 if (pid == -1)
5531 return posix_error();
5532 if (result < 0) {
5533 /* Don't clobber the OSError if the fork failed. */
5534 PyErr_SetString(PyExc_RuntimeError,
5535 "not holding the import lock");
5536 return NULL;
5537 }
5538 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005539}
5540#endif
5541
5542
Guido van Rossumad0ee831995-03-01 10:34:45 +00005543#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005544PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005545"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005546Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005547Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005548
Barry Warsaw53699e91996-12-10 23:23:01 +00005549static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005550posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005551{
Victor Stinner8c62be82010-05-06 00:08:46 +00005552 pid_t pid;
5553 int result = 0;
5554 _PyImport_AcquireLock();
5555 pid = fork();
5556 if (pid == 0) {
5557 /* child: this clobbers and resets the import lock. */
5558 PyOS_AfterFork();
5559 } else {
5560 /* parent: release the import lock. */
5561 result = _PyImport_ReleaseLock();
5562 }
5563 if (pid == -1)
5564 return posix_error();
5565 if (result < 0) {
5566 /* Don't clobber the OSError if the fork failed. */
5567 PyErr_SetString(PyExc_RuntimeError,
5568 "not holding the import lock");
5569 return NULL;
5570 }
5571 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005572}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005573#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005574
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005575#ifdef HAVE_SCHED_H
5576
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005577#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5578
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005579PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5580"sched_get_priority_max(policy)\n\n\
5581Get the maximum scheduling priority for *policy*.");
5582
5583static PyObject *
5584posix_sched_get_priority_max(PyObject *self, PyObject *args)
5585{
5586 int policy, max;
5587
5588 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5589 return NULL;
5590 max = sched_get_priority_max(policy);
5591 if (max < 0)
5592 return posix_error();
5593 return PyLong_FromLong(max);
5594}
5595
5596PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5597"sched_get_priority_min(policy)\n\n\
5598Get the minimum scheduling priority for *policy*.");
5599
5600static PyObject *
5601posix_sched_get_priority_min(PyObject *self, PyObject *args)
5602{
5603 int policy, min;
5604
5605 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5606 return NULL;
5607 min = sched_get_priority_min(policy);
5608 if (min < 0)
5609 return posix_error();
5610 return PyLong_FromLong(min);
5611}
5612
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005613#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5614
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005615#ifdef HAVE_SCHED_SETSCHEDULER
5616
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005617PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5618"sched_getscheduler(pid)\n\n\
5619Get the scheduling policy for the process with a PID of *pid*.\n\
5620Passing a PID of 0 returns the scheduling policy for the calling process.");
5621
5622static PyObject *
5623posix_sched_getscheduler(PyObject *self, PyObject *args)
5624{
5625 pid_t pid;
5626 int policy;
5627
5628 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5629 return NULL;
5630 policy = sched_getscheduler(pid);
5631 if (policy < 0)
5632 return posix_error();
5633 return PyLong_FromLong(policy);
5634}
5635
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005636#endif
5637
5638#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5639
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005640static PyObject *
5641sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5642{
5643 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005644 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005645
5646 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5647 return NULL;
5648 res = PyStructSequence_New(type);
5649 if (!res)
5650 return NULL;
5651 Py_INCREF(priority);
5652 PyStructSequence_SET_ITEM(res, 0, priority);
5653 return res;
5654}
5655
5656PyDoc_STRVAR(sched_param__doc__,
5657"sched_param(sched_priority): A scheduling parameter.\n\n\
5658Current has only one field: sched_priority");
5659
5660static PyStructSequence_Field sched_param_fields[] = {
5661 {"sched_priority", "the scheduling priority"},
5662 {0}
5663};
5664
5665static PyStructSequence_Desc sched_param_desc = {
5666 "sched_param", /* name */
5667 sched_param__doc__, /* doc */
5668 sched_param_fields,
5669 1
5670};
5671
5672static int
5673convert_sched_param(PyObject *param, struct sched_param *res)
5674{
5675 long priority;
5676
5677 if (Py_TYPE(param) != &SchedParamType) {
5678 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5679 return 0;
5680 }
5681 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5682 if (priority == -1 && PyErr_Occurred())
5683 return 0;
5684 if (priority > INT_MAX || priority < INT_MIN) {
5685 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5686 return 0;
5687 }
5688 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5689 return 1;
5690}
5691
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005692#endif
5693
5694#ifdef HAVE_SCHED_SETSCHEDULER
5695
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005696PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5697"sched_setscheduler(pid, policy, param)\n\n\
5698Set the scheduling policy, *policy*, for *pid*.\n\
5699If *pid* is 0, the calling process is changed.\n\
5700*param* is an instance of sched_param.");
5701
5702static PyObject *
5703posix_sched_setscheduler(PyObject *self, PyObject *args)
5704{
5705 pid_t pid;
5706 int policy;
5707 struct sched_param param;
5708
5709 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5710 &pid, &policy, &convert_sched_param, &param))
5711 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005712
5713 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005714 ** sched_setscheduler() returns 0 in Linux, but the previous
5715 ** scheduling policy under Solaris/Illumos, and others.
5716 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005717 */
5718 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005719 return posix_error();
5720 Py_RETURN_NONE;
5721}
5722
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005723#endif
5724
5725#ifdef HAVE_SCHED_SETPARAM
5726
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005727PyDoc_STRVAR(posix_sched_getparam__doc__,
5728"sched_getparam(pid) -> sched_param\n\n\
5729Returns scheduling parameters for the process with *pid* as an instance of the\n\
5730sched_param class. A PID of 0 means the calling process.");
5731
5732static PyObject *
5733posix_sched_getparam(PyObject *self, PyObject *args)
5734{
5735 pid_t pid;
5736 struct sched_param param;
5737 PyObject *res, *priority;
5738
5739 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5740 return NULL;
5741 if (sched_getparam(pid, &param))
5742 return posix_error();
5743 res = PyStructSequence_New(&SchedParamType);
5744 if (!res)
5745 return NULL;
5746 priority = PyLong_FromLong(param.sched_priority);
5747 if (!priority) {
5748 Py_DECREF(res);
5749 return NULL;
5750 }
5751 PyStructSequence_SET_ITEM(res, 0, priority);
5752 return res;
5753}
5754
5755PyDoc_STRVAR(posix_sched_setparam__doc__,
5756"sched_setparam(pid, param)\n\n\
5757Set scheduling parameters for a process with PID *pid*.\n\
5758A PID of 0 means the calling process.");
5759
5760static PyObject *
5761posix_sched_setparam(PyObject *self, PyObject *args)
5762{
5763 pid_t pid;
5764 struct sched_param param;
5765
5766 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5767 &pid, &convert_sched_param, &param))
5768 return NULL;
5769 if (sched_setparam(pid, &param))
5770 return posix_error();
5771 Py_RETURN_NONE;
5772}
5773
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005774#endif
5775
5776#ifdef HAVE_SCHED_RR_GET_INTERVAL
5777
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005778PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5779"sched_rr_get_interval(pid) -> float\n\n\
5780Return the round-robin quantum for the process with PID *pid* in seconds.");
5781
5782static PyObject *
5783posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5784{
5785 pid_t pid;
5786 struct timespec interval;
5787
5788 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5789 return NULL;
5790 if (sched_rr_get_interval(pid, &interval))
5791 return posix_error();
5792 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5793}
5794
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005795#endif
5796
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005797PyDoc_STRVAR(posix_sched_yield__doc__,
5798"sched_yield()\n\n\
5799Voluntarily relinquish the CPU.");
5800
5801static PyObject *
5802posix_sched_yield(PyObject *self, PyObject *noargs)
5803{
5804 if (sched_yield())
5805 return posix_error();
5806 Py_RETURN_NONE;
5807}
5808
Benjamin Peterson2740af82011-08-02 17:41:34 -05005809#ifdef HAVE_SCHED_SETAFFINITY
5810
Antoine Pitrou84869872012-08-04 16:16:35 +02005811/* The minimum number of CPUs allocated in a cpu_set_t */
5812static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005813
5814PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5815"sched_setaffinity(pid, cpu_set)\n\n\
5816Set the affinity of the process with PID *pid* to *cpu_set*.");
5817
5818static PyObject *
5819posix_sched_setaffinity(PyObject *self, PyObject *args)
5820{
5821 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005822 int ncpus;
5823 size_t setsize;
5824 cpu_set_t *mask = NULL;
5825 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005826
Antoine Pitrou84869872012-08-04 16:16:35 +02005827 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5828 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005829 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005830
5831 iterator = PyObject_GetIter(iterable);
5832 if (iterator == NULL)
5833 return NULL;
5834
5835 ncpus = NCPUS_START;
5836 setsize = CPU_ALLOC_SIZE(ncpus);
5837 mask = CPU_ALLOC(ncpus);
5838 if (mask == NULL) {
5839 PyErr_NoMemory();
5840 goto error;
5841 }
5842 CPU_ZERO_S(setsize, mask);
5843
5844 while ((item = PyIter_Next(iterator))) {
5845 long cpu;
5846 if (!PyLong_Check(item)) {
5847 PyErr_Format(PyExc_TypeError,
5848 "expected an iterator of ints, "
5849 "but iterator yielded %R",
5850 Py_TYPE(item));
5851 Py_DECREF(item);
5852 goto error;
5853 }
5854 cpu = PyLong_AsLong(item);
5855 Py_DECREF(item);
5856 if (cpu < 0) {
5857 if (!PyErr_Occurred())
5858 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5859 goto error;
5860 }
5861 if (cpu > INT_MAX - 1) {
5862 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5863 goto error;
5864 }
5865 if (cpu >= ncpus) {
5866 /* Grow CPU mask to fit the CPU number */
5867 int newncpus = ncpus;
5868 cpu_set_t *newmask;
5869 size_t newsetsize;
5870 while (newncpus <= cpu) {
5871 if (newncpus > INT_MAX / 2)
5872 newncpus = cpu + 1;
5873 else
5874 newncpus = newncpus * 2;
5875 }
5876 newmask = CPU_ALLOC(newncpus);
5877 if (newmask == NULL) {
5878 PyErr_NoMemory();
5879 goto error;
5880 }
5881 newsetsize = CPU_ALLOC_SIZE(newncpus);
5882 CPU_ZERO_S(newsetsize, newmask);
5883 memcpy(newmask, mask, setsize);
5884 CPU_FREE(mask);
5885 setsize = newsetsize;
5886 mask = newmask;
5887 ncpus = newncpus;
5888 }
5889 CPU_SET_S(cpu, setsize, mask);
5890 }
5891 Py_CLEAR(iterator);
5892
5893 if (sched_setaffinity(pid, setsize, mask)) {
5894 posix_error();
5895 goto error;
5896 }
5897 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005898 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005899
5900error:
5901 if (mask)
5902 CPU_FREE(mask);
5903 Py_XDECREF(iterator);
5904 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005905}
5906
5907PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5908"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5909Return the affinity of the process with PID *pid*.\n\
5910The returned cpu_set will be of size *ncpus*.");
5911
5912static PyObject *
5913posix_sched_getaffinity(PyObject *self, PyObject *args)
5914{
5915 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005916 int cpu, ncpus, count;
5917 size_t setsize;
5918 cpu_set_t *mask = NULL;
5919 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005920
Antoine Pitrou84869872012-08-04 16:16:35 +02005921 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5922 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005923 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005924
5925 ncpus = NCPUS_START;
5926 while (1) {
5927 setsize = CPU_ALLOC_SIZE(ncpus);
5928 mask = CPU_ALLOC(ncpus);
5929 if (mask == NULL)
5930 return PyErr_NoMemory();
5931 if (sched_getaffinity(pid, setsize, mask) == 0)
5932 break;
5933 CPU_FREE(mask);
5934 if (errno != EINVAL)
5935 return posix_error();
5936 if (ncpus > INT_MAX / 2) {
5937 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5938 "a large enough CPU set");
5939 return NULL;
5940 }
5941 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005942 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005943
5944 res = PySet_New(NULL);
5945 if (res == NULL)
5946 goto error;
5947 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5948 if (CPU_ISSET_S(cpu, setsize, mask)) {
5949 PyObject *cpu_num = PyLong_FromLong(cpu);
5950 --count;
5951 if (cpu_num == NULL)
5952 goto error;
5953 if (PySet_Add(res, cpu_num)) {
5954 Py_DECREF(cpu_num);
5955 goto error;
5956 }
5957 Py_DECREF(cpu_num);
5958 }
5959 }
5960 CPU_FREE(mask);
5961 return res;
5962
5963error:
5964 if (mask)
5965 CPU_FREE(mask);
5966 Py_XDECREF(res);
5967 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005968}
5969
Benjamin Peterson2740af82011-08-02 17:41:34 -05005970#endif /* HAVE_SCHED_SETAFFINITY */
5971
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005972#endif /* HAVE_SCHED_H */
5973
Neal Norwitzb59798b2003-03-21 01:43:31 +00005974/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005975/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5976#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005977#define DEV_PTY_FILE "/dev/ptc"
5978#define HAVE_DEV_PTMX
5979#else
5980#define DEV_PTY_FILE "/dev/ptmx"
5981#endif
5982
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005983#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005984#ifdef HAVE_PTY_H
5985#include <pty.h>
5986#else
5987#ifdef HAVE_LIBUTIL_H
5988#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005989#else
5990#ifdef HAVE_UTIL_H
5991#include <util.h>
5992#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005993#endif /* HAVE_LIBUTIL_H */
5994#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005995#ifdef HAVE_STROPTS_H
5996#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005997#endif
5998#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005999
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006000#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006001PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006002"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006003Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006004
6005static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006006posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006007{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006008 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006009#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006010 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006011#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006012#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006013 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006014#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006015 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006016#endif
6017#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006018
Thomas Wouters70c21a12000-07-14 14:28:33 +00006019#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006020 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006021 goto posix_error;
6022
6023 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6024 goto error;
6025 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6026 goto error;
6027
Neal Norwitzb59798b2003-03-21 01:43:31 +00006028#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006029 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6030 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006031 goto posix_error;
6032 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6033 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006034
Victor Stinnerdaf45552013-08-28 00:53:59 +02006035 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006037 goto posix_error;
6038
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006039#else
Victor Stinner000de532013-11-25 23:19:58 +01006040 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006041 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006042 goto posix_error;
6043
Victor Stinner8c62be82010-05-06 00:08:46 +00006044 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006045
Victor Stinner8c62be82010-05-06 00:08:46 +00006046 /* change permission of slave */
6047 if (grantpt(master_fd) < 0) {
6048 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006049 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006050 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006051
Victor Stinner8c62be82010-05-06 00:08:46 +00006052 /* unlock slave */
6053 if (unlockpt(master_fd) < 0) {
6054 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006055 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006056 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006057
Victor Stinner8c62be82010-05-06 00:08:46 +00006058 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006059
Victor Stinner8c62be82010-05-06 00:08:46 +00006060 slave_name = ptsname(master_fd); /* get name of slave */
6061 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006062 goto posix_error;
6063
6064 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00006065 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006066 goto posix_error;
Victor Stinner000de532013-11-25 23:19:58 +01006067
6068 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6069 goto posix_error;
6070
Neal Norwitzb59798b2003-03-21 01:43:31 +00006071#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006072 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6073 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006074#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006075 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006076#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006077#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006078#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006079
Victor Stinner8c62be82010-05-06 00:08:46 +00006080 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006081
Victor Stinnerdaf45552013-08-28 00:53:59 +02006082posix_error:
6083 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006084#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006085error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006086#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02006087 if (master_fd != -1)
6088 close(master_fd);
6089 if (slave_fd != -1)
6090 close(slave_fd);
6091 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006092}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006093#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006094
6095#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006096PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006097"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006098Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6099Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006100To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006101
6102static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006103posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006104{
Victor Stinner8c62be82010-05-06 00:08:46 +00006105 int master_fd = -1, result = 0;
6106 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006107
Victor Stinner8c62be82010-05-06 00:08:46 +00006108 _PyImport_AcquireLock();
6109 pid = forkpty(&master_fd, NULL, NULL, NULL);
6110 if (pid == 0) {
6111 /* child: this clobbers and resets the import lock. */
6112 PyOS_AfterFork();
6113 } else {
6114 /* parent: release the import lock. */
6115 result = _PyImport_ReleaseLock();
6116 }
6117 if (pid == -1)
6118 return posix_error();
6119 if (result < 0) {
6120 /* Don't clobber the OSError if the fork failed. */
6121 PyErr_SetString(PyExc_RuntimeError,
6122 "not holding the import lock");
6123 return NULL;
6124 }
6125 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006126}
6127#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006128
Ross Lagerwall7807c352011-03-17 20:20:30 +02006129
Guido van Rossumad0ee831995-03-01 10:34:45 +00006130#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006131PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006132"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006133Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006134
Barry Warsaw53699e91996-12-10 23:23:01 +00006135static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006136posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006137{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006138 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006139}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006140#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006141
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006142
Guido van Rossumad0ee831995-03-01 10:34:45 +00006143#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006144PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006145"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006146Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006147
Barry Warsaw53699e91996-12-10 23:23:01 +00006148static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006149posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006150{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006151 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006152}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006153#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006155
Guido van Rossumad0ee831995-03-01 10:34:45 +00006156#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006157PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006158"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006159Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006160
Barry Warsaw53699e91996-12-10 23:23:01 +00006161static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006162posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006163{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006164 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006165}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006166#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006167
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006168
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006169PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006170"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006171Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006172
Barry Warsaw53699e91996-12-10 23:23:01 +00006173static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006174posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006175{
Victor Stinner8c62be82010-05-06 00:08:46 +00006176 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006177}
6178
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006179#ifdef HAVE_GETGROUPLIST
6180PyDoc_STRVAR(posix_getgrouplist__doc__,
6181"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6182Returns a list of groups to which a user belongs.\n\n\
6183 user: username to lookup\n\
6184 group: base group id of the user");
6185
6186static PyObject *
6187posix_getgrouplist(PyObject *self, PyObject *args)
6188{
6189#ifdef NGROUPS_MAX
6190#define MAX_GROUPS NGROUPS_MAX
6191#else
6192 /* defined to be 16 on Solaris7, so this should be a small number */
6193#define MAX_GROUPS 64
6194#endif
6195
6196 const char *user;
6197 int i, ngroups;
6198 PyObject *list;
6199#ifdef __APPLE__
6200 int *groups, basegid;
6201#else
6202 gid_t *groups, basegid;
6203#endif
6204 ngroups = MAX_GROUPS;
6205
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006206#ifdef __APPLE__
6207 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006208 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006209#else
6210 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6211 _Py_Gid_Converter, &basegid))
6212 return NULL;
6213#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006214
6215#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006216 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006217#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006218 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006219#endif
6220 if (groups == NULL)
6221 return PyErr_NoMemory();
6222
6223 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6224 PyMem_Del(groups);
6225 return posix_error();
6226 }
6227
6228 list = PyList_New(ngroups);
6229 if (list == NULL) {
6230 PyMem_Del(groups);
6231 return NULL;
6232 }
6233
6234 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006235#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006236 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006237#else
6238 PyObject *o = _PyLong_FromGid(groups[i]);
6239#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006240 if (o == NULL) {
6241 Py_DECREF(list);
6242 PyMem_Del(groups);
6243 return NULL;
6244 }
6245 PyList_SET_ITEM(list, i, o);
6246 }
6247
6248 PyMem_Del(groups);
6249
6250 return list;
6251}
6252#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006253
Fred Drakec9680921999-12-13 16:37:25 +00006254#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006255PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006256"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006257Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006258
6259static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006260posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006261{
6262 PyObject *result = NULL;
6263
Fred Drakec9680921999-12-13 16:37:25 +00006264#ifdef NGROUPS_MAX
6265#define MAX_GROUPS NGROUPS_MAX
6266#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006267 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006268#define MAX_GROUPS 64
6269#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006270 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006271
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006272 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006273 * This is a helper variable to store the intermediate result when
6274 * that happens.
6275 *
6276 * To keep the code readable the OSX behaviour is unconditional,
6277 * according to the POSIX spec this should be safe on all unix-y
6278 * systems.
6279 */
6280 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006281 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006282
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006283#ifdef __APPLE__
6284 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6285 * there are more groups than can fit in grouplist. Therefore, on OS X
6286 * always first call getgroups with length 0 to get the actual number
6287 * of groups.
6288 */
6289 n = getgroups(0, NULL);
6290 if (n < 0) {
6291 return posix_error();
6292 } else if (n <= MAX_GROUPS) {
6293 /* groups will fit in existing array */
6294 alt_grouplist = grouplist;
6295 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006296 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006297 if (alt_grouplist == NULL) {
6298 errno = EINVAL;
6299 return posix_error();
6300 }
6301 }
6302
6303 n = getgroups(n, alt_grouplist);
6304 if (n == -1) {
6305 if (alt_grouplist != grouplist) {
6306 PyMem_Free(alt_grouplist);
6307 }
6308 return posix_error();
6309 }
6310#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006311 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006312 if (n < 0) {
6313 if (errno == EINVAL) {
6314 n = getgroups(0, NULL);
6315 if (n == -1) {
6316 return posix_error();
6317 }
6318 if (n == 0) {
6319 /* Avoid malloc(0) */
6320 alt_grouplist = grouplist;
6321 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006322 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006323 if (alt_grouplist == NULL) {
6324 errno = EINVAL;
6325 return posix_error();
6326 }
6327 n = getgroups(n, alt_grouplist);
6328 if (n == -1) {
6329 PyMem_Free(alt_grouplist);
6330 return posix_error();
6331 }
6332 }
6333 } else {
6334 return posix_error();
6335 }
6336 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006337#endif
6338
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006339 result = PyList_New(n);
6340 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006341 int i;
6342 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006343 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006344 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006345 Py_DECREF(result);
6346 result = NULL;
6347 break;
Fred Drakec9680921999-12-13 16:37:25 +00006348 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006349 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006350 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006351 }
6352
6353 if (alt_grouplist != grouplist) {
6354 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006356
Fred Drakec9680921999-12-13 16:37:25 +00006357 return result;
6358}
6359#endif
6360
Antoine Pitroub7572f02009-12-02 20:46:48 +00006361#ifdef HAVE_INITGROUPS
6362PyDoc_STRVAR(posix_initgroups__doc__,
6363"initgroups(username, gid) -> None\n\n\
6364Call the system initgroups() to initialize the group access list with all of\n\
6365the groups of which the specified username is a member, plus the specified\n\
6366group id.");
6367
6368static PyObject *
6369posix_initgroups(PyObject *self, PyObject *args)
6370{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006371 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006372 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006373 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006374#ifdef __APPLE__
6375 int gid;
6376#else
6377 gid_t gid;
6378#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006379
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006380#ifdef __APPLE__
6381 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6382 PyUnicode_FSConverter, &oname,
6383 &gid))
6384#else
6385 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6386 PyUnicode_FSConverter, &oname,
6387 _Py_Gid_Converter, &gid))
6388#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006389 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006390 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006391
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006392 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006393 Py_DECREF(oname);
6394 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006395 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006396
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 Py_INCREF(Py_None);
6398 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006399}
6400#endif
6401
Martin v. Löwis606edc12002-06-13 21:09:11 +00006402#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006403PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006404"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006405Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006406
6407static PyObject *
6408posix_getpgid(PyObject *self, PyObject *args)
6409{
Victor Stinner8c62be82010-05-06 00:08:46 +00006410 pid_t pid, pgid;
6411 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6412 return NULL;
6413 pgid = getpgid(pid);
6414 if (pgid < 0)
6415 return posix_error();
6416 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006417}
6418#endif /* HAVE_GETPGID */
6419
6420
Guido van Rossumb6775db1994-08-01 11:34:53 +00006421#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006422PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006423"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006424Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006425
Barry Warsaw53699e91996-12-10 23:23:01 +00006426static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006427posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006428{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006429#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006430 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006431#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006432 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006433#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006434}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006435#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006436
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006437
Guido van Rossumb6775db1994-08-01 11:34:53 +00006438#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006439PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006440"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006441Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006442
Barry Warsaw53699e91996-12-10 23:23:01 +00006443static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006444posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006445{
Guido van Rossum64933891994-10-20 21:56:42 +00006446#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006447 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006448#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006450#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006451 return posix_error();
6452 Py_INCREF(Py_None);
6453 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006454}
6455
Guido van Rossumb6775db1994-08-01 11:34:53 +00006456#endif /* HAVE_SETPGRP */
6457
Guido van Rossumad0ee831995-03-01 10:34:45 +00006458#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006459
6460#ifdef MS_WINDOWS
6461#include <tlhelp32.h>
6462
6463static PyObject*
6464win32_getppid()
6465{
6466 HANDLE snapshot;
6467 pid_t mypid;
6468 PyObject* result = NULL;
6469 BOOL have_record;
6470 PROCESSENTRY32 pe;
6471
6472 mypid = getpid(); /* This function never fails */
6473
6474 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6475 if (snapshot == INVALID_HANDLE_VALUE)
6476 return PyErr_SetFromWindowsErr(GetLastError());
6477
6478 pe.dwSize = sizeof(pe);
6479 have_record = Process32First(snapshot, &pe);
6480 while (have_record) {
6481 if (mypid == (pid_t)pe.th32ProcessID) {
6482 /* We could cache the ulong value in a static variable. */
6483 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6484 break;
6485 }
6486
6487 have_record = Process32Next(snapshot, &pe);
6488 }
6489
6490 /* If our loop exits and our pid was not found (result will be NULL)
6491 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6492 * error anyway, so let's raise it. */
6493 if (!result)
6494 result = PyErr_SetFromWindowsErr(GetLastError());
6495
6496 CloseHandle(snapshot);
6497
6498 return result;
6499}
6500#endif /*MS_WINDOWS*/
6501
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006502PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006503"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006504Return the parent's process id. If the parent process has already exited,\n\
6505Windows machines will still return its id; others systems will return the id\n\
6506of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006507
Barry Warsaw53699e91996-12-10 23:23:01 +00006508static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006509posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006510{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006511#ifdef MS_WINDOWS
6512 return win32_getppid();
6513#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006514 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006515#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006516}
6517#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006518
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006519
Fred Drake12c6e2d1999-12-14 21:25:03 +00006520#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006521PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006522"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006523Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006524
6525static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006526posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006527{
Victor Stinner8c62be82010-05-06 00:08:46 +00006528 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006529#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006530 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006531 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006532
6533 if (GetUserNameW(user_name, &num_chars)) {
6534 /* num_chars is the number of unicode chars plus null terminator */
6535 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006536 }
6537 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006538 result = PyErr_SetFromWindowsErr(GetLastError());
6539#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006540 char *name;
6541 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006542
Victor Stinner8c62be82010-05-06 00:08:46 +00006543 errno = 0;
6544 name = getlogin();
6545 if (name == NULL) {
6546 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006547 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006548 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006549 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006550 }
6551 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006552 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006553 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006554#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006555 return result;
6556}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006557#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006558
Guido van Rossumad0ee831995-03-01 10:34:45 +00006559#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006560PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006561"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006562Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006563
Barry Warsaw53699e91996-12-10 23:23:01 +00006564static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006565posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006566{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006567 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006568}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006569#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006570
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006571
Guido van Rossumad0ee831995-03-01 10:34:45 +00006572#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006573PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006574"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006575Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006576
Barry Warsaw53699e91996-12-10 23:23:01 +00006577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006578posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006579{
Victor Stinner8c62be82010-05-06 00:08:46 +00006580 pid_t pid;
6581 int sig;
6582 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6583 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006584 if (kill(pid, sig) == -1)
6585 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006586 Py_INCREF(Py_None);
6587 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006588}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006589#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006590
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006591#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006592PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006593"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006594Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006595
6596static PyObject *
6597posix_killpg(PyObject *self, PyObject *args)
6598{
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 int sig;
6600 pid_t pgid;
6601 /* XXX some man pages make the `pgid` parameter an int, others
6602 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6603 take the same type. Moreover, pid_t is always at least as wide as
6604 int (else compilation of this module fails), which is safe. */
6605 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6606 return NULL;
6607 if (killpg(pgid, sig) == -1)
6608 return posix_error();
6609 Py_INCREF(Py_None);
6610 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006611}
6612#endif
6613
Brian Curtineb24d742010-04-12 17:16:38 +00006614#ifdef MS_WINDOWS
6615PyDoc_STRVAR(win32_kill__doc__,
6616"kill(pid, sig)\n\n\
6617Kill a process with a signal.");
6618
6619static PyObject *
6620win32_kill(PyObject *self, PyObject *args)
6621{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006622 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006623 pid_t pid;
6624 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006625 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006626
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006627 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006629
Victor Stinner8c62be82010-05-06 00:08:46 +00006630 /* Console processes which share a common console can be sent CTRL+C or
6631 CTRL+BREAK events, provided they handle said events. */
6632 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006633 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006634 err = GetLastError();
6635 PyErr_SetFromWindowsErr(err);
6636 }
6637 else
6638 Py_RETURN_NONE;
6639 }
Brian Curtineb24d742010-04-12 17:16:38 +00006640
Victor Stinner8c62be82010-05-06 00:08:46 +00006641 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6642 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006643 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 if (handle == NULL) {
6645 err = GetLastError();
6646 return PyErr_SetFromWindowsErr(err);
6647 }
Brian Curtineb24d742010-04-12 17:16:38 +00006648
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 if (TerminateProcess(handle, sig) == 0) {
6650 err = GetLastError();
6651 result = PyErr_SetFromWindowsErr(err);
6652 } else {
6653 Py_INCREF(Py_None);
6654 result = Py_None;
6655 }
Brian Curtineb24d742010-04-12 17:16:38 +00006656
Victor Stinner8c62be82010-05-06 00:08:46 +00006657 CloseHandle(handle);
6658 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006659}
6660#endif /* MS_WINDOWS */
6661
Guido van Rossumc0125471996-06-28 18:55:32 +00006662#ifdef HAVE_PLOCK
6663
6664#ifdef HAVE_SYS_LOCK_H
6665#include <sys/lock.h>
6666#endif
6667
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006668PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006669"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006670Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006671
Barry Warsaw53699e91996-12-10 23:23:01 +00006672static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006673posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006674{
Victor Stinner8c62be82010-05-06 00:08:46 +00006675 int op;
6676 if (!PyArg_ParseTuple(args, "i:plock", &op))
6677 return NULL;
6678 if (plock(op) == -1)
6679 return posix_error();
6680 Py_INCREF(Py_None);
6681 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006682}
6683#endif
6684
Guido van Rossumb6775db1994-08-01 11:34:53 +00006685#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006686PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006687"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006688Set the current process's user id.");
6689
Barry Warsaw53699e91996-12-10 23:23:01 +00006690static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006691posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006692{
Victor Stinner8c62be82010-05-06 00:08:46 +00006693 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006694 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006696 if (setuid(uid) < 0)
6697 return posix_error();
6698 Py_INCREF(Py_None);
6699 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006700}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006701#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006702
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006703
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006704#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006705PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006706"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006707Set the current process's effective user id.");
6708
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006709static PyObject *
6710posix_seteuid (PyObject *self, PyObject *args)
6711{
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006713 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 if (seteuid(euid) < 0) {
6716 return posix_error();
6717 } else {
6718 Py_INCREF(Py_None);
6719 return Py_None;
6720 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006721}
6722#endif /* HAVE_SETEUID */
6723
6724#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006725PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006726"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006727Set the current process's effective group id.");
6728
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006729static PyObject *
6730posix_setegid (PyObject *self, PyObject *args)
6731{
Victor Stinner8c62be82010-05-06 00:08:46 +00006732 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006733 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006735 if (setegid(egid) < 0) {
6736 return posix_error();
6737 } else {
6738 Py_INCREF(Py_None);
6739 return Py_None;
6740 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006741}
6742#endif /* HAVE_SETEGID */
6743
6744#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006745PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006746"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006747Set the current process's real and effective user ids.");
6748
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006749static PyObject *
6750posix_setreuid (PyObject *self, PyObject *args)
6751{
Victor Stinner8c62be82010-05-06 00:08:46 +00006752 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006753 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6754 _Py_Uid_Converter, &ruid,
6755 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006756 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006757 if (setreuid(ruid, euid) < 0) {
6758 return posix_error();
6759 } else {
6760 Py_INCREF(Py_None);
6761 return Py_None;
6762 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006763}
6764#endif /* HAVE_SETREUID */
6765
6766#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006767PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006768"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006769Set the current process's real and effective group ids.");
6770
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006771static PyObject *
6772posix_setregid (PyObject *self, PyObject *args)
6773{
Victor Stinner8c62be82010-05-06 00:08:46 +00006774 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006775 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6776 _Py_Gid_Converter, &rgid,
6777 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 if (setregid(rgid, egid) < 0) {
6780 return posix_error();
6781 } else {
6782 Py_INCREF(Py_None);
6783 return Py_None;
6784 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006785}
6786#endif /* HAVE_SETREGID */
6787
Guido van Rossumb6775db1994-08-01 11:34:53 +00006788#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006789PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006790"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006791Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006792
Barry Warsaw53699e91996-12-10 23:23:01 +00006793static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006794posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006795{
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006797 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006798 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 if (setgid(gid) < 0)
6800 return posix_error();
6801 Py_INCREF(Py_None);
6802 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006803}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006804#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006805
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006806#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006807PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006808"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006809Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006810
6811static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006812posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006813{
Victor Stinner8c62be82010-05-06 00:08:46 +00006814 int i, len;
6815 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006816
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 if (!PySequence_Check(groups)) {
6818 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6819 return NULL;
6820 }
6821 len = PySequence_Size(groups);
6822 if (len > MAX_GROUPS) {
6823 PyErr_SetString(PyExc_ValueError, "too many groups");
6824 return NULL;
6825 }
6826 for(i = 0; i < len; i++) {
6827 PyObject *elem;
6828 elem = PySequence_GetItem(groups, i);
6829 if (!elem)
6830 return NULL;
6831 if (!PyLong_Check(elem)) {
6832 PyErr_SetString(PyExc_TypeError,
6833 "groups must be integers");
6834 Py_DECREF(elem);
6835 return NULL;
6836 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006837 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 Py_DECREF(elem);
6839 return NULL;
6840 }
6841 }
6842 Py_DECREF(elem);
6843 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006844
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 if (setgroups(len, grouplist) < 0)
6846 return posix_error();
6847 Py_INCREF(Py_None);
6848 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006849}
6850#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006851
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006852#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6853static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006854wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006855{
Victor Stinner8c62be82010-05-06 00:08:46 +00006856 PyObject *result;
6857 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006858 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006859
Victor Stinner8c62be82010-05-06 00:08:46 +00006860 if (pid == -1)
6861 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006862
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 if (struct_rusage == NULL) {
6864 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6865 if (m == NULL)
6866 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006867 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 Py_DECREF(m);
6869 if (struct_rusage == NULL)
6870 return NULL;
6871 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006872
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6874 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6875 if (!result)
6876 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006877
6878#ifndef doubletime
6879#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6880#endif
6881
Victor Stinner8c62be82010-05-06 00:08:46 +00006882 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006883 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006885 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006886#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6888 SET_INT(result, 2, ru->ru_maxrss);
6889 SET_INT(result, 3, ru->ru_ixrss);
6890 SET_INT(result, 4, ru->ru_idrss);
6891 SET_INT(result, 5, ru->ru_isrss);
6892 SET_INT(result, 6, ru->ru_minflt);
6893 SET_INT(result, 7, ru->ru_majflt);
6894 SET_INT(result, 8, ru->ru_nswap);
6895 SET_INT(result, 9, ru->ru_inblock);
6896 SET_INT(result, 10, ru->ru_oublock);
6897 SET_INT(result, 11, ru->ru_msgsnd);
6898 SET_INT(result, 12, ru->ru_msgrcv);
6899 SET_INT(result, 13, ru->ru_nsignals);
6900 SET_INT(result, 14, ru->ru_nvcsw);
6901 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006902#undef SET_INT
6903
Victor Stinner8c62be82010-05-06 00:08:46 +00006904 if (PyErr_Occurred()) {
6905 Py_DECREF(result);
6906 return NULL;
6907 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006908
Victor Stinner8c62be82010-05-06 00:08:46 +00006909 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006910}
6911#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6912
6913#ifdef HAVE_WAIT3
6914PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006915"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006916Wait for completion of a child process.");
6917
6918static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006919posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006920{
Victor Stinner8c62be82010-05-06 00:08:46 +00006921 pid_t pid;
6922 int options;
6923 struct rusage ru;
6924 WAIT_TYPE status;
6925 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006926
Victor Stinner4195b5c2012-02-08 23:03:19 +01006927 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006929
Victor Stinner8c62be82010-05-06 00:08:46 +00006930 Py_BEGIN_ALLOW_THREADS
6931 pid = wait3(&status, options, &ru);
6932 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006933
Victor Stinner4195b5c2012-02-08 23:03:19 +01006934 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006935}
6936#endif /* HAVE_WAIT3 */
6937
6938#ifdef HAVE_WAIT4
6939PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006940"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006941Wait for completion of a given child process.");
6942
6943static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006944posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006945{
Victor Stinner8c62be82010-05-06 00:08:46 +00006946 pid_t pid;
6947 int options;
6948 struct rusage ru;
6949 WAIT_TYPE status;
6950 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006951
Victor Stinner4195b5c2012-02-08 23:03:19 +01006952 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006954
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 Py_BEGIN_ALLOW_THREADS
6956 pid = wait4(pid, &status, options, &ru);
6957 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006958
Victor Stinner4195b5c2012-02-08 23:03:19 +01006959 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006960}
6961#endif /* HAVE_WAIT4 */
6962
Ross Lagerwall7807c352011-03-17 20:20:30 +02006963#if defined(HAVE_WAITID) && !defined(__APPLE__)
6964PyDoc_STRVAR(posix_waitid__doc__,
6965"waitid(idtype, id, options) -> waitid_result\n\n\
6966Wait for the completion of one or more child processes.\n\n\
6967idtype can be P_PID, P_PGID or P_ALL.\n\
6968id specifies the pid to wait on.\n\
6969options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6970or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6971Returns either waitid_result or None if WNOHANG is specified and there are\n\
6972no children in a waitable state.");
6973
6974static PyObject *
6975posix_waitid(PyObject *self, PyObject *args)
6976{
6977 PyObject *result;
6978 idtype_t idtype;
6979 id_t id;
6980 int options, res;
6981 siginfo_t si;
6982 si.si_pid = 0;
6983 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6984 return NULL;
6985 Py_BEGIN_ALLOW_THREADS
6986 res = waitid(idtype, id, &si, options);
6987 Py_END_ALLOW_THREADS
6988 if (res == -1)
6989 return posix_error();
6990
6991 if (si.si_pid == 0)
6992 Py_RETURN_NONE;
6993
6994 result = PyStructSequence_New(&WaitidResultType);
6995 if (!result)
6996 return NULL;
6997
6998 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006999 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007000 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7001 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7002 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7003 if (PyErr_Occurred()) {
7004 Py_DECREF(result);
7005 return NULL;
7006 }
7007
7008 return result;
7009}
7010#endif
7011
Guido van Rossumb6775db1994-08-01 11:34:53 +00007012#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007013PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007014"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007015Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007016
Barry Warsaw53699e91996-12-10 23:23:01 +00007017static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007018posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007019{
Victor Stinner8c62be82010-05-06 00:08:46 +00007020 pid_t pid;
7021 int options;
7022 WAIT_TYPE status;
7023 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007024
Victor Stinner8c62be82010-05-06 00:08:46 +00007025 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7026 return NULL;
7027 Py_BEGIN_ALLOW_THREADS
7028 pid = waitpid(pid, &status, options);
7029 Py_END_ALLOW_THREADS
7030 if (pid == -1)
7031 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007032
Victor Stinner8c62be82010-05-06 00:08:46 +00007033 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007034}
7035
Tim Petersab034fa2002-02-01 11:27:43 +00007036#elif defined(HAVE_CWAIT)
7037
7038/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007039PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007040"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007041"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007042
7043static PyObject *
7044posix_waitpid(PyObject *self, PyObject *args)
7045{
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 Py_intptr_t pid;
7047 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007048
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007049 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007050 return NULL;
7051 Py_BEGIN_ALLOW_THREADS
7052 pid = _cwait(&status, pid, options);
7053 Py_END_ALLOW_THREADS
7054 if (pid == -1)
7055 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007056
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007058 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007059}
7060#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007061
Guido van Rossumad0ee831995-03-01 10:34:45 +00007062#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007063PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007064"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007065Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007066
Barry Warsaw53699e91996-12-10 23:23:01 +00007067static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007068posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007069{
Victor Stinner8c62be82010-05-06 00:08:46 +00007070 pid_t pid;
7071 WAIT_TYPE status;
7072 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007073
Victor Stinner8c62be82010-05-06 00:08:46 +00007074 Py_BEGIN_ALLOW_THREADS
7075 pid = wait(&status);
7076 Py_END_ALLOW_THREADS
7077 if (pid == -1)
7078 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007079
Victor Stinner8c62be82010-05-06 00:08:46 +00007080 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007081}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007082#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007083
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007084
Larry Hastings9cf065c2012-06-22 16:30:09 -07007085#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7086PyDoc_STRVAR(readlink__doc__,
7087"readlink(path, *, dir_fd=None) -> path\n\n\
7088Return a string representing the path to which the symbolic link points.\n\
7089\n\
7090If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7091 and path should be relative; path will then be relative to that directory.\n\
7092dir_fd may not be implemented on your platform.\n\
7093 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007094#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007095
Guido van Rossumb6775db1994-08-01 11:34:53 +00007096#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007097
Barry Warsaw53699e91996-12-10 23:23:01 +00007098static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007099posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007100{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007101 path_t path;
7102 int dir_fd = DEFAULT_DIR_FD;
7103 char buffer[MAXPATHLEN];
7104 ssize_t length;
7105 PyObject *return_value = NULL;
7106 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007107
Larry Hastings9cf065c2012-06-22 16:30:09 -07007108 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007109 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007110 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7111 path_converter, &path,
7112#ifdef HAVE_READLINKAT
7113 dir_fd_converter, &dir_fd
7114#else
7115 dir_fd_unavailable, &dir_fd
7116#endif
7117 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007118 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007119
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007121#ifdef HAVE_READLINKAT
7122 if (dir_fd != DEFAULT_DIR_FD)
7123 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007124 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007125#endif
7126 length = readlink(path.narrow, buffer, sizeof(buffer));
7127 Py_END_ALLOW_THREADS
7128
7129 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007130 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007131 goto exit;
7132 }
7133
7134 if (PyUnicode_Check(path.object))
7135 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7136 else
7137 return_value = PyBytes_FromStringAndSize(buffer, length);
7138exit:
7139 path_cleanup(&path);
7140 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007141}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007142
7143
Guido van Rossumb6775db1994-08-01 11:34:53 +00007144#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007145
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007146
Larry Hastings9cf065c2012-06-22 16:30:09 -07007147#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007148PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007149"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7150Create a symbolic link pointing to src named dst.\n\n\
7151target_is_directory is required on Windows if the target is to be\n\
7152 interpreted as a directory. (On Windows, symlink requires\n\
7153 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7154 target_is_directory is ignored on non-Windows platforms.\n\
7155\n\
7156If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7157 and path should be relative; path will then be relative to that directory.\n\
7158dir_fd may not be implemented on your platform.\n\
7159 If it is unavailable, using it will raise a NotImplementedError.");
7160
7161#if defined(MS_WINDOWS)
7162
7163/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7164static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7165static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007166
Larry Hastings9cf065c2012-06-22 16:30:09 -07007167static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007168check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007169{
7170 HINSTANCE hKernel32;
7171 /* only recheck */
7172 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7173 return 1;
7174 hKernel32 = GetModuleHandleW(L"KERNEL32");
7175 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7176 "CreateSymbolicLinkW");
7177 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7178 "CreateSymbolicLinkA");
7179 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7180}
7181
Victor Stinner31b3b922013-06-05 01:49:17 +02007182/* Remove the last portion of the path */
7183static void
7184_dirnameW(WCHAR *path)
7185{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007186 WCHAR *ptr;
7187
7188 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007189 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007190 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007191 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007192 }
7193 *ptr = 0;
7194}
7195
Victor Stinner31b3b922013-06-05 01:49:17 +02007196/* Remove the last portion of the path */
7197static void
7198_dirnameA(char *path)
7199{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007200 char *ptr;
7201
7202 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007203 for(ptr = path + strlen(path); ptr != path; ptr--) {
7204 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007205 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007206 }
7207 *ptr = 0;
7208}
7209
Victor Stinner31b3b922013-06-05 01:49:17 +02007210/* Is this path absolute? */
7211static int
7212_is_absW(const WCHAR *path)
7213{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007214 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7215
7216}
7217
Victor Stinner31b3b922013-06-05 01:49:17 +02007218/* Is this path absolute? */
7219static int
7220_is_absA(const char *path)
7221{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007222 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7223
7224}
7225
Victor Stinner31b3b922013-06-05 01:49:17 +02007226/* join root and rest with a backslash */
7227static void
7228_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7229{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007230 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007231
Victor Stinner31b3b922013-06-05 01:49:17 +02007232 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007233 wcscpy(dest_path, rest);
7234 return;
7235 }
7236
7237 root_len = wcslen(root);
7238
7239 wcscpy(dest_path, root);
7240 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007241 dest_path[root_len] = L'\\';
7242 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007243 }
7244 wcscpy(dest_path+root_len, rest);
7245}
7246
Victor Stinner31b3b922013-06-05 01:49:17 +02007247/* join root and rest with a backslash */
7248static void
7249_joinA(char *dest_path, const char *root, const char *rest)
7250{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007251 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007252
Victor Stinner31b3b922013-06-05 01:49:17 +02007253 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007254 strcpy(dest_path, rest);
7255 return;
7256 }
7257
7258 root_len = strlen(root);
7259
7260 strcpy(dest_path, root);
7261 if(root_len) {
7262 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007263 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007264 }
7265 strcpy(dest_path+root_len, rest);
7266}
7267
Victor Stinner31b3b922013-06-05 01:49:17 +02007268/* Return True if the path at src relative to dest is a directory */
7269static int
7270_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007271{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007272 WIN32_FILE_ATTRIBUTE_DATA src_info;
7273 WCHAR dest_parent[MAX_PATH];
7274 WCHAR src_resolved[MAX_PATH] = L"";
7275
7276 /* dest_parent = os.path.dirname(dest) */
7277 wcscpy(dest_parent, dest);
7278 _dirnameW(dest_parent);
7279 /* src_resolved = os.path.join(dest_parent, src) */
7280 _joinW(src_resolved, dest_parent, src);
7281 return (
7282 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7283 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7284 );
7285}
7286
Victor Stinner31b3b922013-06-05 01:49:17 +02007287/* Return True if the path at src relative to dest is a directory */
7288static int
7289_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007290{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007291 WIN32_FILE_ATTRIBUTE_DATA src_info;
7292 char dest_parent[MAX_PATH];
7293 char src_resolved[MAX_PATH] = "";
7294
7295 /* dest_parent = os.path.dirname(dest) */
7296 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007297 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007298 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007299 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007300 return (
7301 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7302 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7303 );
7304}
7305
Larry Hastings9cf065c2012-06-22 16:30:09 -07007306#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007307
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007308static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007309posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007310{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007311 path_t src;
7312 path_t dst;
7313 int dir_fd = DEFAULT_DIR_FD;
7314 int target_is_directory = 0;
7315 static char *keywords[] = {"src", "dst", "target_is_directory",
7316 "dir_fd", NULL};
7317 PyObject *return_value;
7318#ifdef MS_WINDOWS
7319 DWORD result;
7320#else
7321 int result;
7322#endif
7323
7324 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007325 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007326 src.argument_name = "src";
7327 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007328 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007329 dst.argument_name = "dst";
7330
7331#ifdef MS_WINDOWS
7332 if (!check_CreateSymbolicLink()) {
7333 PyErr_SetString(PyExc_NotImplementedError,
7334 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007335 return NULL;
7336 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007337 if (!win32_can_symlink) {
7338 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007339 return NULL;
7340 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007341#endif
7342
7343 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7344 keywords,
7345 path_converter, &src,
7346 path_converter, &dst,
7347 &target_is_directory,
7348#ifdef HAVE_SYMLINKAT
7349 dir_fd_converter, &dir_fd
7350#else
7351 dir_fd_unavailable, &dir_fd
7352#endif
7353 ))
7354 return NULL;
7355
7356 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7357 PyErr_SetString(PyExc_ValueError,
7358 "symlink: src and dst must be the same type");
7359 return_value = NULL;
7360 goto exit;
7361 }
7362
7363#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007364
Larry Hastings9cf065c2012-06-22 16:30:09 -07007365 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007366 if (dst.wide) {
7367 /* if src is a directory, ensure target_is_directory==1 */
7368 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007369 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7370 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007371 }
7372 else {
7373 /* if src is a directory, ensure target_is_directory==1 */
7374 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007375 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7376 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007377 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007378 Py_END_ALLOW_THREADS
7379
7380 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08007381 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007382 goto exit;
7383 }
7384
7385#else
7386
7387 Py_BEGIN_ALLOW_THREADS
7388#if HAVE_SYMLINKAT
7389 if (dir_fd != DEFAULT_DIR_FD)
7390 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7391 else
7392#endif
7393 result = symlink(src.narrow, dst.narrow);
7394 Py_END_ALLOW_THREADS
7395
7396 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08007397 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007398 goto exit;
7399 }
7400#endif
7401
7402 return_value = Py_None;
7403 Py_INCREF(Py_None);
7404 goto exit; /* silence "unused label" warning */
7405exit:
7406 path_cleanup(&src);
7407 path_cleanup(&dst);
7408 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007409}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007410
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007411#endif /* HAVE_SYMLINK */
7412
Larry Hastings9cf065c2012-06-22 16:30:09 -07007413
Brian Curtind40e6f72010-07-08 21:39:08 +00007414#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7415
Brian Curtind40e6f72010-07-08 21:39:08 +00007416static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007417win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007418{
7419 wchar_t *path;
7420 DWORD n_bytes_returned;
7421 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007422 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007423 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007424 HANDLE reparse_point_handle;
7425
7426 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7427 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7428 wchar_t *print_name;
7429
Larry Hastings9cf065c2012-06-22 16:30:09 -07007430 static char *keywords[] = {"path", "dir_fd", NULL};
7431
7432 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7433 &po,
7434 dir_fd_unavailable, &dir_fd
7435 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007436 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007437
Victor Stinnereb5657a2011-09-30 01:44:27 +02007438 path = PyUnicode_AsUnicode(po);
7439 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007440 return NULL;
7441
7442 /* First get a handle to the reparse point */
7443 Py_BEGIN_ALLOW_THREADS
7444 reparse_point_handle = CreateFileW(
7445 path,
7446 0,
7447 0,
7448 0,
7449 OPEN_EXISTING,
7450 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7451 0);
7452 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007453
Brian Curtind40e6f72010-07-08 21:39:08 +00007454 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007455 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007456
Brian Curtind40e6f72010-07-08 21:39:08 +00007457 Py_BEGIN_ALLOW_THREADS
7458 /* New call DeviceIoControl to read the reparse point */
7459 io_result = DeviceIoControl(
7460 reparse_point_handle,
7461 FSCTL_GET_REPARSE_POINT,
7462 0, 0, /* in buffer */
7463 target_buffer, sizeof(target_buffer),
7464 &n_bytes_returned,
7465 0 /* we're not using OVERLAPPED_IO */
7466 );
7467 CloseHandle(reparse_point_handle);
7468 Py_END_ALLOW_THREADS
7469
7470 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007471 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007472
7473 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7474 {
7475 PyErr_SetString(PyExc_ValueError,
7476 "not a symbolic link");
7477 return NULL;
7478 }
Brian Curtin74e45612010-07-09 15:58:59 +00007479 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7480 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7481
7482 result = PyUnicode_FromWideChar(print_name,
7483 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007484 return result;
7485}
7486
7487#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7488
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007489
Larry Hastings605a62d2012-06-24 04:33:36 -07007490static PyStructSequence_Field times_result_fields[] = {
7491 {"user", "user time"},
7492 {"system", "system time"},
7493 {"children_user", "user time of children"},
7494 {"children_system", "system time of children"},
7495 {"elapsed", "elapsed time since an arbitrary point in the past"},
7496 {NULL}
7497};
7498
7499PyDoc_STRVAR(times_result__doc__,
7500"times_result: Result from os.times().\n\n\
7501This object may be accessed either as a tuple of\n\
7502 (user, system, children_user, children_system, elapsed),\n\
7503or via the attributes user, system, children_user, children_system,\n\
7504and elapsed.\n\
7505\n\
7506See os.times for more information.");
7507
7508static PyStructSequence_Desc times_result_desc = {
7509 "times_result", /* name */
7510 times_result__doc__, /* doc */
7511 times_result_fields,
7512 5
7513};
7514
7515static PyTypeObject TimesResultType;
7516
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007517#ifdef MS_WINDOWS
7518#define HAVE_TIMES /* mandatory, for the method table */
7519#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007520
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007521#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007522
7523static PyObject *
7524build_times_result(double user, double system,
7525 double children_user, double children_system,
7526 double elapsed)
7527{
7528 PyObject *value = PyStructSequence_New(&TimesResultType);
7529 if (value == NULL)
7530 return NULL;
7531
7532#define SET(i, field) \
7533 { \
7534 PyObject *o = PyFloat_FromDouble(field); \
7535 if (!o) { \
7536 Py_DECREF(value); \
7537 return NULL; \
7538 } \
7539 PyStructSequence_SET_ITEM(value, i, o); \
7540 } \
7541
7542 SET(0, user);
7543 SET(1, system);
7544 SET(2, children_user);
7545 SET(3, children_system);
7546 SET(4, elapsed);
7547
7548#undef SET
7549
7550 return value;
7551}
7552
7553PyDoc_STRVAR(posix_times__doc__,
7554"times() -> times_result\n\n\
7555Return an object containing floating point numbers indicating process\n\
7556times. The object behaves like a named tuple with these fields:\n\
7557 (utime, stime, cutime, cstime, elapsed_time)");
7558
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007559#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007560static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007561posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007562{
Victor Stinner8c62be82010-05-06 00:08:46 +00007563 FILETIME create, exit, kernel, user;
7564 HANDLE hProc;
7565 hProc = GetCurrentProcess();
7566 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7567 /* The fields of a FILETIME structure are the hi and lo part
7568 of a 64-bit value expressed in 100 nanosecond units.
7569 1e7 is one second in such units; 1e-7 the inverse.
7570 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7571 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007572 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007573 (double)(user.dwHighDateTime*429.4967296 +
7574 user.dwLowDateTime*1e-7),
7575 (double)(kernel.dwHighDateTime*429.4967296 +
7576 kernel.dwLowDateTime*1e-7),
7577 (double)0,
7578 (double)0,
7579 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007580}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007581#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007582#define NEED_TICKS_PER_SECOND
7583static long ticks_per_second = -1;
7584static PyObject *
7585posix_times(PyObject *self, PyObject *noargs)
7586{
7587 struct tms t;
7588 clock_t c;
7589 errno = 0;
7590 c = times(&t);
7591 if (c == (clock_t) -1)
7592 return posix_error();
7593 return build_times_result(
7594 (double)t.tms_utime / ticks_per_second,
7595 (double)t.tms_stime / ticks_per_second,
7596 (double)t.tms_cutime / ticks_per_second,
7597 (double)t.tms_cstime / ticks_per_second,
7598 (double)c / ticks_per_second);
7599}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007600#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007601
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007602#endif /* HAVE_TIMES */
7603
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007604
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007605#ifdef HAVE_GETSID
7606PyDoc_STRVAR(posix_getsid__doc__,
7607"getsid(pid) -> sid\n\n\
7608Call the system call getsid().");
7609
7610static PyObject *
7611posix_getsid(PyObject *self, PyObject *args)
7612{
Victor Stinner8c62be82010-05-06 00:08:46 +00007613 pid_t pid;
7614 int sid;
7615 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7616 return NULL;
7617 sid = getsid(pid);
7618 if (sid < 0)
7619 return posix_error();
7620 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007621}
7622#endif /* HAVE_GETSID */
7623
7624
Guido van Rossumb6775db1994-08-01 11:34:53 +00007625#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007626PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007627"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007628Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007629
Barry Warsaw53699e91996-12-10 23:23:01 +00007630static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007631posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007632{
Victor Stinner8c62be82010-05-06 00:08:46 +00007633 if (setsid() < 0)
7634 return posix_error();
7635 Py_INCREF(Py_None);
7636 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007637}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007638#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007639
Guido van Rossumb6775db1994-08-01 11:34:53 +00007640#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007641PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007642"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007643Call the system call setpgid().");
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_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007647{
Victor Stinner8c62be82010-05-06 00:08:46 +00007648 pid_t pid;
7649 int pgrp;
7650 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7651 return NULL;
7652 if (setpgid(pid, pgrp) < 0)
7653 return posix_error();
7654 Py_INCREF(Py_None);
7655 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007656}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007657#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007658
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007659
Guido van Rossumb6775db1994-08-01 11:34:53 +00007660#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007661PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007662"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007663Return 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_tcgetpgrp(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:tcgetpgrp", &fd))
7671 return NULL;
7672 pgid = tcgetpgrp(fd);
7673 if (pgid < 0)
7674 return posix_error();
7675 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007676}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007677#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007678
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007679
Guido van Rossumb6775db1994-08-01 11:34:53 +00007680#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007681PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007682"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007683Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007684
Barry Warsaw53699e91996-12-10 23:23:01 +00007685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007686posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007687{
Victor Stinner8c62be82010-05-06 00:08:46 +00007688 int fd;
7689 pid_t pgid;
7690 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7691 return NULL;
7692 if (tcsetpgrp(fd, pgid) < 0)
7693 return posix_error();
7694 Py_INCREF(Py_None);
7695 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007696}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007697#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007698
Guido van Rossum687dd131993-05-17 08:34:16 +00007699/* Functions acting on file descriptors */
7700
Victor Stinnerdaf45552013-08-28 00:53:59 +02007701#ifdef O_CLOEXEC
7702extern int _Py_open_cloexec_works;
7703#endif
7704
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007705PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007706"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7707Open a file for low level IO. Returns a file handle (integer).\n\
7708\n\
7709If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7710 and path should be relative; path will then be relative to that directory.\n\
7711dir_fd may not be implemented on your platform.\n\
7712 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007713
Barry Warsaw53699e91996-12-10 23:23:01 +00007714static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007715posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007716{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007717 path_t path;
7718 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007720 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007721 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007722 PyObject *return_value = NULL;
7723 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Victor Stinnerdaf45552013-08-28 00:53:59 +02007724#ifdef O_CLOEXEC
7725 int *atomic_flag_works = &_Py_open_cloexec_works;
7726#elif !defined(MS_WINDOWS)
7727 int *atomic_flag_works = NULL;
7728#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007729
Larry Hastings9cf065c2012-06-22 16:30:09 -07007730 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007731 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007732 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7733 path_converter, &path,
7734 &flags, &mode,
7735#ifdef HAVE_OPENAT
7736 dir_fd_converter, &dir_fd
7737#else
7738 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007739#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007740 ))
7741 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007742
Victor Stinnerdaf45552013-08-28 00:53:59 +02007743#ifdef MS_WINDOWS
7744 flags |= O_NOINHERIT;
7745#elif defined(O_CLOEXEC)
7746 flags |= O_CLOEXEC;
7747#endif
7748
Victor Stinner8c62be82010-05-06 00:08:46 +00007749 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007750#ifdef MS_WINDOWS
7751 if (path.wide)
7752 fd = _wopen(path.wide, flags, mode);
7753 else
7754#endif
7755#ifdef HAVE_OPENAT
7756 if (dir_fd != DEFAULT_DIR_FD)
7757 fd = openat(dir_fd, path.narrow, flags, mode);
7758 else
7759#endif
7760 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007761 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007762
Larry Hastings9cf065c2012-06-22 16:30:09 -07007763 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007764 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007765 goto exit;
7766 }
7767
Victor Stinnerdaf45552013-08-28 00:53:59 +02007768#ifndef MS_WINDOWS
7769 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7770 close(fd);
7771 goto exit;
7772 }
7773#endif
7774
Larry Hastings9cf065c2012-06-22 16:30:09 -07007775 return_value = PyLong_FromLong((long)fd);
7776
7777exit:
7778 path_cleanup(&path);
7779 return return_value;
7780}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007781
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007782PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007783"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007784Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007785
Benjamin Peterson932bba32014-02-11 10:16:16 -05007786/*
7787The underscore at end of function name avoids a name clash with the libc
7788function posix_close.
7789*/
Barry Warsaw53699e91996-12-10 23:23:01 +00007790static PyObject *
Benjamin Peterson932bba32014-02-11 10:16:16 -05007791posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007792{
Victor Stinner8c62be82010-05-06 00:08:46 +00007793 int fd, res;
7794 if (!PyArg_ParseTuple(args, "i:close", &fd))
7795 return NULL;
7796 if (!_PyVerify_fd(fd))
7797 return posix_error();
7798 Py_BEGIN_ALLOW_THREADS
7799 res = close(fd);
7800 Py_END_ALLOW_THREADS
7801 if (res < 0)
7802 return posix_error();
7803 Py_INCREF(Py_None);
7804 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007805}
7806
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007807
Victor Stinner8c62be82010-05-06 00:08:46 +00007808PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007809"closerange(fd_low, fd_high)\n\n\
7810Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7811
7812static PyObject *
7813posix_closerange(PyObject *self, PyObject *args)
7814{
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 int fd_from, fd_to, i;
7816 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7817 return NULL;
7818 Py_BEGIN_ALLOW_THREADS
7819 for (i = fd_from; i < fd_to; i++)
7820 if (_PyVerify_fd(i))
7821 close(i);
7822 Py_END_ALLOW_THREADS
7823 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007824}
7825
7826
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007827PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007828"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007829Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007830
Barry Warsaw53699e91996-12-10 23:23:01 +00007831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007832posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007833{
Victor Stinner8c62be82010-05-06 00:08:46 +00007834 int fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007835
Victor Stinner8c62be82010-05-06 00:08:46 +00007836 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7837 return NULL;
Tim Golden23005082013-10-25 11:22:37 +01007838
Victor Stinnerdaf45552013-08-28 00:53:59 +02007839 fd = _Py_dup(fd);
7840 if (fd == -1)
7841 return NULL;
7842
Victor Stinner8c62be82010-05-06 00:08:46 +00007843 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007844}
7845
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007846
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007847PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007848"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007849Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007850
Barry Warsaw53699e91996-12-10 23:23:01 +00007851static PyObject *
Victor Stinnerdaf45552013-08-28 00:53:59 +02007852posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007853{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007854 static char *keywords[] = {"fd", "fd2", "inheritable", NULL};
7855 int fd, fd2;
7856 int inheritable = 1;
7857 int res;
7858#if defined(HAVE_DUP3) && \
7859 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7860 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7861 int dup3_works = -1;
7862#endif
7863
7864 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords,
7865 &fd, &fd2, &inheritable))
Victor Stinner8c62be82010-05-06 00:08:46 +00007866 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007867
Victor Stinner8c62be82010-05-06 00:08:46 +00007868 if (!_PyVerify_fd_dup2(fd, fd2))
7869 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007870
7871#ifdef MS_WINDOWS
7872 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007874 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007875 if (res < 0)
7876 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007877
7878 /* Character files like console cannot be make non-inheritable */
7879 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7880 close(fd2);
7881 return NULL;
7882 }
7883
7884#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7885 Py_BEGIN_ALLOW_THREADS
7886 if (!inheritable)
7887 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7888 else
7889 res = dup2(fd, fd2);
7890 Py_END_ALLOW_THREADS
7891 if (res < 0)
7892 return posix_error();
7893
7894#else
7895
7896#ifdef HAVE_DUP3
7897 if (!inheritable && dup3_works != 0) {
7898 Py_BEGIN_ALLOW_THREADS
7899 res = dup3(fd, fd2, O_CLOEXEC);
7900 Py_END_ALLOW_THREADS
7901 if (res < 0) {
7902 if (dup3_works == -1)
7903 dup3_works = (errno != ENOSYS);
7904 if (dup3_works)
7905 return posix_error();
7906 }
7907 }
7908
7909 if (inheritable || dup3_works == 0)
7910 {
7911#endif
7912 Py_BEGIN_ALLOW_THREADS
7913 res = dup2(fd, fd2);
7914 Py_END_ALLOW_THREADS
7915 if (res < 0)
7916 return posix_error();
7917
7918 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7919 close(fd2);
7920 return NULL;
7921 }
7922#ifdef HAVE_DUP3
7923 }
7924#endif
7925
7926#endif
7927
Victor Stinner8c62be82010-05-06 00:08:46 +00007928 Py_INCREF(Py_None);
7929 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007930}
7931
Ross Lagerwall7807c352011-03-17 20:20:30 +02007932#ifdef HAVE_LOCKF
7933PyDoc_STRVAR(posix_lockf__doc__,
7934"lockf(fd, cmd, len)\n\n\
7935Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7936fd is an open file descriptor.\n\
7937cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7938F_TEST.\n\
7939len specifies the section of the file to lock.");
7940
7941static PyObject *
7942posix_lockf(PyObject *self, PyObject *args)
7943{
7944 int fd, cmd, res;
7945 off_t len;
7946 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7947 &fd, &cmd, _parse_off_t, &len))
7948 return NULL;
7949
7950 Py_BEGIN_ALLOW_THREADS
7951 res = lockf(fd, cmd, len);
7952 Py_END_ALLOW_THREADS
7953
7954 if (res < 0)
7955 return posix_error();
7956
7957 Py_RETURN_NONE;
7958}
7959#endif
7960
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007961
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007962PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007963"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007964Set the current position of a file descriptor.\n\
7965Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007966
Barry Warsaw53699e91996-12-10 23:23:01 +00007967static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007968posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007969{
Victor Stinner8c62be82010-05-06 00:08:46 +00007970 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007971#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007973#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007974 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007975#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007976 PyObject *posobj;
7977 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007979#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007980 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7981 switch (how) {
7982 case 0: how = SEEK_SET; break;
7983 case 1: how = SEEK_CUR; break;
7984 case 2: how = SEEK_END; break;
7985 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007986#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007987
Ross Lagerwall8e749672011-03-17 21:54:07 +02007988#if !defined(HAVE_LARGEFILE_SUPPORT)
7989 pos = PyLong_AsLong(posobj);
7990#else
7991 pos = PyLong_AsLongLong(posobj);
7992#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 if (PyErr_Occurred())
7994 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007995
Victor Stinner8c62be82010-05-06 00:08:46 +00007996 if (!_PyVerify_fd(fd))
7997 return posix_error();
7998 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02007999#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008000 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00008001#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00008003#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008004 Py_END_ALLOW_THREADS
8005 if (res < 0)
8006 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008007
8008#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008009 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008010#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008011 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008012#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008013}
8014
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008015
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008016PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008017"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008018Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008019
Barry Warsaw53699e91996-12-10 23:23:01 +00008020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008021posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008022{
Victor Stinner8c62be82010-05-06 00:08:46 +00008023 int fd, size;
8024 Py_ssize_t n;
8025 PyObject *buffer;
8026 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
8027 return NULL;
8028 if (size < 0) {
8029 errno = EINVAL;
8030 return posix_error();
8031 }
8032 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8033 if (buffer == NULL)
8034 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00008035 if (!_PyVerify_fd(fd)) {
8036 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00008037 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00008038 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008039 Py_BEGIN_ALLOW_THREADS
8040 n = read(fd, PyBytes_AS_STRING(buffer), size);
8041 Py_END_ALLOW_THREADS
8042 if (n < 0) {
8043 Py_DECREF(buffer);
8044 return posix_error();
8045 }
8046 if (n != size)
8047 _PyBytes_Resize(&buffer, n);
8048 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008049}
8050
Ross Lagerwall7807c352011-03-17 20:20:30 +02008051#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8052 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008053static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008054iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8055{
8056 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008057 Py_ssize_t blen, total = 0;
8058
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008059 *iov = PyMem_New(struct iovec, cnt);
8060 if (*iov == NULL) {
8061 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008062 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008063 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008064
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008065 *buf = PyMem_New(Py_buffer, cnt);
8066 if (*buf == NULL) {
8067 PyMem_Del(*iov);
8068 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008069 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008070 }
8071
8072 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008073 PyObject *item = PySequence_GetItem(seq, i);
8074 if (item == NULL)
8075 goto fail;
8076 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8077 Py_DECREF(item);
8078 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008079 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008080 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008081 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008082 blen = (*buf)[i].len;
8083 (*iov)[i].iov_len = blen;
8084 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008085 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008086 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008087
8088fail:
8089 PyMem_Del(*iov);
8090 for (j = 0; j < i; j++) {
8091 PyBuffer_Release(&(*buf)[j]);
8092 }
8093 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008094 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008095}
8096
8097static void
8098iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8099{
8100 int i;
8101 PyMem_Del(iov);
8102 for (i = 0; i < cnt; i++) {
8103 PyBuffer_Release(&buf[i]);
8104 }
8105 PyMem_Del(buf);
8106}
8107#endif
8108
Ross Lagerwall7807c352011-03-17 20:20:30 +02008109#ifdef HAVE_READV
8110PyDoc_STRVAR(posix_readv__doc__,
8111"readv(fd, buffers) -> bytesread\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008112Read from a file descriptor fd into a number of mutable, bytes-like\n\
8113objects (\"buffers\"). readv will transfer data into each buffer\n\
8114until it is full and then move on to the next buffer in the sequence\n\
8115to hold the rest of the data.\n\n\
8116readv returns the total number of bytes read (which may be less than\n\
8117the total capacity of all the buffers.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008118
8119static PyObject *
8120posix_readv(PyObject *self, PyObject *args)
8121{
8122 int fd, cnt;
8123 Py_ssize_t n;
8124 PyObject *seq;
8125 struct iovec *iov;
8126 Py_buffer *buf;
8127
8128 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8129 return NULL;
8130 if (!PySequence_Check(seq)) {
8131 PyErr_SetString(PyExc_TypeError,
8132 "readv() arg 2 must be a sequence");
8133 return NULL;
8134 }
8135 cnt = PySequence_Size(seq);
8136
Victor Stinner57ddf782014-01-08 15:21:28 +01008137 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE) < 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008138 return NULL;
8139
8140 Py_BEGIN_ALLOW_THREADS
8141 n = readv(fd, iov, cnt);
8142 Py_END_ALLOW_THREADS
8143
8144 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008145 if (n < 0)
8146 return posix_error();
8147
Ross Lagerwall7807c352011-03-17 20:20:30 +02008148 return PyLong_FromSsize_t(n);
8149}
8150#endif
8151
8152#ifdef HAVE_PREAD
8153PyDoc_STRVAR(posix_pread__doc__,
8154"pread(fd, buffersize, offset) -> string\n\n\
8155Read from a file descriptor, fd, at a position of offset. It will read up\n\
8156to buffersize number of bytes. The file offset remains unchanged.");
8157
8158static PyObject *
8159posix_pread(PyObject *self, PyObject *args)
8160{
8161 int fd, size;
8162 off_t offset;
8163 Py_ssize_t n;
8164 PyObject *buffer;
8165 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8166 return NULL;
8167
8168 if (size < 0) {
8169 errno = EINVAL;
8170 return posix_error();
8171 }
8172 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8173 if (buffer == NULL)
8174 return NULL;
8175 if (!_PyVerify_fd(fd)) {
8176 Py_DECREF(buffer);
8177 return posix_error();
8178 }
8179 Py_BEGIN_ALLOW_THREADS
8180 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8181 Py_END_ALLOW_THREADS
8182 if (n < 0) {
8183 Py_DECREF(buffer);
8184 return posix_error();
8185 }
8186 if (n != size)
8187 _PyBytes_Resize(&buffer, n);
8188 return buffer;
8189}
8190#endif
8191
8192PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008193"write(fd, data) -> byteswritten\n\n\
8194Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008195
8196static PyObject *
8197posix_write(PyObject *self, PyObject *args)
8198{
8199 Py_buffer pbuf;
8200 int fd;
8201 Py_ssize_t size, len;
8202
8203 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8204 return NULL;
8205 if (!_PyVerify_fd(fd)) {
8206 PyBuffer_Release(&pbuf);
8207 return posix_error();
8208 }
8209 len = pbuf.len;
8210 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008211#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008212 if (len > INT_MAX)
8213 len = INT_MAX;
8214 size = write(fd, pbuf.buf, (int)len);
8215#else
8216 size = write(fd, pbuf.buf, len);
8217#endif
8218 Py_END_ALLOW_THREADS
8219 PyBuffer_Release(&pbuf);
8220 if (size < 0)
8221 return posix_error();
8222 return PyLong_FromSsize_t(size);
8223}
8224
8225#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008226PyDoc_STRVAR(posix_sendfile__doc__,
8227"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8228sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8229 -> byteswritten\n\
8230Copy nbytes bytes from file descriptor in to file descriptor out.");
8231
8232static PyObject *
8233posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8234{
8235 int in, out;
8236 Py_ssize_t ret;
8237 off_t offset;
8238
8239#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8240#ifndef __APPLE__
8241 Py_ssize_t len;
8242#endif
8243 PyObject *headers = NULL, *trailers = NULL;
8244 Py_buffer *hbuf, *tbuf;
8245 off_t sbytes;
8246 struct sf_hdtr sf;
8247 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008248 static char *keywords[] = {"out", "in",
8249 "offset", "count",
8250 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008251
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008252 sf.headers = NULL;
8253 sf.trailers = NULL;
8254
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008255#ifdef __APPLE__
8256 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008257 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008258#else
8259 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008260 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008261#endif
8262 &headers, &trailers, &flags))
8263 return NULL;
8264 if (headers != NULL) {
8265 if (!PySequence_Check(headers)) {
8266 PyErr_SetString(PyExc_TypeError,
8267 "sendfile() headers must be a sequence or None");
8268 return NULL;
8269 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008270 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008271 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008272 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008273 (i = iov_setup(&(sf.headers), &hbuf,
8274 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008275 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008276#ifdef __APPLE__
8277 sbytes += i;
8278#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008279 }
8280 }
8281 if (trailers != NULL) {
8282 if (!PySequence_Check(trailers)) {
8283 PyErr_SetString(PyExc_TypeError,
8284 "sendfile() trailers must be a sequence or None");
8285 return NULL;
8286 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008287 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008288 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008289 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008290 (i = iov_setup(&(sf.trailers), &tbuf,
8291 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008292 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008293#ifdef __APPLE__
8294 sbytes += i;
8295#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008296 }
8297 }
8298
8299 Py_BEGIN_ALLOW_THREADS
8300#ifdef __APPLE__
8301 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8302#else
8303 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8304#endif
8305 Py_END_ALLOW_THREADS
8306
8307 if (sf.headers != NULL)
8308 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8309 if (sf.trailers != NULL)
8310 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8311
8312 if (ret < 0) {
8313 if ((errno == EAGAIN) || (errno == EBUSY)) {
8314 if (sbytes != 0) {
8315 // some data has been sent
8316 goto done;
8317 }
8318 else {
8319 // no data has been sent; upper application is supposed
8320 // to retry on EAGAIN or EBUSY
8321 return posix_error();
8322 }
8323 }
8324 return posix_error();
8325 }
8326 goto done;
8327
8328done:
8329 #if !defined(HAVE_LARGEFILE_SUPPORT)
8330 return Py_BuildValue("l", sbytes);
8331 #else
8332 return Py_BuildValue("L", sbytes);
8333 #endif
8334
8335#else
8336 Py_ssize_t count;
8337 PyObject *offobj;
8338 static char *keywords[] = {"out", "in",
8339 "offset", "count", NULL};
8340 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8341 keywords, &out, &in, &offobj, &count))
8342 return NULL;
8343#ifdef linux
8344 if (offobj == Py_None) {
8345 Py_BEGIN_ALLOW_THREADS
8346 ret = sendfile(out, in, NULL, count);
8347 Py_END_ALLOW_THREADS
8348 if (ret < 0)
8349 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008350 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008351 }
8352#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008353 if (!_parse_off_t(offobj, &offset))
8354 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008355 Py_BEGIN_ALLOW_THREADS
8356 ret = sendfile(out, in, &offset, count);
8357 Py_END_ALLOW_THREADS
8358 if (ret < 0)
8359 return posix_error();
8360 return Py_BuildValue("n", ret);
8361#endif
8362}
8363#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008364
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008365PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008366"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008367Like stat(), but for an open file descriptor.\n\
8368Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008369
Barry Warsaw53699e91996-12-10 23:23:01 +00008370static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008371posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008372{
Victor Stinner8c62be82010-05-06 00:08:46 +00008373 int fd;
8374 STRUCT_STAT st;
8375 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008376 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008377 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 Py_BEGIN_ALLOW_THREADS
8379 res = FSTAT(fd, &st);
8380 Py_END_ALLOW_THREADS
8381 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008382#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008383 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008384#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008385 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008386#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008387 }
Tim Peters5aa91602002-01-30 05:46:57 +00008388
Victor Stinner4195b5c2012-02-08 23:03:19 +01008389 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008390}
8391
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008392PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008393"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008394Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008395connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008396
8397static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008398posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008399{
Victor Stinner8c62be82010-05-06 00:08:46 +00008400 int fd;
8401 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8402 return NULL;
8403 if (!_PyVerify_fd(fd))
8404 return PyBool_FromLong(0);
8405 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008406}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008407
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008408#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008409PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008410"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008411Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008412
Barry Warsaw53699e91996-12-10 23:23:01 +00008413static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008414posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008415{
Victor Stinner8c62be82010-05-06 00:08:46 +00008416 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008417#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008419 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008420 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008421#else
8422 int res;
8423#endif
8424
8425#ifdef MS_WINDOWS
8426 attr.nLength = sizeof(attr);
8427 attr.lpSecurityDescriptor = NULL;
8428 attr.bInheritHandle = FALSE;
8429
8430 Py_BEGIN_ALLOW_THREADS
8431 ok = CreatePipe(&read, &write, &attr, 0);
8432 if (ok) {
8433 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8434 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8435 if (fds[0] == -1 || fds[1] == -1) {
8436 CloseHandle(read);
8437 CloseHandle(write);
8438 ok = 0;
8439 }
8440 }
8441 Py_END_ALLOW_THREADS
8442
Victor Stinner8c62be82010-05-06 00:08:46 +00008443 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008444 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008445#else
8446
8447#ifdef HAVE_PIPE2
8448 Py_BEGIN_ALLOW_THREADS
8449 res = pipe2(fds, O_CLOEXEC);
8450 Py_END_ALLOW_THREADS
8451
8452 if (res != 0 && errno == ENOSYS)
8453 {
8454#endif
8455 Py_BEGIN_ALLOW_THREADS
8456 res = pipe(fds);
8457 Py_END_ALLOW_THREADS
8458
8459 if (res == 0) {
8460 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8461 close(fds[0]);
8462 close(fds[1]);
8463 return NULL;
8464 }
8465 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8466 close(fds[0]);
8467 close(fds[1]);
8468 return NULL;
8469 }
8470 }
8471#ifdef HAVE_PIPE2
8472 }
8473#endif
8474
8475 if (res != 0)
8476 return PyErr_SetFromErrno(PyExc_OSError);
8477#endif /* !MS_WINDOWS */
8478 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008479}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008480#endif /* HAVE_PIPE */
8481
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008482#ifdef HAVE_PIPE2
8483PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008484"pipe2(flags) -> (read_end, write_end)\n\n\
8485Create a pipe with flags set atomically.\n\
8486flags can be constructed by ORing together one or more of these values:\n\
8487O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008488");
8489
8490static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008491posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008492{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008493 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008494 int fds[2];
8495 int res;
8496
Serhiy Storchaka78980432013-01-15 01:12:17 +02008497 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008498 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008499 return NULL;
8500
8501 res = pipe2(fds, flags);
8502 if (res != 0)
8503 return posix_error();
8504 return Py_BuildValue("(ii)", fds[0], fds[1]);
8505}
8506#endif /* HAVE_PIPE2 */
8507
Ross Lagerwall7807c352011-03-17 20:20:30 +02008508#ifdef HAVE_WRITEV
8509PyDoc_STRVAR(posix_writev__doc__,
8510"writev(fd, buffers) -> byteswritten\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008511Write the contents of *buffers* to file descriptor *fd*. *buffers*\n\
8512must be a sequence of bytes-like objects.\n\n\
8513writev writes the contents of each object to the file descriptor\n\
8514and returns the total number of bytes written.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008515
8516static PyObject *
8517posix_writev(PyObject *self, PyObject *args)
8518{
8519 int fd, cnt;
8520 Py_ssize_t res;
8521 PyObject *seq;
8522 struct iovec *iov;
8523 Py_buffer *buf;
8524 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8525 return NULL;
8526 if (!PySequence_Check(seq)) {
8527 PyErr_SetString(PyExc_TypeError,
8528 "writev() arg 2 must be a sequence");
8529 return NULL;
8530 }
8531 cnt = PySequence_Size(seq);
8532
Victor Stinner57ddf782014-01-08 15:21:28 +01008533 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008534 return NULL;
8535 }
8536
8537 Py_BEGIN_ALLOW_THREADS
8538 res = writev(fd, iov, cnt);
8539 Py_END_ALLOW_THREADS
8540
8541 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008542 if (res < 0)
8543 return posix_error();
8544
Ross Lagerwall7807c352011-03-17 20:20:30 +02008545 return PyLong_FromSsize_t(res);
8546}
8547#endif
8548
8549#ifdef HAVE_PWRITE
8550PyDoc_STRVAR(posix_pwrite__doc__,
8551"pwrite(fd, string, offset) -> byteswritten\n\n\
8552Write string to a file descriptor, fd, from offset, leaving the file\n\
8553offset unchanged.");
8554
8555static PyObject *
8556posix_pwrite(PyObject *self, PyObject *args)
8557{
8558 Py_buffer pbuf;
8559 int fd;
8560 off_t offset;
8561 Py_ssize_t size;
8562
8563 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8564 return NULL;
8565
8566 if (!_PyVerify_fd(fd)) {
8567 PyBuffer_Release(&pbuf);
8568 return posix_error();
8569 }
8570 Py_BEGIN_ALLOW_THREADS
8571 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8572 Py_END_ALLOW_THREADS
8573 PyBuffer_Release(&pbuf);
8574 if (size < 0)
8575 return posix_error();
8576 return PyLong_FromSsize_t(size);
8577}
8578#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008579
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008580#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008581PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008582"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8583Create a FIFO (a POSIX named pipe).\n\
8584\n\
8585If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8586 and path should be relative; path will then be relative to that directory.\n\
8587dir_fd may not be implemented on your platform.\n\
8588 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008589
Barry Warsaw53699e91996-12-10 23:23:01 +00008590static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008591posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008592{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008593 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008594 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008595 int dir_fd = DEFAULT_DIR_FD;
8596 int result;
8597 PyObject *return_value = NULL;
8598 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8599
8600 memset(&path, 0, sizeof(path));
8601 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8602 path_converter, &path,
8603 &mode,
8604#ifdef HAVE_MKFIFOAT
8605 dir_fd_converter, &dir_fd
8606#else
8607 dir_fd_unavailable, &dir_fd
8608#endif
8609 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008610 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008611
Victor Stinner8c62be82010-05-06 00:08:46 +00008612 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008613#ifdef HAVE_MKFIFOAT
8614 if (dir_fd != DEFAULT_DIR_FD)
8615 result = mkfifoat(dir_fd, path.narrow, mode);
8616 else
8617#endif
8618 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008619 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008620
8621 if (result < 0) {
8622 return_value = posix_error();
8623 goto exit;
8624 }
8625
8626 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008627 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008628
8629exit:
8630 path_cleanup(&path);
8631 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008632}
8633#endif
8634
Neal Norwitz11690112002-07-30 01:08:28 +00008635#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008636PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008637"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008638Create a filesystem node (file, device special file or named pipe)\n\
8639named filename. mode specifies both the permissions to use and the\n\
8640type of node to be created, being combined (bitwise OR) with one of\n\
8641S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008642device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008643os.makedev()), otherwise it is ignored.\n\
8644\n\
8645If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8646 and path should be relative; path will then be relative to that directory.\n\
8647dir_fd may not be implemented on your platform.\n\
8648 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008649
8650
8651static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008652posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008653{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008654 path_t path;
8655 int mode = 0666;
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008656 dev_t device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008657 int dir_fd = DEFAULT_DIR_FD;
8658 int result;
8659 PyObject *return_value = NULL;
8660 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8661
8662 memset(&path, 0, sizeof(path));
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008663 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|iO&$O&:mknod", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008664 path_converter, &path,
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008665 &mode, _Py_Dev_Converter, &device,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008666#ifdef HAVE_MKNODAT
8667 dir_fd_converter, &dir_fd
8668#else
8669 dir_fd_unavailable, &dir_fd
8670#endif
8671 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008672 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008673
Victor Stinner8c62be82010-05-06 00:08:46 +00008674 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008675#ifdef HAVE_MKNODAT
8676 if (dir_fd != DEFAULT_DIR_FD)
8677 result = mknodat(dir_fd, path.narrow, mode, device);
8678 else
8679#endif
8680 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008681 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008682
8683 if (result < 0) {
8684 return_value = posix_error();
8685 goto exit;
8686 }
8687
8688 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008689 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008690
Larry Hastings9cf065c2012-06-22 16:30:09 -07008691exit:
8692 path_cleanup(&path);
8693 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008694}
8695#endif
8696
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008697#ifdef HAVE_DEVICE_MACROS
8698PyDoc_STRVAR(posix_major__doc__,
8699"major(device) -> major number\n\
8700Extracts a device major number from a raw device number.");
8701
8702static PyObject *
8703posix_major(PyObject *self, PyObject *args)
8704{
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008705 dev_t device;
8706 if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00008707 return NULL;
8708 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008709}
8710
8711PyDoc_STRVAR(posix_minor__doc__,
8712"minor(device) -> minor number\n\
8713Extracts a device minor number from a raw device number.");
8714
8715static PyObject *
8716posix_minor(PyObject *self, PyObject *args)
8717{
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008718 dev_t device;
8719 if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00008720 return NULL;
8721 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008722}
8723
8724PyDoc_STRVAR(posix_makedev__doc__,
8725"makedev(major, minor) -> device number\n\
8726Composes a raw device number from the major and minor device numbers.");
8727
8728static PyObject *
8729posix_makedev(PyObject *self, PyObject *args)
8730{
Victor Stinner8c62be82010-05-06 00:08:46 +00008731 int major, minor;
8732 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8733 return NULL;
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008734 return _PyLong_FromDev(makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008735}
8736#endif /* device macros */
8737
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008738
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008739#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008740PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008741"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008742Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008743
Barry Warsaw53699e91996-12-10 23:23:01 +00008744static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008745posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008746{
Victor Stinner8c62be82010-05-06 00:08:46 +00008747 int fd;
8748 off_t length;
8749 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008750
Ross Lagerwall7807c352011-03-17 20:20:30 +02008751 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008752 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008753
Victor Stinner8c62be82010-05-06 00:08:46 +00008754 Py_BEGIN_ALLOW_THREADS
8755 res = ftruncate(fd, length);
8756 Py_END_ALLOW_THREADS
8757 if (res < 0)
8758 return posix_error();
8759 Py_INCREF(Py_None);
8760 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008761}
8762#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008763
Ross Lagerwall7807c352011-03-17 20:20:30 +02008764#ifdef HAVE_TRUNCATE
8765PyDoc_STRVAR(posix_truncate__doc__,
8766"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008767Truncate the file given by path to length bytes.\n\
8768On some platforms, path may also be specified as an open file descriptor.\n\
8769 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008770
8771static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008772posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008773{
Georg Brandl306336b2012-06-24 12:55:33 +02008774 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008775 off_t length;
8776 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008777 PyObject *result = NULL;
8778 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008779
Georg Brandl306336b2012-06-24 12:55:33 +02008780 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008781 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008782#ifdef HAVE_FTRUNCATE
8783 path.allow_fd = 1;
8784#endif
8785 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8786 path_converter, &path,
8787 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008788 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008789
8790 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008791#ifdef HAVE_FTRUNCATE
8792 if (path.fd != -1)
8793 res = ftruncate(path.fd, length);
8794 else
8795#endif
8796 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008797 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008798 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008799 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008800 else {
8801 Py_INCREF(Py_None);
8802 result = Py_None;
8803 }
8804 path_cleanup(&path);
8805 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008806}
8807#endif
8808
Victor Stinnerd6b17692014-09-30 12:20:05 +02008809/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8810 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8811 defined, which is the case in Python on AIX. AIX bug report:
8812 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8813#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8814# define POSIX_FADVISE_AIX_BUG
8815#endif
8816
8817#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008818PyDoc_STRVAR(posix_posix_fallocate__doc__,
8819"posix_fallocate(fd, offset, len)\n\n\
8820Ensures that enough disk space is allocated for the file specified by fd\n\
8821starting from offset and continuing for len bytes.");
8822
8823static PyObject *
8824posix_posix_fallocate(PyObject *self, PyObject *args)
8825{
8826 off_t len, offset;
8827 int res, fd;
8828
8829 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8830 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8831 return NULL;
8832
8833 Py_BEGIN_ALLOW_THREADS
8834 res = posix_fallocate(fd, offset, len);
8835 Py_END_ALLOW_THREADS
8836 if (res != 0) {
8837 errno = res;
8838 return posix_error();
8839 }
8840 Py_RETURN_NONE;
8841}
8842#endif
8843
Victor Stinnerd6b17692014-09-30 12:20:05 +02008844#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008845PyDoc_STRVAR(posix_posix_fadvise__doc__,
8846"posix_fadvise(fd, offset, len, advice)\n\n\
8847Announces an intention to access data in a specific pattern thus allowing\n\
8848the kernel to make optimizations.\n\
8849The advice applies to the region of the file specified by fd starting at\n\
8850offset and continuing for len bytes.\n\
8851advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8852POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8853POSIX_FADV_DONTNEED.");
8854
8855static PyObject *
8856posix_posix_fadvise(PyObject *self, PyObject *args)
8857{
8858 off_t len, offset;
8859 int res, fd, advice;
8860
8861 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8862 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8863 return NULL;
8864
8865 Py_BEGIN_ALLOW_THREADS
8866 res = posix_fadvise(fd, offset, len, advice);
8867 Py_END_ALLOW_THREADS
8868 if (res != 0) {
8869 errno = res;
8870 return posix_error();
8871 }
8872 Py_RETURN_NONE;
8873}
8874#endif
8875
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008876#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008877PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008878"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008879Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008880
Fred Drake762e2061999-08-26 17:23:54 +00008881/* Save putenv() parameters as values here, so we can collect them when they
8882 * get re-set with another call for the same key. */
8883static PyObject *posix_putenv_garbage;
8884
Tim Peters5aa91602002-01-30 05:46:57 +00008885static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008886posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008887{
Victor Stinner84ae1182010-05-06 22:05:07 +00008888 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008889#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008890 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008891 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008892
Victor Stinner8c62be82010-05-06 00:08:46 +00008893 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008894 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008895 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008896 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008897
Victor Stinner65170952011-11-22 22:16:17 +01008898 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008899 if (newstr == NULL) {
8900 PyErr_NoMemory();
8901 goto error;
8902 }
Victor Stinner65170952011-11-22 22:16:17 +01008903 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8904 PyErr_Format(PyExc_ValueError,
8905 "the environment variable is longer than %u characters",
8906 _MAX_ENV);
8907 goto error;
8908 }
8909
Victor Stinner8c62be82010-05-06 00:08:46 +00008910 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008911 if (newenv == NULL)
8912 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008913 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008914 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008915 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008916 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008917#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008918 PyObject *os1, *os2;
8919 char *s1, *s2;
8920 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008921
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008922 if (!PyArg_ParseTuple(args,
8923 "O&O&:putenv",
8924 PyUnicode_FSConverter, &os1,
8925 PyUnicode_FSConverter, &os2))
8926 return NULL;
8927 s1 = PyBytes_AsString(os1);
8928 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008929
Victor Stinner65170952011-11-22 22:16:17 +01008930 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008931 if (newstr == NULL) {
8932 PyErr_NoMemory();
8933 goto error;
8934 }
8935
Victor Stinner8c62be82010-05-06 00:08:46 +00008936 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008937 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008938 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008939 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008940 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008941#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008942
Victor Stinner8c62be82010-05-06 00:08:46 +00008943 /* Install the first arg and newstr in posix_putenv_garbage;
8944 * this will cause previous value to be collected. This has to
8945 * happen after the real putenv() call because the old value
8946 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008947 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008948 /* really not much we can do; just leak */
8949 PyErr_Clear();
8950 }
8951 else {
8952 Py_DECREF(newstr);
8953 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008954
Martin v. Löwis011e8422009-05-05 04:43:17 +00008955#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008956 Py_DECREF(os1);
8957 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008958#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008959 Py_RETURN_NONE;
8960
8961error:
8962#ifndef MS_WINDOWS
8963 Py_DECREF(os1);
8964 Py_DECREF(os2);
8965#endif
8966 Py_XDECREF(newstr);
8967 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008968}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008969#endif /* putenv */
8970
Guido van Rossumc524d952001-10-19 01:31:59 +00008971#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008972PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008973"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008974Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008975
8976static PyObject *
8977posix_unsetenv(PyObject *self, PyObject *args)
8978{
Victor Stinner65170952011-11-22 22:16:17 +01008979 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008980#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008981 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008982#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008983
8984 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008985
Victor Stinner65170952011-11-22 22:16:17 +01008986 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008987 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008988
Victor Stinner984890f2011-11-24 13:53:38 +01008989#ifdef HAVE_BROKEN_UNSETENV
8990 unsetenv(PyBytes_AS_STRING(name));
8991#else
Victor Stinner65170952011-11-22 22:16:17 +01008992 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008993 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008994 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008995 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008996 }
Victor Stinner984890f2011-11-24 13:53:38 +01008997#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008998
Victor Stinner8c62be82010-05-06 00:08:46 +00008999 /* Remove the key from posix_putenv_garbage;
9000 * this will cause it to be collected. This has to
9001 * happen after the real unsetenv() call because the
9002 * old value was still accessible until then.
9003 */
Victor Stinner65170952011-11-22 22:16:17 +01009004 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009005 /* really not much we can do; just leak */
9006 PyErr_Clear();
9007 }
Victor Stinner65170952011-11-22 22:16:17 +01009008 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00009009 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009010}
9011#endif /* unsetenv */
9012
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009013PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009014"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009015Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009016
Guido van Rossumf68d8e52001-04-14 17:55:09 +00009017static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009018posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00009019{
Victor Stinner8c62be82010-05-06 00:08:46 +00009020 int code;
9021 char *message;
9022 if (!PyArg_ParseTuple(args, "i:strerror", &code))
9023 return NULL;
9024 message = strerror(code);
9025 if (message == NULL) {
9026 PyErr_SetString(PyExc_ValueError,
9027 "strerror() argument out of range");
9028 return NULL;
9029 }
Victor Stinner1b579672011-12-17 05:47:23 +01009030 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009031}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009032
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009033
Guido van Rossumc9641791998-08-04 15:26:23 +00009034#ifdef HAVE_SYS_WAIT_H
9035
Fred Drake106c1a02002-04-23 15:58:02 +00009036#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009037PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009038"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009039Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00009040
9041static PyObject *
9042posix_WCOREDUMP(PyObject *self, PyObject *args)
9043{
Victor Stinner8c62be82010-05-06 00:08:46 +00009044 WAIT_TYPE status;
9045 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009046
Victor Stinner8c62be82010-05-06 00:08:46 +00009047 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
9048 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009049
Victor Stinner8c62be82010-05-06 00:08:46 +00009050 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009051}
9052#endif /* WCOREDUMP */
9053
9054#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009055PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009056"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00009057Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009058job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00009059
9060static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009061posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00009062{
Victor Stinner8c62be82010-05-06 00:08:46 +00009063 WAIT_TYPE status;
9064 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009065
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
9067 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009068
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009070}
9071#endif /* WIFCONTINUED */
9072
Guido van Rossumc9641791998-08-04 15:26:23 +00009073#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009074PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009075"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009076Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009077
9078static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009079posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009080{
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 WAIT_TYPE status;
9082 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009083
Victor Stinner8c62be82010-05-06 00:08:46 +00009084 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
9085 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009086
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009088}
9089#endif /* WIFSTOPPED */
9090
9091#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009092PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009093"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009094Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009095
9096static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009097posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009098{
Victor Stinner8c62be82010-05-06 00:08:46 +00009099 WAIT_TYPE status;
9100 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009101
Victor Stinner8c62be82010-05-06 00:08:46 +00009102 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9103 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009104
Victor Stinner8c62be82010-05-06 00:08:46 +00009105 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009106}
9107#endif /* WIFSIGNALED */
9108
9109#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009110PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009111"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009112Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009113system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009114
9115static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009116posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009117{
Victor Stinner8c62be82010-05-06 00:08:46 +00009118 WAIT_TYPE status;
9119 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009120
Victor Stinner8c62be82010-05-06 00:08:46 +00009121 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9122 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009123
Victor Stinner8c62be82010-05-06 00:08:46 +00009124 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009125}
9126#endif /* WIFEXITED */
9127
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009128#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009129PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009130"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009131Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009132
9133static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009134posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009135{
Victor Stinner8c62be82010-05-06 00:08:46 +00009136 WAIT_TYPE status;
9137 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009138
Victor Stinner8c62be82010-05-06 00:08:46 +00009139 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9140 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009141
Victor Stinner8c62be82010-05-06 00:08:46 +00009142 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009143}
9144#endif /* WEXITSTATUS */
9145
9146#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009147PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009148"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009149Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009150value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009151
9152static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009153posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009154{
Victor Stinner8c62be82010-05-06 00:08:46 +00009155 WAIT_TYPE status;
9156 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009157
Victor Stinner8c62be82010-05-06 00:08:46 +00009158 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9159 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009160
Victor Stinner8c62be82010-05-06 00:08:46 +00009161 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009162}
9163#endif /* WTERMSIG */
9164
9165#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009166PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009167"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009168Return the signal that stopped the process that provided\n\
9169the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009170
9171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009172posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009173{
Victor Stinner8c62be82010-05-06 00:08:46 +00009174 WAIT_TYPE status;
9175 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009176
Victor Stinner8c62be82010-05-06 00:08:46 +00009177 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9178 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009179
Victor Stinner8c62be82010-05-06 00:08:46 +00009180 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009181}
9182#endif /* WSTOPSIG */
9183
9184#endif /* HAVE_SYS_WAIT_H */
9185
9186
Thomas Wouters477c8d52006-05-27 19:21:47 +00009187#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009188#ifdef _SCO_DS
9189/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9190 needed definitions in sys/statvfs.h */
9191#define _SVID3
9192#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009193#include <sys/statvfs.h>
9194
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009195static PyObject*
9196_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009197 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9198 if (v == NULL)
9199 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009200
9201#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009202 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9203 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9204 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9205 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9206 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9207 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9208 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9209 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9210 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9211 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009212#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009213 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9214 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9215 PyStructSequence_SET_ITEM(v, 2,
9216 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9217 PyStructSequence_SET_ITEM(v, 3,
9218 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9219 PyStructSequence_SET_ITEM(v, 4,
9220 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9221 PyStructSequence_SET_ITEM(v, 5,
9222 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9223 PyStructSequence_SET_ITEM(v, 6,
9224 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9225 PyStructSequence_SET_ITEM(v, 7,
9226 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9227 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9228 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009229#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009230 if (PyErr_Occurred()) {
9231 Py_DECREF(v);
9232 return NULL;
9233 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009234
Victor Stinner8c62be82010-05-06 00:08:46 +00009235 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009236}
9237
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009238PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009239"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009240Perform an fstatvfs system call on the given fd.\n\
9241Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009242
9243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009244posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009245{
Victor Stinner8c62be82010-05-06 00:08:46 +00009246 int fd, res;
9247 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009248
Victor Stinner8c62be82010-05-06 00:08:46 +00009249 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9250 return NULL;
9251 Py_BEGIN_ALLOW_THREADS
9252 res = fstatvfs(fd, &st);
9253 Py_END_ALLOW_THREADS
9254 if (res != 0)
9255 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009256
Victor Stinner8c62be82010-05-06 00:08:46 +00009257 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009258}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009259#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009260
9261
Thomas Wouters477c8d52006-05-27 19:21:47 +00009262#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009263#include <sys/statvfs.h>
9264
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009265PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009266"statvfs(path)\n\n\
9267Perform a statvfs system call on the given path.\n\
9268\n\
9269path may always be specified as a string.\n\
9270On some platforms, path may also be specified as an open file descriptor.\n\
9271 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009272
9273static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009274posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009275{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009276 static char *keywords[] = {"path", NULL};
9277 path_t path;
9278 int result;
9279 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009280 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009281
Larry Hastings9cf065c2012-06-22 16:30:09 -07009282 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009283 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009284#ifdef HAVE_FSTATVFS
9285 path.allow_fd = 1;
9286#endif
9287 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9288 path_converter, &path
9289 ))
9290 return NULL;
9291
9292 Py_BEGIN_ALLOW_THREADS
9293#ifdef HAVE_FSTATVFS
9294 if (path.fd != -1) {
9295#ifdef __APPLE__
9296 /* handle weak-linking on Mac OS X 10.3 */
9297 if (fstatvfs == NULL) {
9298 fd_specified("statvfs", path.fd);
9299 goto exit;
9300 }
9301#endif
9302 result = fstatvfs(path.fd, &st);
9303 }
9304 else
9305#endif
9306 result = statvfs(path.narrow, &st);
9307 Py_END_ALLOW_THREADS
9308
9309 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009310 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009311 goto exit;
9312 }
9313
9314 return_value = _pystatvfs_fromstructstatvfs(st);
9315
9316exit:
9317 path_cleanup(&path);
9318 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009319}
9320#endif /* HAVE_STATVFS */
9321
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009322#ifdef MS_WINDOWS
9323PyDoc_STRVAR(win32__getdiskusage__doc__,
9324"_getdiskusage(path) -> (total, free)\n\n\
9325Return disk usage statistics about the given path as (total, free) tuple.");
9326
9327static PyObject *
9328win32__getdiskusage(PyObject *self, PyObject *args)
9329{
9330 BOOL retval;
9331 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009332 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009333
Victor Stinner6139c1b2011-11-09 22:14:14 +01009334 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009335 return NULL;
9336
9337 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009338 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009339 Py_END_ALLOW_THREADS
9340 if (retval == 0)
9341 return PyErr_SetFromWindowsErr(0);
9342
9343 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9344}
9345#endif
9346
9347
Fred Drakec9680921999-12-13 16:37:25 +00009348/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9349 * It maps strings representing configuration variable names to
9350 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009351 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009352 * rarely-used constants. There are three separate tables that use
9353 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009354 *
9355 * This code is always included, even if none of the interfaces that
9356 * need it are included. The #if hackery needed to avoid it would be
9357 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009358 */
9359struct constdef {
9360 char *name;
9361 long value;
9362};
9363
Fred Drake12c6e2d1999-12-14 21:25:03 +00009364static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009365conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009366 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009367{
Christian Heimes217cfd12007-12-02 14:31:20 +00009368 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009369 *valuep = PyLong_AS_LONG(arg);
9370 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009371 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009372 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009373 /* look up the value in the table using a binary search */
9374 size_t lo = 0;
9375 size_t mid;
9376 size_t hi = tablesize;
9377 int cmp;
9378 const char *confname;
9379 if (!PyUnicode_Check(arg)) {
9380 PyErr_SetString(PyExc_TypeError,
9381 "configuration names must be strings or integers");
9382 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009384 confname = _PyUnicode_AsString(arg);
9385 if (confname == NULL)
9386 return 0;
9387 while (lo < hi) {
9388 mid = (lo + hi) / 2;
9389 cmp = strcmp(confname, table[mid].name);
9390 if (cmp < 0)
9391 hi = mid;
9392 else if (cmp > 0)
9393 lo = mid + 1;
9394 else {
9395 *valuep = table[mid].value;
9396 return 1;
9397 }
9398 }
9399 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9400 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009401 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009402}
9403
9404
9405#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9406static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009407#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009408 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009409#endif
9410#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009411 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009412#endif
Fred Drakec9680921999-12-13 16:37:25 +00009413#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009414 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009415#endif
9416#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009417 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009418#endif
9419#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009420 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009421#endif
9422#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009423 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009424#endif
9425#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009426 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009427#endif
9428#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009429 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009430#endif
9431#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009432 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009433#endif
9434#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009435 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009436#endif
9437#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009438 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009439#endif
9440#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009441 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009442#endif
9443#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009444 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009445#endif
9446#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009447 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009448#endif
9449#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009450 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009451#endif
9452#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009453 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009454#endif
9455#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009456 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009457#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009458#ifdef _PC_ACL_ENABLED
9459 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9460#endif
9461#ifdef _PC_MIN_HOLE_SIZE
9462 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9463#endif
9464#ifdef _PC_ALLOC_SIZE_MIN
9465 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9466#endif
9467#ifdef _PC_REC_INCR_XFER_SIZE
9468 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9469#endif
9470#ifdef _PC_REC_MAX_XFER_SIZE
9471 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9472#endif
9473#ifdef _PC_REC_MIN_XFER_SIZE
9474 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9475#endif
9476#ifdef _PC_REC_XFER_ALIGN
9477 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9478#endif
9479#ifdef _PC_SYMLINK_MAX
9480 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9481#endif
9482#ifdef _PC_XATTR_ENABLED
9483 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9484#endif
9485#ifdef _PC_XATTR_EXISTS
9486 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9487#endif
9488#ifdef _PC_TIMESTAMP_RESOLUTION
9489 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9490#endif
Fred Drakec9680921999-12-13 16:37:25 +00009491};
9492
Fred Drakec9680921999-12-13 16:37:25 +00009493static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009494conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009495{
9496 return conv_confname(arg, valuep, posix_constants_pathconf,
9497 sizeof(posix_constants_pathconf)
9498 / sizeof(struct constdef));
9499}
9500#endif
9501
9502#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009503PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009504"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009505Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009506If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009507
9508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009509posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009510{
9511 PyObject *result = NULL;
9512 int name, fd;
9513
Fred Drake12c6e2d1999-12-14 21:25:03 +00009514 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9515 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009516 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009517
Stefan Krah0e803b32010-11-26 16:16:47 +00009518 errno = 0;
9519 limit = fpathconf(fd, name);
9520 if (limit == -1 && errno != 0)
9521 posix_error();
9522 else
9523 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009524 }
9525 return result;
9526}
9527#endif
9528
9529
9530#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009531PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009532"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009533Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009534If there is no limit, return -1.\n\
9535On some platforms, path may also be specified as an open file descriptor.\n\
9536 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009537
9538static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009539posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009540{
Georg Brandl306336b2012-06-24 12:55:33 +02009541 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009542 PyObject *result = NULL;
9543 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009544 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009545
Georg Brandl306336b2012-06-24 12:55:33 +02009546 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009547 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009548#ifdef HAVE_FPATHCONF
9549 path.allow_fd = 1;
9550#endif
9551 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9552 path_converter, &path,
9553 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009555
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009557#ifdef HAVE_FPATHCONF
9558 if (path.fd != -1)
9559 limit = fpathconf(path.fd, name);
9560 else
9561#endif
9562 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 if (limit == -1 && errno != 0) {
9564 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009565 /* could be a path or name problem */
9566 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009567 else
Victor Stinner292c8352012-10-30 02:17:38 +01009568 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 }
9570 else
9571 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009572 }
Georg Brandl306336b2012-06-24 12:55:33 +02009573 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009574 return result;
9575}
9576#endif
9577
9578#ifdef HAVE_CONFSTR
9579static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009580#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009582#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009583#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009585#endif
9586#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009587 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009588#endif
Fred Draked86ed291999-12-15 15:34:33 +00009589#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009591#endif
9592#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009594#endif
9595#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009597#endif
9598#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009600#endif
Fred Drakec9680921999-12-13 16:37:25 +00009601#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009602 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009603#endif
9604#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009605 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009606#endif
9607#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009608 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009609#endif
9610#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009611 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009612#endif
9613#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009614 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009615#endif
9616#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009617 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009618#endif
9619#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009620 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009621#endif
9622#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009623 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009624#endif
Fred Draked86ed291999-12-15 15:34:33 +00009625#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009626 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009627#endif
Fred Drakec9680921999-12-13 16:37:25 +00009628#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009629 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009630#endif
Fred Draked86ed291999-12-15 15:34:33 +00009631#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009633#endif
9634#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009635 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009636#endif
9637#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009638 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009639#endif
9640#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009642#endif
Fred Drakec9680921999-12-13 16:37:25 +00009643#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009644 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009645#endif
9646#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009647 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009648#endif
9649#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009651#endif
9652#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009654#endif
9655#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009656 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009657#endif
9658#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009660#endif
9661#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009662 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009663#endif
9664#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009665 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009666#endif
9667#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009669#endif
9670#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009671 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009672#endif
9673#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009674 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009675#endif
9676#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009678#endif
9679#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009680 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009681#endif
9682#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009683 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009684#endif
9685#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009686 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009687#endif
9688#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009689 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009690#endif
Fred Draked86ed291999-12-15 15:34:33 +00009691#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009692 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009693#endif
9694#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009695 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009696#endif
9697#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009698 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009699#endif
9700#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009701 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009702#endif
9703#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009704 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009705#endif
9706#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009707 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009708#endif
9709#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009711#endif
9712#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009713 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009714#endif
9715#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009717#endif
9718#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009719 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009720#endif
9721#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009722 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009723#endif
9724#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009726#endif
9727#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009729#endif
Fred Drakec9680921999-12-13 16:37:25 +00009730};
9731
9732static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009733conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009734{
9735 return conv_confname(arg, valuep, posix_constants_confstr,
9736 sizeof(posix_constants_confstr)
9737 / sizeof(struct constdef));
9738}
9739
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009740PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009741"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009742Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009743
9744static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009745posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009746{
9747 PyObject *result = NULL;
9748 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009749 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009750 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009751
Victor Stinnercb043522010-09-10 23:49:04 +00009752 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9753 return NULL;
9754
9755 errno = 0;
9756 len = confstr(name, buffer, sizeof(buffer));
9757 if (len == 0) {
9758 if (errno) {
9759 posix_error();
9760 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009761 }
9762 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009763 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009764 }
9765 }
Victor Stinnercb043522010-09-10 23:49:04 +00009766
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009767 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009768 char *buf = PyMem_Malloc(len);
9769 if (buf == NULL)
9770 return PyErr_NoMemory();
9771 confstr(name, buf, len);
9772 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9773 PyMem_Free(buf);
9774 }
9775 else
9776 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009777 return result;
9778}
9779#endif
9780
9781
9782#ifdef HAVE_SYSCONF
9783static struct constdef posix_constants_sysconf[] = {
9784#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009786#endif
9787#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009789#endif
9790#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009792#endif
9793#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009795#endif
9796#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009798#endif
9799#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009801#endif
9802#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009804#endif
9805#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009807#endif
9808#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009810#endif
9811#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009813#endif
Fred Draked86ed291999-12-15 15:34:33 +00009814#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009816#endif
9817#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009819#endif
Fred Drakec9680921999-12-13 16:37:25 +00009820#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009822#endif
Fred Drakec9680921999-12-13 16:37:25 +00009823#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009825#endif
9826#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009828#endif
9829#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009831#endif
9832#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009834#endif
9835#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009837#endif
Fred Draked86ed291999-12-15 15:34:33 +00009838#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009840#endif
Fred Drakec9680921999-12-13 16:37:25 +00009841#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009843#endif
9844#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009846#endif
9847#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009849#endif
9850#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009852#endif
9853#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009854 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009855#endif
Fred Draked86ed291999-12-15 15:34:33 +00009856#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009857 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009858#endif
Fred Drakec9680921999-12-13 16:37:25 +00009859#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009861#endif
9862#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009863 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009864#endif
9865#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009867#endif
9868#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009869 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009870#endif
9871#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009872 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009873#endif
9874#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009875 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009876#endif
9877#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009878 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009879#endif
9880#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009881 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009882#endif
9883#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009885#endif
9886#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009887 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009888#endif
9889#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009890 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009891#endif
9892#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009894#endif
9895#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009896 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009897#endif
9898#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009900#endif
9901#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009902 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009903#endif
9904#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009905 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009906#endif
9907#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009909#endif
9910#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009912#endif
9913#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009915#endif
9916#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
Fred Draked86ed291999-12-15 15:34:33 +00009928#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009930#endif
Fred Drakec9680921999-12-13 16:37:25 +00009931#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
9937#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
Fred Draked86ed291999-12-15 15:34:33 +00009940#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009942#endif
Fred Drakec9680921999-12-13 16:37:25 +00009943#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
Fred Draked86ed291999-12-15 15:34:33 +00009946#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009948#endif
9949#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009951#endif
Fred Drakec9680921999-12-13 16:37:25 +00009952#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
9955#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
9961#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
Fred Draked86ed291999-12-15 15:34:33 +00009964#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009966#endif
Fred Drakec9680921999-12-13 16:37:25 +00009967#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009969#endif
9970#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
9979#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009981#endif
9982#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
9985#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009987#endif
Fred Draked86ed291999-12-15 15:34:33 +00009988#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009990#endif
Fred Drakec9680921999-12-13 16:37:25 +00009991#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
Fred Draked86ed291999-12-15 15:34:33 +00009997#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009999#endif
Fred Drakec9680921999-12-13 16:37:25 +000010000#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
10018#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
10021#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010023#endif
10024#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010026#endif
Fred Draked86ed291999-12-15 15:34:33 +000010027#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010029#endif
10030#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010032#endif
Fred Drakec9680921999-12-13 16:37:25 +000010033#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
10036#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
10039#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010041#endif
10042#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010044#endif
10045#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
10048#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
10051#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010053#endif
10054#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
10057#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010059#endif
10060#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
10063#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010065#endif
10066#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
10069#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010071#endif
10072#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010074#endif
10075#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010077#endif
10078#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010080#endif
10081#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010083#endif
10084#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010086#endif
10087#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010089#endif
10090#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010092#endif
10093#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010095#endif
10096#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
10105#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010107#endif
10108#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
10111#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
10114#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
10117#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
10120#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
10123#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
10126#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
10129#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
Fred Draked86ed291999-12-15 15:34:33 +000010138#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010140#endif
Fred Drakec9680921999-12-13 16:37:25 +000010141#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
10153#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
10156#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010158#endif
10159#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
10162#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
10168#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
10234#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
10258#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010260#endif
10261#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010263#endif
10264#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010266#endif
10267#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010269#endif
10270#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010272#endif
10273#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010275#endif
10276};
10277
10278static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010279conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010280{
10281 return conv_confname(arg, valuep, posix_constants_sysconf,
10282 sizeof(posix_constants_sysconf)
10283 / sizeof(struct constdef));
10284}
10285
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010286PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010287"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010288Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010289
10290static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010291posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010292{
10293 PyObject *result = NULL;
10294 int name;
10295
10296 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +020010297 long value;
Fred Drakec9680921999-12-13 16:37:25 +000010298
10299 errno = 0;
10300 value = sysconf(name);
10301 if (value == -1 && errno != 0)
10302 posix_error();
10303 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010304 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010305 }
10306 return result;
10307}
10308#endif
10309
10310
Fred Drakebec628d1999-12-15 18:31:10 +000010311/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010312 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010313 * the exported dictionaries that are used to publish information about the
10314 * names available on the host platform.
10315 *
10316 * Sorting the table at runtime ensures that the table is properly ordered
10317 * when used, even for platforms we're not able to test on. It also makes
10318 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010319 */
Fred Drakebec628d1999-12-15 18:31:10 +000010320
10321static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010322cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010323{
10324 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010326 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010327 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010328
10329 return strcmp(c1->name, c2->name);
10330}
10331
10332static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010333setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010335{
Fred Drakebec628d1999-12-15 18:31:10 +000010336 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010337 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010338
10339 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10340 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010341 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010343
Barry Warsaw3155db32000-04-13 15:20:40 +000010344 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 PyObject *o = PyLong_FromLong(table[i].value);
10346 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10347 Py_XDECREF(o);
10348 Py_DECREF(d);
10349 return -1;
10350 }
10351 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010352 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010353 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010354}
10355
Fred Drakebec628d1999-12-15 18:31:10 +000010356/* Return -1 on failure, 0 on success. */
10357static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010358setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010359{
10360#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010361 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010362 sizeof(posix_constants_pathconf)
10363 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010364 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010365 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010366#endif
10367#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010368 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010369 sizeof(posix_constants_confstr)
10370 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010371 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010372 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010373#endif
10374#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010375 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010376 sizeof(posix_constants_sysconf)
10377 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010378 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010379 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010380#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010381 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010382}
Fred Draked86ed291999-12-15 15:34:33 +000010383
10384
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010385PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010386"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010387Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010388in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010389
10390static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010391posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010392{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010393 abort();
10394 /*NOTREACHED*/
10395 Py_FatalError("abort() called from Python code didn't abort!");
10396 return NULL;
10397}
Fred Drakebec628d1999-12-15 18:31:10 +000010398
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010399#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010400PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010401"startfile(filepath [, operation]) - Start a file with its associated\n\
10402application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010403\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010404When \"operation\" is not specified or \"open\", this acts like\n\
10405double-clicking the file in Explorer, or giving the file name as an\n\
10406argument to the DOS \"start\" command: the file is opened with whatever\n\
10407application (if any) its extension is associated.\n\
10408When another \"operation\" is given, it specifies what should be done with\n\
10409the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010410\n\
10411startfile returns as soon as the associated application is launched.\n\
10412There is no option to wait for the application to close, and no way\n\
10413to retrieve the application's exit status.\n\
10414\n\
10415The filepath is relative to the current directory. If you want to use\n\
10416an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010417the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010418
10419static PyObject *
10420win32_startfile(PyObject *self, PyObject *args)
10421{
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 PyObject *ofilepath;
10423 char *filepath;
10424 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010425 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010426 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010427
Victor Stinnereb5657a2011-09-30 01:44:27 +020010428 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010429 if (!PyArg_ParseTuple(args, "U|s:startfile",
10430 &unipath, &operation)) {
10431 PyErr_Clear();
10432 goto normal;
10433 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010434
Victor Stinner8c62be82010-05-06 00:08:46 +000010435 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010436 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010438 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 PyErr_Clear();
10440 operation = NULL;
10441 goto normal;
10442 }
10443 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010444
Victor Stinnereb5657a2011-09-30 01:44:27 +020010445 wpath = PyUnicode_AsUnicode(unipath);
10446 if (wpath == NULL)
10447 goto normal;
10448 if (uoperation) {
10449 woperation = PyUnicode_AsUnicode(uoperation);
10450 if (woperation == NULL)
10451 goto normal;
10452 }
10453 else
10454 woperation = NULL;
10455
Victor Stinner8c62be82010-05-06 00:08:46 +000010456 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010457 rc = ShellExecuteW((HWND)0, woperation, wpath,
10458 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010459 Py_END_ALLOW_THREADS
10460
Victor Stinnereb5657a2011-09-30 01:44:27 +020010461 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010462 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010463 win32_error_object("startfile", unipath);
10464 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010465 }
10466 Py_INCREF(Py_None);
10467 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010468
10469normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10471 PyUnicode_FSConverter, &ofilepath,
10472 &operation))
10473 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010474 if (win32_warn_bytes_api()) {
10475 Py_DECREF(ofilepath);
10476 return NULL;
10477 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 filepath = PyBytes_AsString(ofilepath);
10479 Py_BEGIN_ALLOW_THREADS
10480 rc = ShellExecute((HWND)0, operation, filepath,
10481 NULL, NULL, SW_SHOWNORMAL);
10482 Py_END_ALLOW_THREADS
10483 if (rc <= (HINSTANCE)32) {
10484 PyObject *errval = win32_error("startfile", filepath);
10485 Py_DECREF(ofilepath);
10486 return errval;
10487 }
10488 Py_DECREF(ofilepath);
10489 Py_INCREF(Py_None);
10490 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010491}
10492#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010493
Martin v. Löwis438b5342002-12-27 10:16:42 +000010494#ifdef HAVE_GETLOADAVG
10495PyDoc_STRVAR(posix_getloadavg__doc__,
10496"getloadavg() -> (float, float, float)\n\n\
10497Return the number of processes in the system run queue averaged over\n\
10498the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10499was unobtainable");
10500
10501static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010502posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010503{
10504 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010505 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010506 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10507 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010508 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010509 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010510}
10511#endif
10512
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010513PyDoc_STRVAR(device_encoding__doc__,
10514"device_encoding(fd) -> str\n\n\
10515Return a string describing the encoding of the device\n\
10516if the output is a terminal; else return None.");
10517
10518static PyObject *
10519device_encoding(PyObject *self, PyObject *args)
10520{
Victor Stinner8c62be82010-05-06 00:08:46 +000010521 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010522
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10524 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010525
10526 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010527}
10528
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010529#ifdef HAVE_SETRESUID
10530PyDoc_STRVAR(posix_setresuid__doc__,
10531"setresuid(ruid, euid, suid)\n\n\
10532Set the current process's real, effective, and saved user ids.");
10533
10534static PyObject*
10535posix_setresuid (PyObject *self, PyObject *args)
10536{
Victor Stinner8c62be82010-05-06 00:08:46 +000010537 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010538 uid_t ruid, euid, suid;
10539 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10540 _Py_Uid_Converter, &ruid,
10541 _Py_Uid_Converter, &euid,
10542 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 return NULL;
10544 if (setresuid(ruid, euid, suid) < 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_SETRESGID
10551PyDoc_STRVAR(posix_setresgid__doc__,
10552"setresgid(rgid, egid, sgid)\n\n\
10553Set the current process's real, effective, and saved group ids.");
10554
10555static PyObject*
10556posix_setresgid (PyObject *self, PyObject *args)
10557{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010558 gid_t rgid, egid, sgid;
10559 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10560 _Py_Gid_Converter, &rgid,
10561 _Py_Gid_Converter, &egid,
10562 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010563 return NULL;
10564 if (setresgid(rgid, egid, sgid) < 0)
10565 return posix_error();
10566 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010567}
10568#endif
10569
10570#ifdef HAVE_GETRESUID
10571PyDoc_STRVAR(posix_getresuid__doc__,
10572"getresuid() -> (ruid, euid, suid)\n\n\
10573Get tuple of the current process's real, effective, and saved user ids.");
10574
10575static PyObject*
10576posix_getresuid (PyObject *self, PyObject *noargs)
10577{
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010579 if (getresuid(&ruid, &euid, &suid) < 0)
10580 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010581 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10582 _PyLong_FromUid(euid),
10583 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010584}
10585#endif
10586
10587#ifdef HAVE_GETRESGID
10588PyDoc_STRVAR(posix_getresgid__doc__,
10589"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010590Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010591
10592static PyObject*
10593posix_getresgid (PyObject *self, PyObject *noargs)
10594{
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010596 if (getresgid(&rgid, &egid, &sgid) < 0)
10597 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010598 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10599 _PyLong_FromGid(egid),
10600 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010601}
10602#endif
10603
Benjamin Peterson9428d532011-09-14 11:45:52 -040010604#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010605
Benjamin Peterson799bd802011-08-31 22:15:17 -040010606PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010607"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10608Return the value of extended attribute attribute on path.\n\
10609\n\
10610path may be either a string or an open file descriptor.\n\
10611If follow_symlinks is False, and the last element of the path is a symbolic\n\
10612 link, getxattr will examine the symbolic link itself instead of the file\n\
10613 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010614
10615static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010616posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010617{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010618 path_t path;
10619 path_t attribute;
10620 int follow_symlinks = 1;
10621 PyObject *buffer = NULL;
10622 int i;
10623 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010624
Larry Hastings9cf065c2012-06-22 16:30:09 -070010625 memset(&path, 0, sizeof(path));
10626 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010627 path.function_name = "getxattr";
10628 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010629 path.allow_fd = 1;
10630 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10631 path_converter, &path,
10632 path_converter, &attribute,
10633 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010634 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010635
Larry Hastings9cf065c2012-06-22 16:30:09 -070010636 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10637 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010638
Larry Hastings9cf065c2012-06-22 16:30:09 -070010639 for (i = 0; ; i++) {
10640 void *ptr;
10641 ssize_t result;
10642 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10643 Py_ssize_t buffer_size = buffer_sizes[i];
10644 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010645 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010646 goto exit;
10647 }
10648 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10649 if (!buffer)
10650 goto exit;
10651 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010652
Larry Hastings9cf065c2012-06-22 16:30:09 -070010653 Py_BEGIN_ALLOW_THREADS;
10654 if (path.fd >= 0)
10655 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10656 else if (follow_symlinks)
10657 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10658 else
10659 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10660 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010661
Larry Hastings9cf065c2012-06-22 16:30:09 -070010662 if (result < 0) {
10663 Py_DECREF(buffer);
10664 buffer = NULL;
10665 if (errno == ERANGE)
10666 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010667 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010668 goto exit;
10669 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010670
Larry Hastings9cf065c2012-06-22 16:30:09 -070010671 if (result != buffer_size) {
10672 /* Can only shrink. */
10673 _PyBytes_Resize(&buffer, result);
10674 }
10675 break;
10676 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010677
Larry Hastings9cf065c2012-06-22 16:30:09 -070010678exit:
10679 path_cleanup(&path);
10680 path_cleanup(&attribute);
10681 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010682}
10683
10684PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010685"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10686Set extended attribute attribute on path to value.\n\
10687path may be either a string or an open file descriptor.\n\
10688If follow_symlinks is False, and the last element of the path is a symbolic\n\
10689 link, setxattr will modify the symbolic link itself instead of the file\n\
10690 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010691
10692static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010693posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010694{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010695 path_t path;
10696 path_t attribute;
10697 Py_buffer value;
10698 int flags = 0;
10699 int follow_symlinks = 1;
10700 int result;
10701 PyObject *return_value = NULL;
10702 static char *keywords[] = {"path", "attribute", "value",
10703 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010704
Larry Hastings9cf065c2012-06-22 16:30:09 -070010705 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010706 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010707 path.allow_fd = 1;
10708 memset(&attribute, 0, sizeof(attribute));
10709 memset(&value, 0, sizeof(value));
10710 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10711 keywords,
10712 path_converter, &path,
10713 path_converter, &attribute,
10714 &value, &flags,
10715 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010716 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010717
10718 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10719 goto exit;
10720
Benjamin Peterson799bd802011-08-31 22:15:17 -040010721 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010722 if (path.fd > -1)
10723 result = fsetxattr(path.fd, attribute.narrow,
10724 value.buf, value.len, flags);
10725 else if (follow_symlinks)
10726 result = setxattr(path.narrow, attribute.narrow,
10727 value.buf, value.len, flags);
10728 else
10729 result = lsetxattr(path.narrow, attribute.narrow,
10730 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010731 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010732
Larry Hastings9cf065c2012-06-22 16:30:09 -070010733 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010734 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010735 goto exit;
10736 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010737
Larry Hastings9cf065c2012-06-22 16:30:09 -070010738 return_value = Py_None;
10739 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010740
Larry Hastings9cf065c2012-06-22 16:30:09 -070010741exit:
10742 path_cleanup(&path);
10743 path_cleanup(&attribute);
10744 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010745
Larry Hastings9cf065c2012-06-22 16:30:09 -070010746 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010747}
10748
10749PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010750"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10751Remove extended attribute attribute on path.\n\
10752path may be either a string or an open file descriptor.\n\
10753If follow_symlinks is False, and the last element of the path is a symbolic\n\
10754 link, removexattr will modify the symbolic link itself instead of the file\n\
10755 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010756
10757static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010758posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010759{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010760 path_t path;
10761 path_t attribute;
10762 int follow_symlinks = 1;
10763 int result;
10764 PyObject *return_value = NULL;
10765 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010766
Larry Hastings9cf065c2012-06-22 16:30:09 -070010767 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010768 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010769 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010770 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010771 path.allow_fd = 1;
10772 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10773 keywords,
10774 path_converter, &path,
10775 path_converter, &attribute,
10776 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010777 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010778
10779 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10780 goto exit;
10781
Benjamin Peterson799bd802011-08-31 22:15:17 -040010782 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010783 if (path.fd > -1)
10784 result = fremovexattr(path.fd, attribute.narrow);
10785 else if (follow_symlinks)
10786 result = removexattr(path.narrow, attribute.narrow);
10787 else
10788 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010789 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010790
Larry Hastings9cf065c2012-06-22 16:30:09 -070010791 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010792 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010793 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010794 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010795
Larry Hastings9cf065c2012-06-22 16:30:09 -070010796 return_value = Py_None;
10797 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010798
Larry Hastings9cf065c2012-06-22 16:30:09 -070010799exit:
10800 path_cleanup(&path);
10801 path_cleanup(&attribute);
10802
10803 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010804}
10805
10806PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010807"listxattr(path='.', *, follow_symlinks=True)\n\n\
10808Return a list of extended attributes on path.\n\
10809\n\
10810path may be either None, a string, or an open file descriptor.\n\
10811if path is None, listxattr will examine the current directory.\n\
10812If follow_symlinks is False, and the last element of the path is a symbolic\n\
10813 link, listxattr will examine the symbolic link itself instead of the file\n\
10814 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010815
10816static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010817posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010818{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010819 path_t path;
10820 int follow_symlinks = 1;
10821 Py_ssize_t i;
10822 PyObject *result = NULL;
10823 char *buffer = NULL;
10824 char *name;
10825 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010826
Larry Hastings9cf065c2012-06-22 16:30:09 -070010827 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010828 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010829 path.allow_fd = 1;
10830 path.fd = -1;
10831 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10832 path_converter, &path,
10833 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010834 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010835
Larry Hastings9cf065c2012-06-22 16:30:09 -070010836 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10837 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010838
Larry Hastings9cf065c2012-06-22 16:30:09 -070010839 name = path.narrow ? path.narrow : ".";
10840 for (i = 0; ; i++) {
10841 char *start, *trace, *end;
10842 ssize_t length;
10843 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10844 Py_ssize_t buffer_size = buffer_sizes[i];
10845 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010846 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010847 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010848 break;
10849 }
10850 buffer = PyMem_MALLOC(buffer_size);
10851 if (!buffer) {
10852 PyErr_NoMemory();
10853 break;
10854 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010855
Larry Hastings9cf065c2012-06-22 16:30:09 -070010856 Py_BEGIN_ALLOW_THREADS;
10857 if (path.fd > -1)
10858 length = flistxattr(path.fd, buffer, buffer_size);
10859 else if (follow_symlinks)
10860 length = listxattr(name, buffer, buffer_size);
10861 else
10862 length = llistxattr(name, buffer, buffer_size);
10863 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010864
Larry Hastings9cf065c2012-06-22 16:30:09 -070010865 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010866 if (errno == ERANGE) {
10867 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010868 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010869 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010870 }
Victor Stinner292c8352012-10-30 02:17:38 +010010871 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010872 break;
10873 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010874
Larry Hastings9cf065c2012-06-22 16:30:09 -070010875 result = PyList_New(0);
10876 if (!result) {
10877 goto exit;
10878 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010879
Larry Hastings9cf065c2012-06-22 16:30:09 -070010880 end = buffer + length;
10881 for (trace = start = buffer; trace != end; trace++) {
10882 if (!*trace) {
10883 int error;
10884 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10885 trace - start);
10886 if (!attribute) {
10887 Py_DECREF(result);
10888 result = NULL;
10889 goto exit;
10890 }
10891 error = PyList_Append(result, attribute);
10892 Py_DECREF(attribute);
10893 if (error) {
10894 Py_DECREF(result);
10895 result = NULL;
10896 goto exit;
10897 }
10898 start = trace + 1;
10899 }
10900 }
10901 break;
10902 }
10903exit:
10904 path_cleanup(&path);
10905 if (buffer)
10906 PyMem_FREE(buffer);
10907 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010908}
10909
Benjamin Peterson9428d532011-09-14 11:45:52 -040010910#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010911
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010912
Georg Brandl2fb477c2012-02-21 00:33:36 +010010913PyDoc_STRVAR(posix_urandom__doc__,
10914"urandom(n) -> str\n\n\
10915Return n random bytes suitable for cryptographic use.");
10916
10917static PyObject *
10918posix_urandom(PyObject *self, PyObject *args)
10919{
10920 Py_ssize_t size;
10921 PyObject *result;
10922 int ret;
10923
10924 /* Read arguments */
10925 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10926 return NULL;
10927 if (size < 0)
10928 return PyErr_Format(PyExc_ValueError,
10929 "negative argument not allowed");
10930 result = PyBytes_FromStringAndSize(NULL, size);
10931 if (result == NULL)
10932 return NULL;
10933
10934 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10935 PyBytes_GET_SIZE(result));
10936 if (ret == -1) {
10937 Py_DECREF(result);
10938 return NULL;
10939 }
10940 return result;
10941}
10942
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010943/* Terminal size querying */
10944
10945static PyTypeObject TerminalSizeType;
10946
10947PyDoc_STRVAR(TerminalSize_docstring,
10948 "A tuple of (columns, lines) for holding terminal window size");
10949
10950static PyStructSequence_Field TerminalSize_fields[] = {
10951 {"columns", "width of the terminal window in characters"},
10952 {"lines", "height of the terminal window in characters"},
10953 {NULL, NULL}
10954};
10955
10956static PyStructSequence_Desc TerminalSize_desc = {
10957 "os.terminal_size",
10958 TerminalSize_docstring,
10959 TerminalSize_fields,
10960 2,
10961};
10962
10963#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10964PyDoc_STRVAR(termsize__doc__,
10965 "Return the size of the terminal window as (columns, lines).\n" \
10966 "\n" \
10967 "The optional argument fd (default standard output) specifies\n" \
10968 "which file descriptor should be queried.\n" \
10969 "\n" \
10970 "If the file descriptor is not connected to a terminal, an OSError\n" \
10971 "is thrown.\n" \
10972 "\n" \
10973 "This function will only be defined if an implementation is\n" \
10974 "available for this system.\n" \
10975 "\n" \
10976 "shutil.get_terminal_size is the high-level function which should \n" \
10977 "normally be used, os.get_terminal_size is the low-level implementation.");
10978
10979static PyObject*
10980get_terminal_size(PyObject *self, PyObject *args)
10981{
10982 int columns, lines;
10983 PyObject *termsize;
10984
10985 int fd = fileno(stdout);
10986 /* Under some conditions stdout may not be connected and
10987 * fileno(stdout) may point to an invalid file descriptor. For example
10988 * GUI apps don't have valid standard streams by default.
10989 *
10990 * If this happens, and the optional fd argument is not present,
10991 * the ioctl below will fail returning EBADF. This is what we want.
10992 */
10993
10994 if (!PyArg_ParseTuple(args, "|i", &fd))
10995 return NULL;
10996
10997#ifdef TERMSIZE_USE_IOCTL
10998 {
10999 struct winsize w;
11000 if (ioctl(fd, TIOCGWINSZ, &w))
11001 return PyErr_SetFromErrno(PyExc_OSError);
11002 columns = w.ws_col;
11003 lines = w.ws_row;
11004 }
11005#endif /* TERMSIZE_USE_IOCTL */
11006
11007#ifdef TERMSIZE_USE_CONIO
11008 {
11009 DWORD nhandle;
11010 HANDLE handle;
11011 CONSOLE_SCREEN_BUFFER_INFO csbi;
11012 switch (fd) {
11013 case 0: nhandle = STD_INPUT_HANDLE;
11014 break;
11015 case 1: nhandle = STD_OUTPUT_HANDLE;
11016 break;
11017 case 2: nhandle = STD_ERROR_HANDLE;
11018 break;
11019 default:
11020 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11021 }
11022 handle = GetStdHandle(nhandle);
11023 if (handle == NULL)
11024 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11025 if (handle == INVALID_HANDLE_VALUE)
11026 return PyErr_SetFromWindowsErr(0);
11027
11028 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11029 return PyErr_SetFromWindowsErr(0);
11030
11031 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11032 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11033 }
11034#endif /* TERMSIZE_USE_CONIO */
11035
11036 termsize = PyStructSequence_New(&TerminalSizeType);
11037 if (termsize == NULL)
11038 return NULL;
11039 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11040 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11041 if (PyErr_Occurred()) {
11042 Py_DECREF(termsize);
11043 return NULL;
11044 }
11045 return termsize;
11046}
11047#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11048
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011049PyDoc_STRVAR(posix_cpu_count__doc__,
11050"cpu_count() -> integer\n\n\
11051Return the number of CPUs in the system, or None if this value cannot be\n\
11052established.");
11053
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011054static PyObject *
11055posix_cpu_count(PyObject *self)
11056{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011057 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011058#ifdef MS_WINDOWS
11059 SYSTEM_INFO sysinfo;
11060 GetSystemInfo(&sysinfo);
11061 ncpu = sysinfo.dwNumberOfProcessors;
11062#elif defined(__hpux)
11063 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11064#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11065 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011066#elif defined(__DragonFly__) || \
11067 defined(__OpenBSD__) || \
11068 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011069 defined(__NetBSD__) || \
11070 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011071 int mib[2];
11072 size_t len = sizeof(ncpu);
11073 mib[0] = CTL_HW;
11074 mib[1] = HW_NCPU;
11075 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11076 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011077#endif
11078 if (ncpu >= 1)
11079 return PyLong_FromLong(ncpu);
11080 else
11081 Py_RETURN_NONE;
11082}
11083
Victor Stinnerdaf45552013-08-28 00:53:59 +020011084PyDoc_STRVAR(get_inheritable__doc__,
11085 "get_inheritable(fd) -> bool\n" \
11086 "\n" \
11087 "Get the close-on-exe flag of the specified file descriptor.");
11088
11089static PyObject*
11090posix_get_inheritable(PyObject *self, PyObject *args)
11091{
11092 int fd;
11093 int inheritable;
11094
11095 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd))
11096 return NULL;
11097
11098 if (!_PyVerify_fd(fd))
11099 return posix_error();
11100
11101 inheritable = _Py_get_inheritable(fd);
11102 if (inheritable < 0)
11103 return NULL;
11104 return PyBool_FromLong(inheritable);
11105}
11106
11107PyDoc_STRVAR(set_inheritable__doc__,
11108 "set_inheritable(fd, inheritable)\n" \
11109 "\n" \
11110 "Set the inheritable flag of the specified file descriptor.");
11111
11112static PyObject*
11113posix_set_inheritable(PyObject *self, PyObject *args)
11114{
11115 int fd, inheritable;
11116
11117 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable))
11118 return NULL;
11119
11120 if (!_PyVerify_fd(fd))
11121 return posix_error();
11122
11123 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
11124 return NULL;
11125 Py_RETURN_NONE;
11126}
11127
11128
11129#ifdef MS_WINDOWS
11130PyDoc_STRVAR(get_handle_inheritable__doc__,
11131 "get_handle_inheritable(fd) -> bool\n" \
11132 "\n" \
11133 "Get the close-on-exe flag of the specified file descriptor.");
11134
11135static PyObject*
11136posix_get_handle_inheritable(PyObject *self, PyObject *args)
11137{
11138 Py_intptr_t handle;
11139 DWORD flags;
11140
11141 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle))
11142 return NULL;
11143
11144 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11145 PyErr_SetFromWindowsErr(0);
11146 return NULL;
11147 }
11148
11149 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT);
11150}
11151
11152PyDoc_STRVAR(set_handle_inheritable__doc__,
11153 "set_handle_inheritable(fd, inheritable)\n" \
11154 "\n" \
11155 "Set the inheritable flag of the specified handle.");
11156
11157static PyObject*
11158posix_set_handle_inheritable(PyObject *self, PyObject *args)
11159{
11160 int inheritable = 1;
11161 Py_intptr_t handle;
11162 DWORD flags;
11163
11164 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable",
11165 &handle, &inheritable))
11166 return NULL;
11167
11168 if (inheritable)
11169 flags = HANDLE_FLAG_INHERIT;
11170 else
11171 flags = 0;
11172 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11173 PyErr_SetFromWindowsErr(0);
11174 return NULL;
11175 }
11176 Py_RETURN_NONE;
11177}
11178#endif /* MS_WINDOWS */
11179
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011180
Larry Hastings7726ac92014-01-31 22:03:12 -080011181/*[clinic input]
11182dump buffer
11183[clinic start generated code]*/
11184
11185#ifndef OS_TTYNAME_METHODDEF
11186 #define OS_TTYNAME_METHODDEF
11187#endif /* !defined(OS_TTYNAME_METHODDEF) */
11188/*[clinic end generated code: output=5d071bbc8f49ea12 input=524ce2e021e4eba6]*/
11189
Larry Hastings31826802013-10-19 00:09:25 -070011190
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011191static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070011192
11193 OS_STAT_METHODDEF
11194 OS_ACCESS_METHODDEF
11195 OS_TTYNAME_METHODDEF
11196
Larry Hastings9cf065c2012-06-22 16:30:09 -070011197 {"chdir", (PyCFunction)posix_chdir,
11198 METH_VARARGS | METH_KEYWORDS,
11199 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011200#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011201 {"chflags", (PyCFunction)posix_chflags,
11202 METH_VARARGS | METH_KEYWORDS,
11203 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011204#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011205 {"chmod", (PyCFunction)posix_chmod,
11206 METH_VARARGS | METH_KEYWORDS,
11207 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011208#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011209 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011210#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011211#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070011212 {"chown", (PyCFunction)posix_chown,
11213 METH_VARARGS | METH_KEYWORDS,
11214 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011215#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000011216#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011218#endif /* HAVE_LCHMOD */
11219#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011221#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000011222#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011223 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011224#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011225#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011227#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000011228#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000011230#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011231#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011233#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011234 {"getcwd", (PyCFunction)posix_getcwd_unicode,
11235 METH_NOARGS, posix_getcwd__doc__},
11236 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
11237 METH_NOARGS, posix_getcwdb__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011238#if defined(HAVE_LINK) || defined(MS_WINDOWS)
11239 {"link", (PyCFunction)posix_link,
11240 METH_VARARGS | METH_KEYWORDS,
11241 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011242#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011243 {"listdir", (PyCFunction)posix_listdir,
11244 METH_VARARGS | METH_KEYWORDS,
11245 posix_listdir__doc__},
11246 {"lstat", (PyCFunction)posix_lstat,
11247 METH_VARARGS | METH_KEYWORDS,
11248 posix_lstat__doc__},
11249 {"mkdir", (PyCFunction)posix_mkdir,
11250 METH_VARARGS | METH_KEYWORDS,
11251 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011252#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011254#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011255#ifdef HAVE_GETPRIORITY
11256 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11257#endif /* HAVE_GETPRIORITY */
11258#ifdef HAVE_SETPRIORITY
11259 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11260#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011261#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011262 {"readlink", (PyCFunction)posix_readlink,
11263 METH_VARARGS | METH_KEYWORDS,
11264 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011265#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011266#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011267 {"readlink", (PyCFunction)win_readlink,
11268 METH_VARARGS | METH_KEYWORDS,
11269 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011270#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011271 {"rename", (PyCFunction)posix_rename,
11272 METH_VARARGS | METH_KEYWORDS,
11273 posix_rename__doc__},
11274 {"replace", (PyCFunction)posix_replace,
11275 METH_VARARGS | METH_KEYWORDS,
11276 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011277 {"rmdir", (PyCFunction)posix_rmdir,
11278 METH_VARARGS | METH_KEYWORDS,
11279 posix_rmdir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011281#if defined(HAVE_SYMLINK)
11282 {"symlink", (PyCFunction)posix_symlink,
11283 METH_VARARGS | METH_KEYWORDS,
11284 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011285#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011286#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011287 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011288#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011290#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011291 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011292#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011293 {"unlink", (PyCFunction)posix_unlink,
11294 METH_VARARGS | METH_KEYWORDS,
11295 posix_unlink__doc__},
11296 {"remove", (PyCFunction)posix_unlink,
11297 METH_VARARGS | METH_KEYWORDS,
11298 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011299 {"utime", (PyCFunction)posix_utime,
11300 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011301#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011302 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011303#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011305#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011306 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011307 {"execve", (PyCFunction)posix_execve,
11308 METH_VARARGS | METH_KEYWORDS,
11309 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011310#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011311#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11313 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000011314#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011315#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011317#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011318#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011320#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011321#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011322#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011323 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11324 {"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 +020011325#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011326#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011327 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011328#endif
11329#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011330 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011331#endif
11332#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011333 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011334#endif
11335#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011336 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011337#endif
11338#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011339 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011340#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011341 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011342#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011343 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11344 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11345#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011346#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011347#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011348 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011349#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011350#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011351 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011352#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011353#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011354 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011355#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011356#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011357 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011358#endif /* HAVE_GETEUID */
11359#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011360 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011361#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011362#ifdef HAVE_GETGROUPLIST
11363 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11364#endif
Fred Drakec9680921999-12-13 16:37:25 +000011365#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011366 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011367#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011368 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011369#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011370 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011371#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011372#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011373 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011374#endif /* HAVE_GETPPID */
11375#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011376 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011377#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011378#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011379 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011380#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011381#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011382 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011383#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011384#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011386#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011387#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011388 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011389#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011390#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11392 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011393#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011394#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011395 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011396#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011397#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011398 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011399#endif /* HAVE_SETEUID */
11400#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011401 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011402#endif /* HAVE_SETEGID */
11403#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011404 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011405#endif /* HAVE_SETREUID */
11406#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011407 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011408#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011409#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011410 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011411#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011412#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011413 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011414#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011415#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011416 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011417#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011418#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011419 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011420#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011421#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011422 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011423#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011424#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011425 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011426#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011427#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011428 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011429#endif /* HAVE_WAIT3 */
11430#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011431 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011432#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011433#if defined(HAVE_WAITID) && !defined(__APPLE__)
11434 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11435#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011436#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011437 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011438#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011439#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011440 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011441#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011442#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011443 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011444#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011445#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011446 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011447#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011448#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011449 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011450#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011451#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011452 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011453#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011454 {"open", (PyCFunction)posix_open,\
11455 METH_VARARGS | METH_KEYWORDS,
11456 posix_open__doc__},
Benjamin Peterson932bba32014-02-11 10:16:16 -050011457 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011458 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11459 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11460 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011461 {"dup2", (PyCFunction)posix_dup2,
11462 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011463#ifdef HAVE_LOCKF
11464 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11465#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011466 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11467 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011468#ifdef HAVE_READV
11469 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11470#endif
11471#ifdef HAVE_PREAD
11472 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11473#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011474 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011475#ifdef HAVE_WRITEV
11476 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11477#endif
11478#ifdef HAVE_PWRITE
11479 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11480#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011481#ifdef HAVE_SENDFILE
11482 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11483 posix_sendfile__doc__},
11484#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011485 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011486 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011487#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011488 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011489#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011490#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011491 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011492#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011493#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011494 {"mkfifo", (PyCFunction)posix_mkfifo,
11495 METH_VARARGS | METH_KEYWORDS,
11496 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011497#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011498#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011499 {"mknod", (PyCFunction)posix_mknod,
11500 METH_VARARGS | METH_KEYWORDS,
11501 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011502#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011503#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011504 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11505 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11506 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011507#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011508#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011509 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011510#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011511#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011512 {"truncate", (PyCFunction)posix_truncate,
11513 METH_VARARGS | METH_KEYWORDS,
11514 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011515#endif
Victor Stinnerd6b17692014-09-30 12:20:05 +020011516#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011517 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11518#endif
Victor Stinnerd6b17692014-09-30 12:20:05 +020011519#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011520 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11521#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011522#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011523 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011524#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011525#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011526 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011527#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011528 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011529#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011530 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011531#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011532#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011533 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011534#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011535#ifdef HAVE_SYNC
11536 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11537#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011538#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011539 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011540#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011541#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011542#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011544#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011545#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011547#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011548#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011549 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011550#endif /* WIFSTOPPED */
11551#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011553#endif /* WIFSIGNALED */
11554#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011556#endif /* WIFEXITED */
11557#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011559#endif /* WEXITSTATUS */
11560#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011561 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011562#endif /* WTERMSIG */
11563#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011564 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011565#endif /* WSTOPSIG */
11566#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011567#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011568 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011569#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011570#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011571 {"statvfs", (PyCFunction)posix_statvfs,
11572 METH_VARARGS | METH_KEYWORDS,
11573 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011574#endif
Fred Drakec9680921999-12-13 16:37:25 +000011575#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011576 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011577#endif
11578#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011579 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011580#endif
11581#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011582 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011583#endif
11584#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011585 {"pathconf", (PyCFunction)posix_pathconf,
11586 METH_VARARGS | METH_KEYWORDS,
11587 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011588#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011589 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011590#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011591 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011592 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011593 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011594 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011595 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011596#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011597#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011598 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011599#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011600 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011601#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011602 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011603#endif
11604#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011605 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011606#endif
11607#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011608 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011609#endif
11610#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011611 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011612#endif
11613
Benjamin Peterson9428d532011-09-14 11:45:52 -040011614#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011615 {"setxattr", (PyCFunction)posix_setxattr,
11616 METH_VARARGS | METH_KEYWORDS,
11617 posix_setxattr__doc__},
11618 {"getxattr", (PyCFunction)posix_getxattr,
11619 METH_VARARGS | METH_KEYWORDS,
11620 posix_getxattr__doc__},
11621 {"removexattr", (PyCFunction)posix_removexattr,
11622 METH_VARARGS | METH_KEYWORDS,
11623 posix_removexattr__doc__},
11624 {"listxattr", (PyCFunction)posix_listxattr,
11625 METH_VARARGS | METH_KEYWORDS,
11626 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011627#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011628#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11629 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11630#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011631 {"cpu_count", (PyCFunction)posix_cpu_count,
11632 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011633 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__},
11634 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__},
11635#ifdef MS_WINDOWS
11636 {"get_handle_inheritable", posix_get_handle_inheritable,
11637 METH_VARARGS, get_handle_inheritable__doc__},
11638 {"set_handle_inheritable", posix_set_handle_inheritable,
11639 METH_VARARGS, set_handle_inheritable__doc__},
11640#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011641 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011642};
11643
11644
Brian Curtin52173d42010-12-02 18:29:18 +000011645#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011646static int
Brian Curtin52173d42010-12-02 18:29:18 +000011647enable_symlink()
11648{
11649 HANDLE tok;
11650 TOKEN_PRIVILEGES tok_priv;
11651 LUID luid;
11652 int meth_idx = 0;
11653
11654 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011655 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011656
11657 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011658 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011659
11660 tok_priv.PrivilegeCount = 1;
11661 tok_priv.Privileges[0].Luid = luid;
11662 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11663
11664 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11665 sizeof(TOKEN_PRIVILEGES),
11666 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011667 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011668
Brian Curtin3b4499c2010-12-28 14:31:47 +000011669 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11670 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011671}
11672#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11673
Barry Warsaw4a342091996-12-19 23:50:02 +000011674static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011675all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011676{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011677#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011678 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011679#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011680#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011681 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011682#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011683#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011684 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011685#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011686#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011687 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011688#endif
Fred Drakec9680921999-12-13 16:37:25 +000011689#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011690 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011691#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011692#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011693 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011694#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011695#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011696 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011697#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011698#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011699 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011700#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011701#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011702 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011703#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011704#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011705 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011706#endif
11707#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011708 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011709#endif
11710#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011711 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011712#endif
11713#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011714 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011715#endif
11716#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011717 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011718#endif
11719#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011720 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011721#endif
11722#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011723 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011724#endif
11725#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011726 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011727#endif
11728#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011729 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011730#endif
11731#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011732 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011733#endif
11734#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011735 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011736#endif
11737#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011738 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011739#endif
11740#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011741 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011742#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011743#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011744 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011745#endif
11746#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011747 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011748#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011749#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011750 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011751#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011752#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011753 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011754#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011755#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011756 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011757#endif
11758#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011759 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011760#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011761#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011762 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011763#endif
11764#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011765 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011766#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011767#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011768 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011769#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011770#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011771 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011772#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011773#ifdef O_TMPFILE
11774 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11775#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011776#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011777 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011778#endif
11779#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011780 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011781#endif
11782#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011783 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011784#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011785#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011786 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011787#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011788#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011789 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011790#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011791
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011792
Jesus Cea94363612012-06-22 18:32:07 +020011793#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011794 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011795#endif
11796#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011797 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011798#endif
11799
Tim Peters5aa91602002-01-30 05:46:57 +000011800/* MS Windows */
11801#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011802 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011803 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011804#endif
11805#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011806 /* Optimize for short life (keep in memory). */
11807 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011808 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011809#endif
11810#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011811 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011812 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011813#endif
11814#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011815 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011816 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011817#endif
11818#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011819 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011820 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011821#endif
11822
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011823/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011824#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011825 /* Send a SIGIO signal whenever input or output
11826 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011827 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011828#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011829#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011830 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011831 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011832#endif
11833#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011834 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011835 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011836#endif
11837#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011838 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011839 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011840#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011841#ifdef O_NOLINKS
11842 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011843 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011844#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011845#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011846 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011847 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011848#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011849
Victor Stinner8c62be82010-05-06 00:08:46 +000011850 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011851#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011852 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011853#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011854#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011855 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011856#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011857#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011858 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011859#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011860#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011861 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011862#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011863#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011864 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011865#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011866#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011867 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011868#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011869#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011870 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011871#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011872#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011873 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011874#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011875#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011876 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011877#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011878#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011879 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011880#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011881#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011882 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011883#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011884#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011885 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011886#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011887#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011888 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011889#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011890#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011891 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011892#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011893#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011894 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011895#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011896#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011897 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011898#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011899#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011900 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011901#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011902
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011903 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011904#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011905 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011906#endif /* ST_RDONLY */
11907#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011908 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011909#endif /* ST_NOSUID */
11910
doko@ubuntu.comca616a22013-12-08 15:23:07 +010011911 /* GNU extensions */
11912#ifdef ST_NODEV
11913 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
11914#endif /* ST_NODEV */
11915#ifdef ST_NOEXEC
11916 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
11917#endif /* ST_NOEXEC */
11918#ifdef ST_SYNCHRONOUS
11919 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
11920#endif /* ST_SYNCHRONOUS */
11921#ifdef ST_MANDLOCK
11922 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
11923#endif /* ST_MANDLOCK */
11924#ifdef ST_WRITE
11925 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
11926#endif /* ST_WRITE */
11927#ifdef ST_APPEND
11928 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
11929#endif /* ST_APPEND */
11930#ifdef ST_NOATIME
11931 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
11932#endif /* ST_NOATIME */
11933#ifdef ST_NODIRATIME
11934 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
11935#endif /* ST_NODIRATIME */
11936#ifdef ST_RELATIME
11937 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
11938#endif /* ST_RELATIME */
11939
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011940 /* FreeBSD sendfile() constants */
11941#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011942 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011943#endif
11944#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011945 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011946#endif
11947#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011948 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011949#endif
11950
Ross Lagerwall7807c352011-03-17 20:20:30 +020011951 /* constants for posix_fadvise */
11952#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011953 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011954#endif
11955#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011956 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011957#endif
11958#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011959 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011960#endif
11961#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011962 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011963#endif
11964#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011965 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011966#endif
11967#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011968 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011969#endif
11970
11971 /* constants for waitid */
11972#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011973 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11974 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
11975 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011976#endif
11977#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011978 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011979#endif
11980#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011981 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011982#endif
11983#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011984 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011985#endif
11986#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011987 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011988#endif
11989#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011990 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011991#endif
11992#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011993 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011994#endif
11995#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011996 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011997#endif
11998
11999 /* constants for lockf */
12000#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012001 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012002#endif
12003#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012004 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012005#endif
12006#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012007 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012008#endif
12009#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012010 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012011#endif
12012
Guido van Rossum246bc171999-02-01 23:54:31 +000012013#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012014 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12015 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12016 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12017 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12018 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012019#endif
12020
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012021#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012022 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12023 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12024 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012025#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012026 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012027#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012028#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012029 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012030#endif
12031#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012032 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012033#endif
12034#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012035 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012036#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012037#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012038 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012039#endif
12040#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012041 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012042#endif
12043#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012044 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012045#endif
12046#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012047 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012048#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012049#endif
12050
Benjamin Peterson9428d532011-09-14 11:45:52 -040012051#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012052 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12053 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12054 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012055#endif
12056
Victor Stinner8b905bd2011-10-25 13:34:04 +020012057#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012058 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012059#endif
12060#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012061 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012062#endif
12063#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012064 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012065#endif
12066#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012067 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012068#endif
12069#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012070 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012071#endif
12072#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012073 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012074#endif
12075#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012076 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012077#endif
12078
Victor Stinner8c62be82010-05-06 00:08:46 +000012079 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012080}
12081
12082
Tim Peters5aa91602002-01-30 05:46:57 +000012083#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000012084#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012085#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000012086
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000012087#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000012088#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012089#define MODNAME "posix"
12090#endif
12091
Martin v. Löwis1a214512008-06-11 05:26:20 +000012092static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012093 PyModuleDef_HEAD_INIT,
12094 MODNAME,
12095 posix__doc__,
12096 -1,
12097 posix_methods,
12098 NULL,
12099 NULL,
12100 NULL,
12101 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012102};
12103
12104
Larry Hastings9cf065c2012-06-22 16:30:09 -070012105static char *have_functions[] = {
12106
12107#ifdef HAVE_FACCESSAT
12108 "HAVE_FACCESSAT",
12109#endif
12110
12111#ifdef HAVE_FCHDIR
12112 "HAVE_FCHDIR",
12113#endif
12114
12115#ifdef HAVE_FCHMOD
12116 "HAVE_FCHMOD",
12117#endif
12118
12119#ifdef HAVE_FCHMODAT
12120 "HAVE_FCHMODAT",
12121#endif
12122
12123#ifdef HAVE_FCHOWN
12124 "HAVE_FCHOWN",
12125#endif
12126
Larry Hastings00964ed2013-08-12 13:49:30 -040012127#ifdef HAVE_FCHOWNAT
12128 "HAVE_FCHOWNAT",
12129#endif
12130
Larry Hastings9cf065c2012-06-22 16:30:09 -070012131#ifdef HAVE_FEXECVE
12132 "HAVE_FEXECVE",
12133#endif
12134
12135#ifdef HAVE_FDOPENDIR
12136 "HAVE_FDOPENDIR",
12137#endif
12138
Georg Brandl306336b2012-06-24 12:55:33 +020012139#ifdef HAVE_FPATHCONF
12140 "HAVE_FPATHCONF",
12141#endif
12142
Larry Hastings9cf065c2012-06-22 16:30:09 -070012143#ifdef HAVE_FSTATAT
12144 "HAVE_FSTATAT",
12145#endif
12146
12147#ifdef HAVE_FSTATVFS
12148 "HAVE_FSTATVFS",
12149#endif
12150
Georg Brandl306336b2012-06-24 12:55:33 +020012151#ifdef HAVE_FTRUNCATE
12152 "HAVE_FTRUNCATE",
12153#endif
12154
Larry Hastings9cf065c2012-06-22 16:30:09 -070012155#ifdef HAVE_FUTIMENS
12156 "HAVE_FUTIMENS",
12157#endif
12158
12159#ifdef HAVE_FUTIMES
12160 "HAVE_FUTIMES",
12161#endif
12162
12163#ifdef HAVE_FUTIMESAT
12164 "HAVE_FUTIMESAT",
12165#endif
12166
12167#ifdef HAVE_LINKAT
12168 "HAVE_LINKAT",
12169#endif
12170
12171#ifdef HAVE_LCHFLAGS
12172 "HAVE_LCHFLAGS",
12173#endif
12174
12175#ifdef HAVE_LCHMOD
12176 "HAVE_LCHMOD",
12177#endif
12178
12179#ifdef HAVE_LCHOWN
12180 "HAVE_LCHOWN",
12181#endif
12182
12183#ifdef HAVE_LSTAT
12184 "HAVE_LSTAT",
12185#endif
12186
12187#ifdef HAVE_LUTIMES
12188 "HAVE_LUTIMES",
12189#endif
12190
12191#ifdef HAVE_MKDIRAT
12192 "HAVE_MKDIRAT",
12193#endif
12194
12195#ifdef HAVE_MKFIFOAT
12196 "HAVE_MKFIFOAT",
12197#endif
12198
12199#ifdef HAVE_MKNODAT
12200 "HAVE_MKNODAT",
12201#endif
12202
12203#ifdef HAVE_OPENAT
12204 "HAVE_OPENAT",
12205#endif
12206
12207#ifdef HAVE_READLINKAT
12208 "HAVE_READLINKAT",
12209#endif
12210
12211#ifdef HAVE_RENAMEAT
12212 "HAVE_RENAMEAT",
12213#endif
12214
12215#ifdef HAVE_SYMLINKAT
12216 "HAVE_SYMLINKAT",
12217#endif
12218
12219#ifdef HAVE_UNLINKAT
12220 "HAVE_UNLINKAT",
12221#endif
12222
12223#ifdef HAVE_UTIMENSAT
12224 "HAVE_UTIMENSAT",
12225#endif
12226
12227#ifdef MS_WINDOWS
12228 "MS_WINDOWS",
12229#endif
12230
12231 NULL
12232};
12233
12234
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012235PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012236INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012237{
Victor Stinner8c62be82010-05-06 00:08:46 +000012238 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012239 PyObject *list;
12240 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012241
Brian Curtin52173d42010-12-02 18:29:18 +000012242#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012243 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012244#endif
12245
Victor Stinner8c62be82010-05-06 00:08:46 +000012246 m = PyModule_Create(&posixmodule);
12247 if (m == NULL)
12248 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012249
Victor Stinner8c62be82010-05-06 00:08:46 +000012250 /* Initialize environ dictionary */
12251 v = convertenviron();
12252 Py_XINCREF(v);
12253 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12254 return NULL;
12255 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012256
Victor Stinner8c62be82010-05-06 00:08:46 +000012257 if (all_ins(m))
12258 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012259
Victor Stinner8c62be82010-05-06 00:08:46 +000012260 if (setup_confname_tables(m))
12261 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012262
Victor Stinner8c62be82010-05-06 00:08:46 +000012263 Py_INCREF(PyExc_OSError);
12264 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012265
Guido van Rossumb3d39562000-01-31 18:41:26 +000012266#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012267 if (posix_putenv_garbage == NULL)
12268 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012269#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012270
Victor Stinner8c62be82010-05-06 00:08:46 +000012271 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012272#if defined(HAVE_WAITID) && !defined(__APPLE__)
12273 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012274 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12275 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012276#endif
12277
Christian Heimes25827622013-10-12 01:27:08 +020012278 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012279 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12280 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12281 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012282 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12283 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012284 structseq_new = StatResultType.tp_new;
12285 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012286
Christian Heimes25827622013-10-12 01:27:08 +020012287 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012288 if (PyStructSequence_InitType2(&StatVFSResultType,
12289 &statvfs_result_desc) < 0)
12290 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012291#ifdef NEED_TICKS_PER_SECOND
12292# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012293 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012294# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012295 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012296# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012297 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012298# endif
12299#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012300
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012301#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012302 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012303 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12304 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012305 SchedParamType.tp_new = sched_param_new;
12306#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012307
12308 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012309 if (PyStructSequence_InitType2(&TerminalSizeType,
12310 &TerminalSize_desc) < 0)
12311 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012312 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012313#if defined(HAVE_WAITID) && !defined(__APPLE__)
12314 Py_INCREF((PyObject*) &WaitidResultType);
12315 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12316#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012317 Py_INCREF((PyObject*) &StatResultType);
12318 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12319 Py_INCREF((PyObject*) &StatVFSResultType);
12320 PyModule_AddObject(m, "statvfs_result",
12321 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012322
12323#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012324 Py_INCREF(&SchedParamType);
12325 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012326#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012327
Larry Hastings605a62d2012-06-24 04:33:36 -070012328 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012329 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12330 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012331 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12332
12333 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012334 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12335 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012336 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12337
Thomas Wouters477c8d52006-05-27 19:21:47 +000012338#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012339 /*
12340 * Step 2 of weak-linking support on Mac OS X.
12341 *
12342 * The code below removes functions that are not available on the
12343 * currently active platform.
12344 *
12345 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012346 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012347 * OSX 10.4.
12348 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012349#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012350 if (fstatvfs == NULL) {
12351 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12352 return NULL;
12353 }
12354 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012355#endif /* HAVE_FSTATVFS */
12356
12357#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012358 if (statvfs == NULL) {
12359 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12360 return NULL;
12361 }
12362 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012363#endif /* HAVE_STATVFS */
12364
12365# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012366 if (lchown == NULL) {
12367 if (PyObject_DelAttrString(m, "lchown") == -1) {
12368 return NULL;
12369 }
12370 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012371#endif /* HAVE_LCHOWN */
12372
12373
12374#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012375
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012376 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012377 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12378
Larry Hastings6fe20b32012-04-19 15:07:49 -070012379 billion = PyLong_FromLong(1000000000);
12380 if (!billion)
12381 return NULL;
12382
Larry Hastings9cf065c2012-06-22 16:30:09 -070012383 /* suppress "function not used" warnings */
12384 {
12385 int ignored;
12386 fd_specified("", -1);
12387 follow_symlinks_specified("", 1);
12388 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12389 dir_fd_converter(Py_None, &ignored);
12390 dir_fd_unavailable(Py_None, &ignored);
12391 }
12392
12393 /*
12394 * provide list of locally available functions
12395 * so os.py can populate support_* lists
12396 */
12397 list = PyList_New(0);
12398 if (!list)
12399 return NULL;
12400 for (trace = have_functions; *trace; trace++) {
12401 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12402 if (!unicode)
12403 return NULL;
12404 if (PyList_Append(list, unicode))
12405 return NULL;
12406 Py_DECREF(unicode);
12407 }
12408 PyModule_AddObject(m, "_have_functions", list);
12409
12410 initialized = 1;
12411
Victor Stinner8c62be82010-05-06 00:08:46 +000012412 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000012413}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012414
12415#ifdef __cplusplus
12416}
12417#endif