blob: 7c937e055370e7ae2a8193a1d87dd540eb0ed666 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Jesus Ceaab70e2a2012-10-05 01:48:08 +02009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020028#ifndef MS_WINDOWS
29#include "posixmodule.h"
30#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000031
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000032#ifdef __cplusplus
33extern "C" {
34#endif
35
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000036PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000037"This module provides access to operating system functionality that is\n\
38standardized by the C Standard and the POSIX standard (a thinly\n\
39disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000040corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000042
Ross Lagerwall4d076da2011-03-18 06:56:53 +020043#ifdef HAVE_SYS_UIO_H
44#include <sys/uio.h>
45#endif
46
Thomas Wouters0e3f5912006-08-11 14:57:12 +000047#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000048#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049#endif /* HAVE_SYS_TYPES_H */
50
51#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000052#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000053#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000054
Guido van Rossum36bc6801995-06-14 22:54:23 +000055#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000056#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000057#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000058
Thomas Wouters0e3f5912006-08-11 14:57:12 +000059#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000060#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000061#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000062
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#ifdef HAVE_FCNTL_H
64#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000065#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000066
Guido van Rossuma6535fd2001-10-18 19:44:10 +000067#ifdef HAVE_GRP_H
68#include <grp.h>
69#endif
70
Barry Warsaw5676bd12003-01-07 20:57:09 +000071#ifdef HAVE_SYSEXITS_H
72#include <sysexits.h>
73#endif /* HAVE_SYSEXITS_H */
74
Anthony Baxter8a560de2004-10-13 15:30:56 +000075#ifdef HAVE_SYS_LOADAVG_H
76#include <sys/loadavg.h>
77#endif
78
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000079#ifdef HAVE_LANGINFO_H
80#include <langinfo.h>
81#endif
82
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000083#ifdef HAVE_SYS_SENDFILE_H
84#include <sys/sendfile.h>
85#endif
86
Benjamin Peterson94b580d2011-08-02 17:30:04 -050087#ifdef HAVE_SCHED_H
88#include <sched.h>
89#endif
90
Benjamin Peterson2dbda072012-03-16 10:12:55 -050091#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050092#undef HAVE_SCHED_SETAFFINITY
93#endif
94
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +020095#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -040096#define USE_XATTRS
97#endif
98
99#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400100#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400101#endif
102
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000103#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
104#ifdef HAVE_SYS_SOCKET_H
105#include <sys/socket.h>
106#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000107#endif
108
Victor Stinner8b905bd2011-10-25 13:34:04 +0200109#ifdef HAVE_DLFCN_H
110#include <dlfcn.h>
111#endif
112
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200113#ifdef __hpux
114#include <sys/mpctl.h>
115#endif
116
117#if defined(__DragonFly__) || \
118 defined(__OpenBSD__) || \
119 defined(__FreeBSD__) || \
120 defined(__NetBSD__) || \
121 defined(__APPLE__)
122#include <sys/sysctl.h>
123#endif
124
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100125#if defined(MS_WINDOWS)
126# define TERMSIZE_USE_CONIO
127#elif defined(HAVE_SYS_IOCTL_H)
128# include <sys/ioctl.h>
129# if defined(HAVE_TERMIOS_H)
130# include <termios.h>
131# endif
132# if defined(TIOCGWINSZ)
133# define TERMSIZE_USE_IOCTL
134# endif
135#endif /* MS_WINDOWS */
136
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000138/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000139#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000141#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142#include <process.h>
143#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#define HAVE_EXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#define HAVE_OPENDIR 1
147#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000148#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_WAIT 1
150#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000152#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000153#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000154#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#define HAVE_EXECV 1
156#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000157#define HAVE_SYSTEM 1
158#define HAVE_CWAIT 1
159#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000160#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000161#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162/* Unix functions that the configure script doesn't check for */
163#define HAVE_EXECV 1
164#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000166#define HAVE_FORK1 1
167#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#define HAVE_GETEGID 1
169#define HAVE_GETEUID 1
170#define HAVE_GETGID 1
171#define HAVE_GETPPID 1
172#define HAVE_GETUID 1
173#define HAVE_KILL 1
174#define HAVE_OPENDIR 1
175#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000176#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000178#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000179#endif /* _MSC_VER */
180#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000181#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000182
Victor Stinnera2f7c002012-02-08 03:36:25 +0100183
Larry Hastings61272b72014-01-07 12:41:53 -0800184/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800185module os
Larry Hastings61272b72014-01-07 12:41:53 -0800186[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -0800187/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8cff096d1133288f]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100188
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000189#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000190
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000191#if defined(__sgi)&&_COMPILER_VERSION>=700
192/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
193 (default) */
194extern char *ctermid_r(char *);
195#endif
196
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000197#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000198#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000199extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000200#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000201#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000202extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000205#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#endif
207#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int chdir(char *);
209extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000210#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000211extern int chdir(const char *);
212extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000213#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000214#ifdef __BORLANDC__
215extern int chmod(const char *, int);
216#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000218#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000219/*#ifdef HAVE_FCHMOD
220extern int fchmod(int, mode_t);
221#endif*/
222/*#ifdef HAVE_LCHMOD
223extern int lchmod(const char *, mode_t);
224#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int chown(const char *, uid_t, gid_t);
226extern char *getcwd(char *, int);
227extern char *strerror(int);
228extern int link(const char *, const char *);
229extern int rename(const char *, const char *);
230extern int stat(const char *, struct stat *);
231extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000233extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000234#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000236extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000237#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000239
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#ifdef HAVE_UTIME_H
243#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000246#ifdef HAVE_SYS_UTIME_H
247#include <sys/utime.h>
248#define HAVE_UTIME_H /* pretend we do for the rest of this file */
249#endif /* HAVE_SYS_UTIME_H */
250
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#ifdef HAVE_SYS_TIMES_H
252#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
255#ifdef HAVE_SYS_PARAM_H
256#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258
259#ifdef HAVE_SYS_UTSNAME_H
260#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000261#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000263#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000265#define NAMLEN(dirent) strlen((dirent)->d_name)
266#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000267#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000268#include <direct.h>
269#define NAMLEN(dirent) strlen((dirent)->d_name)
270#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000273#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#endif
277#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000279#endif
280#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#endif
283#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000285#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000286#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000288#endif
289#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000291#endif
292#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000295#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000296#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000297#endif
298#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000299#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000300#endif
301#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000302#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000303#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000304#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000305#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000306#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000307#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000308#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000309#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
310#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000311static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000312#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000313#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000314
Tim Petersbc2e10e2002-03-03 23:17:02 +0000315#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000316#if defined(PATH_MAX) && PATH_MAX > 1024
317#define MAXPATHLEN PATH_MAX
318#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000319#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000321#endif /* MAXPATHLEN */
322
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000323#ifdef UNION_WAIT
324/* Emulate some macros on systems that have a union instead of macros */
325
326#ifndef WIFEXITED
327#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
328#endif
329
330#ifndef WEXITSTATUS
331#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
332#endif
333
334#ifndef WTERMSIG
335#define WTERMSIG(u_wait) ((u_wait).w_termsig)
336#endif
337
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000338#define WAIT_TYPE union wait
339#define WAIT_STATUS_INT(s) (s.w_status)
340
341#else /* !UNION_WAIT */
342#define WAIT_TYPE int
343#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000344#endif /* UNION_WAIT */
345
Greg Wardb48bc172000-03-01 21:51:56 +0000346/* Don't use the "_r" form if we don't need it (also, won't have a
347 prototype for it, at least on Solaris -- maybe others as well?). */
348#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
349#define USE_CTERMID_R
350#endif
351
Fred Drake699f3522000-06-29 21:12:41 +0000352/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000353#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000354#undef FSTAT
355#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200356#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000357# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700358# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000359# define FSTAT win32_fstat
360# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000361#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000362# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700363# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000364# define FSTAT fstat
365# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000366#endif
367
Tim Peters11b23062003-04-23 02:39:17 +0000368#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000369#include <sys/mkdev.h>
370#else
371#if defined(MAJOR_IN_SYSMACROS)
372#include <sys/sysmacros.h>
373#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000374#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
375#include <sys/mkdev.h>
376#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000377#endif
Fred Drake699f3522000-06-29 21:12:41 +0000378
Victor Stinner6edddfa2013-11-24 19:22:57 +0100379#define DWORD_MAX 4294967295U
380
Larry Hastings9cf065c2012-06-22 16:30:09 -0700381
382#ifdef MS_WINDOWS
383static int
384win32_warn_bytes_api()
385{
386 return PyErr_WarnEx(PyExc_DeprecationWarning,
387 "The Windows bytes API has been deprecated, "
388 "use Unicode filenames instead",
389 1);
390}
391#endif
392
393
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200394#ifndef MS_WINDOWS
395PyObject *
396_PyLong_FromUid(uid_t uid)
397{
398 if (uid == (uid_t)-1)
399 return PyLong_FromLong(-1);
400 return PyLong_FromUnsignedLong(uid);
401}
402
403PyObject *
404_PyLong_FromGid(gid_t gid)
405{
406 if (gid == (gid_t)-1)
407 return PyLong_FromLong(-1);
408 return PyLong_FromUnsignedLong(gid);
409}
410
411int
412_Py_Uid_Converter(PyObject *obj, void *p)
413{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700414 uid_t uid;
415 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200416 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200417 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700418 unsigned long uresult;
419
420 index = PyNumber_Index(obj);
421 if (index == NULL) {
422 PyErr_Format(PyExc_TypeError,
423 "uid should be integer, not %.200s",
424 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200425 return 0;
426 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700427
428 /*
429 * Handling uid_t is complicated for two reasons:
430 * * Although uid_t is (always?) unsigned, it still
431 * accepts -1.
432 * * We don't know its size in advance--it may be
433 * bigger than an int, or it may be smaller than
434 * a long.
435 *
436 * So a bit of defensive programming is in order.
437 * Start with interpreting the value passed
438 * in as a signed long and see if it works.
439 */
440
441 result = PyLong_AsLongAndOverflow(index, &overflow);
442
443 if (!overflow) {
444 uid = (uid_t)result;
445
446 if (result == -1) {
447 if (PyErr_Occurred())
448 goto fail;
449 /* It's a legitimate -1, we're done. */
450 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200451 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700452
453 /* Any other negative number is disallowed. */
454 if (result < 0)
455 goto underflow;
456
457 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200458 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700459 (long)uid != result)
460 goto underflow;
461 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200462 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700463
464 if (overflow < 0)
465 goto underflow;
466
467 /*
468 * Okay, the value overflowed a signed long. If it
469 * fits in an *unsigned* long, it may still be okay,
470 * as uid_t may be unsigned long on this platform.
471 */
472 uresult = PyLong_AsUnsignedLong(index);
473 if (PyErr_Occurred()) {
474 if (PyErr_ExceptionMatches(PyExc_OverflowError))
475 goto overflow;
476 goto fail;
477 }
478
479 uid = (uid_t)uresult;
480
481 /*
482 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
483 * but this value would get interpreted as (uid_t)-1 by chown
484 * and its siblings. That's not what the user meant! So we
485 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100486 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700487 */
488 if (uid == (uid_t)-1)
489 goto overflow;
490
491 /* Ensure the value wasn't truncated. */
492 if (sizeof(uid_t) < sizeof(long) &&
493 (unsigned long)uid != uresult)
494 goto overflow;
495 /* fallthrough */
496
497success:
498 Py_DECREF(index);
499 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200500 return 1;
501
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700502underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200503 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700504 "uid is less than minimum");
505 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200506
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700507overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200508 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700509 "uid is greater than maximum");
510 /* fallthrough */
511
512fail:
513 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200514 return 0;
515}
516
517int
518_Py_Gid_Converter(PyObject *obj, void *p)
519{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700520 gid_t gid;
521 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200522 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200523 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524 unsigned long uresult;
525
526 index = PyNumber_Index(obj);
527 if (index == NULL) {
528 PyErr_Format(PyExc_TypeError,
529 "gid should be integer, not %.200s",
530 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200531 return 0;
532 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533
534 /*
535 * Handling gid_t is complicated for two reasons:
536 * * Although gid_t is (always?) unsigned, it still
537 * accepts -1.
538 * * We don't know its size in advance--it may be
539 * bigger than an int, or it may be smaller than
540 * a long.
541 *
542 * So a bit of defensive programming is in order.
543 * Start with interpreting the value passed
544 * in as a signed long and see if it works.
545 */
546
547 result = PyLong_AsLongAndOverflow(index, &overflow);
548
549 if (!overflow) {
550 gid = (gid_t)result;
551
552 if (result == -1) {
553 if (PyErr_Occurred())
554 goto fail;
555 /* It's a legitimate -1, we're done. */
556 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200557 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700558
559 /* Any other negative number is disallowed. */
560 if (result < 0) {
561 goto underflow;
562 }
563
564 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200565 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700566 (long)gid != result)
567 goto underflow;
568 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200569 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700570
571 if (overflow < 0)
572 goto underflow;
573
574 /*
575 * Okay, the value overflowed a signed long. If it
576 * fits in an *unsigned* long, it may still be okay,
577 * as gid_t may be unsigned long on this platform.
578 */
579 uresult = PyLong_AsUnsignedLong(index);
580 if (PyErr_Occurred()) {
581 if (PyErr_ExceptionMatches(PyExc_OverflowError))
582 goto overflow;
583 goto fail;
584 }
585
586 gid = (gid_t)uresult;
587
588 /*
589 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
590 * but this value would get interpreted as (gid_t)-1 by chown
591 * and its siblings. That's not what the user meant! So we
592 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100593 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700594 */
595 if (gid == (gid_t)-1)
596 goto overflow;
597
598 /* Ensure the value wasn't truncated. */
599 if (sizeof(gid_t) < sizeof(long) &&
600 (unsigned long)gid != uresult)
601 goto overflow;
602 /* fallthrough */
603
604success:
605 Py_DECREF(index);
606 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200607 return 1;
608
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700609underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200610 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700611 "gid is less than minimum");
612 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200613
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700614overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200615 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616 "gid is greater than maximum");
617 /* fallthrough */
618
619fail:
620 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200621 return 0;
622}
623#endif /* MS_WINDOWS */
624
625
Gregory P. Smith702dada2015-01-28 16:07:52 -0800626#ifdef HAVE_LONG_LONG
627# define _PyLong_FromDev PyLong_FromLongLong
628#else
629# define _PyLong_FromDev PyLong_FromLong
630#endif
631
632
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200633#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
634static int
635_Py_Dev_Converter(PyObject *obj, void *p)
636{
637#ifdef HAVE_LONG_LONG
638 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
639#else
640 *((dev_t *)p) = PyLong_AsUnsignedLong(obj);
641#endif
642 if (PyErr_Occurred())
643 return 0;
644 return 1;
645}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800646#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200647
648
Larry Hastings9cf065c2012-06-22 16:30:09 -0700649#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400650/*
651 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
652 * without the int cast, the value gets interpreted as uint (4291925331),
653 * which doesn't play nicely with all the initializer lines in this file that
654 * look like this:
655 * int dir_fd = DEFAULT_DIR_FD;
656 */
657#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700658#else
659#define DEFAULT_DIR_FD (-100)
660#endif
661
662static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200663_fd_converter(PyObject *o, int *p, const char *allowed)
664{
665 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700666 long long_value;
667
668 PyObject *index = PyNumber_Index(o);
669 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200670 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700671 "argument should be %s, not %.200s",
672 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700673 return 0;
674 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700675
676 long_value = PyLong_AsLongAndOverflow(index, &overflow);
677 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200678 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700679 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700681 return 0;
682 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200683 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700684 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700685 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700686 return 0;
687 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700688
Larry Hastings9cf065c2012-06-22 16:30:09 -0700689 *p = (int)long_value;
690 return 1;
691}
692
693static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200694dir_fd_converter(PyObject *o, void *p)
695{
696 if (o == Py_None) {
697 *(int *)p = DEFAULT_DIR_FD;
698 return 1;
699 }
700 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700701}
702
703
704
705/*
706 * A PyArg_ParseTuple "converter" function
707 * that handles filesystem paths in the manner
708 * preferred by the os module.
709 *
710 * path_converter accepts (Unicode) strings and their
711 * subclasses, and bytes and their subclasses. What
712 * it does with the argument depends on the platform:
713 *
714 * * On Windows, if we get a (Unicode) string we
715 * extract the wchar_t * and return it; if we get
716 * bytes we extract the char * and return that.
717 *
718 * * On all other platforms, strings are encoded
719 * to bytes using PyUnicode_FSConverter, then we
720 * extract the char * from the bytes object and
721 * return that.
722 *
723 * path_converter also optionally accepts signed
724 * integers (representing open file descriptors) instead
725 * of path strings.
726 *
727 * Input fields:
728 * path.nullable
729 * If nonzero, the path is permitted to be None.
730 * path.allow_fd
731 * If nonzero, the path is permitted to be a file handle
732 * (a signed int) instead of a string.
733 * path.function_name
734 * If non-NULL, path_converter will use that as the name
735 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700736 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700737 * path.argument_name
738 * If non-NULL, path_converter will use that as the name
739 * of the parameter in error messages.
740 * (If path.argument_name is NULL it uses "path".)
741 *
742 * Output fields:
743 * path.wide
744 * Points to the path if it was expressed as Unicode
745 * and was not encoded. (Only used on Windows.)
746 * path.narrow
747 * Points to the path if it was expressed as bytes,
748 * or it was Unicode and was encoded to bytes.
749 * path.fd
750 * Contains a file descriptor if path.accept_fd was true
751 * and the caller provided a signed integer instead of any
752 * sort of string.
753 *
754 * WARNING: if your "path" parameter is optional, and is
755 * unspecified, path_converter will never get called.
756 * So if you set allow_fd, you *MUST* initialize path.fd = -1
757 * yourself!
758 * path.length
759 * The length of the path in characters, if specified as
760 * a string.
761 * path.object
762 * The original object passed in.
763 * path.cleanup
764 * For internal use only. May point to a temporary object.
765 * (Pay no attention to the man behind the curtain.)
766 *
767 * At most one of path.wide or path.narrow will be non-NULL.
768 * If path was None and path.nullable was set,
769 * or if path was an integer and path.allow_fd was set,
770 * both path.wide and path.narrow will be NULL
771 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200772 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700773 * path_converter takes care to not write to the path_t
774 * unless it's successful. However it must reset the
775 * "cleanup" field each time it's called.
776 *
777 * Use as follows:
778 * path_t path;
779 * memset(&path, 0, sizeof(path));
780 * PyArg_ParseTuple(args, "O&", path_converter, &path);
781 * // ... use values from path ...
782 * path_cleanup(&path);
783 *
784 * (Note that if PyArg_Parse fails you don't need to call
785 * path_cleanup(). However it is safe to do so.)
786 */
787typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100788 const char *function_name;
789 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700790 int nullable;
791 int allow_fd;
792 wchar_t *wide;
793 char *narrow;
794 int fd;
795 Py_ssize_t length;
796 PyObject *object;
797 PyObject *cleanup;
798} path_t;
799
Larry Hastings31826802013-10-19 00:09:25 -0700800#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \
801 {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL}
802
Larry Hastings9cf065c2012-06-22 16:30:09 -0700803static void
804path_cleanup(path_t *path) {
805 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200806 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700807 }
808}
809
810static int
811path_converter(PyObject *o, void *p) {
812 path_t *path = (path_t *)p;
813 PyObject *unicode, *bytes;
814 Py_ssize_t length;
815 char *narrow;
816
817#define FORMAT_EXCEPTION(exc, fmt) \
818 PyErr_Format(exc, "%s%s" fmt, \
819 path->function_name ? path->function_name : "", \
820 path->function_name ? ": " : "", \
821 path->argument_name ? path->argument_name : "path")
822
823 /* Py_CLEANUP_SUPPORTED support */
824 if (o == NULL) {
825 path_cleanup(path);
826 return 1;
827 }
828
829 /* ensure it's always safe to call path_cleanup() */
830 path->cleanup = NULL;
831
832 if (o == Py_None) {
833 if (!path->nullable) {
834 FORMAT_EXCEPTION(PyExc_TypeError,
835 "can't specify None for %s argument");
836 return 0;
837 }
838 path->wide = NULL;
839 path->narrow = NULL;
840 path->length = 0;
841 path->object = o;
842 path->fd = -1;
843 return 1;
844 }
845
846 unicode = PyUnicode_FromObject(o);
847 if (unicode) {
848#ifdef MS_WINDOWS
849 wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100850
851 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
852 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700853 Py_DECREF(unicode);
854 return 0;
855 }
Victor Stinner59799a82013-11-13 14:17:30 +0100856 if (length > 32767) {
857 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700858 Py_DECREF(unicode);
859 return 0;
860 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300861 if (wcslen(wide) != length) {
862 FORMAT_EXCEPTION(PyExc_TypeError, "embedded null character");
863 Py_DECREF(unicode);
864 return 0;
865 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700866
867 path->wide = wide;
868 path->narrow = NULL;
869 path->length = length;
870 path->object = o;
871 path->fd = -1;
872 path->cleanup = unicode;
873 return Py_CLEANUP_SUPPORTED;
874#else
875 int converted = PyUnicode_FSConverter(unicode, &bytes);
876 Py_DECREF(unicode);
877 if (!converted)
878 bytes = NULL;
879#endif
880 }
881 else {
882 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200883 if (PyObject_CheckBuffer(o))
884 bytes = PyBytes_FromObject(o);
885 else
886 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700887 if (!bytes) {
888 PyErr_Clear();
889 if (path->allow_fd) {
890 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200891 int result = _fd_converter(o, &fd,
892 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700893 if (result) {
894 path->wide = NULL;
895 path->narrow = NULL;
896 path->length = 0;
897 path->object = o;
898 path->fd = fd;
899 return result;
900 }
901 }
902 }
903 }
904
905 if (!bytes) {
906 if (!PyErr_Occurred())
907 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
908 return 0;
909 }
910
911#ifdef MS_WINDOWS
912 if (win32_warn_bytes_api()) {
913 Py_DECREF(bytes);
914 return 0;
915 }
916#endif
917
918 length = PyBytes_GET_SIZE(bytes);
919#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100920 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700921 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
922 Py_DECREF(bytes);
923 return 0;
924 }
925#endif
926
927 narrow = PyBytes_AS_STRING(bytes);
928 if (length != strlen(narrow)) {
929 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
930 Py_DECREF(bytes);
931 return 0;
932 }
933
934 path->wide = NULL;
935 path->narrow = narrow;
936 path->length = length;
937 path->object = o;
938 path->fd = -1;
939 path->cleanup = bytes;
940 return Py_CLEANUP_SUPPORTED;
941}
942
943static void
944argument_unavailable_error(char *function_name, char *argument_name) {
945 PyErr_Format(PyExc_NotImplementedError,
946 "%s%s%s unavailable on this platform",
947 (function_name != NULL) ? function_name : "",
948 (function_name != NULL) ? ": ": "",
949 argument_name);
950}
951
952static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200953dir_fd_unavailable(PyObject *o, void *p)
954{
955 int dir_fd;
956 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700957 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200958 if (dir_fd != DEFAULT_DIR_FD) {
959 argument_unavailable_error(NULL, "dir_fd");
960 return 0;
961 }
962 *(int *)p = dir_fd;
963 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700964}
965
966static int
967fd_specified(char *function_name, int fd) {
968 if (fd == -1)
969 return 0;
970
971 argument_unavailable_error(function_name, "fd");
972 return 1;
973}
974
975static int
976follow_symlinks_specified(char *function_name, int follow_symlinks) {
977 if (follow_symlinks)
978 return 0;
979
980 argument_unavailable_error(function_name, "follow_symlinks");
981 return 1;
982}
983
984static int
985path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
986 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
987 PyErr_Format(PyExc_ValueError,
988 "%s: can't specify dir_fd without matching path",
989 function_name);
990 return 1;
991 }
992 return 0;
993}
994
995static int
996dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
997 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
998 PyErr_Format(PyExc_ValueError,
999 "%s: can't specify both dir_fd and fd",
1000 function_name);
1001 return 1;
1002 }
1003 return 0;
1004}
1005
1006static int
1007fd_and_follow_symlinks_invalid(char *function_name, int fd,
1008 int follow_symlinks) {
1009 if ((fd > 0) && (!follow_symlinks)) {
1010 PyErr_Format(PyExc_ValueError,
1011 "%s: cannot use fd and follow_symlinks together",
1012 function_name);
1013 return 1;
1014 }
1015 return 0;
1016}
1017
1018static int
1019dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
1020 int follow_symlinks) {
1021 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1022 PyErr_Format(PyExc_ValueError,
1023 "%s: cannot use dir_fd and follow_symlinks together",
1024 function_name);
1025 return 1;
1026 }
1027 return 0;
1028}
1029
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001030/* A helper used by a number of POSIX-only functions */
1031#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +00001032static int
1033_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001034{
1035#if !defined(HAVE_LARGEFILE_SUPPORT)
1036 *((off_t*)addr) = PyLong_AsLong(arg);
1037#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +00001038 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001039#endif
1040 if (PyErr_Occurred())
1041 return 0;
1042 return 1;
1043}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001044#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001045
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001046#if defined _MSC_VER && _MSC_VER >= 1400
1047/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +02001048 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001049 * Normally, an invalid fd is likely to be a C program error and therefore
1050 * an assertion can be useful, but it does contradict the POSIX standard
1051 * which for write(2) states:
1052 * "Otherwise, -1 shall be returned and errno set to indicate the error."
1053 * "[EBADF] The fildes argument is not a valid file descriptor open for
1054 * writing."
1055 * Furthermore, python allows the user to enter any old integer
1056 * as a fd and should merely raise a python exception on error.
1057 * The Microsoft CRT doesn't provide an official way to check for the
1058 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +00001059 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001060 * internal structures involved.
1061 * The structures below must be updated for each version of visual studio
1062 * according to the file internal.h in the CRT source, until MS comes
1063 * up with a less hacky way to do this.
1064 * (all of this is to avoid globally modifying the CRT behaviour using
1065 * _set_invalid_parameter_handler() and _CrtSetReportMode())
1066 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001067/* The actual size of the structure is determined at runtime.
1068 * Only the first items must be present.
1069 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001070typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +00001071 intptr_t osfhnd;
1072 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001073} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001074
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001075extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001076#define IOINFO_L2E 5
1077#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
1078#define IOINFO_ARRAYS 64
1079#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
1080#define FOPEN 0x01
1081#define _NO_CONSOLE_FILENO (intptr_t)-2
1082
1083/* This function emulates what the windows CRT does to validate file handles */
1084int
1085_PyVerify_fd(int fd)
1086{
Victor Stinner8c62be82010-05-06 00:08:46 +00001087 const int i1 = fd >> IOINFO_L2E;
1088 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001089
Antoine Pitrou22e41552010-08-15 18:07:50 +00001090 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001091
Victor Stinner8c62be82010-05-06 00:08:46 +00001092 /* Determine the actual size of the ioinfo structure,
1093 * as used by the CRT loaded in memory
1094 */
1095 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
1096 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
1097 }
1098 if (sizeof_ioinfo == 0) {
1099 /* This should not happen... */
1100 goto fail;
1101 }
1102
1103 /* See that it isn't a special CLEAR fileno */
1104 if (fd != _NO_CONSOLE_FILENO) {
1105 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
1106 * we check pointer validity and other info
1107 */
1108 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
1109 /* finally, check that the file is open */
1110 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
1111 if (info->osfile & FOPEN) {
1112 return 1;
1113 }
1114 }
1115 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001116 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001117 errno = EBADF;
1118 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001119}
1120
1121/* the special case of checking dup2. The target fd must be in a sensible range */
1122static int
1123_PyVerify_fd_dup2(int fd1, int fd2)
1124{
Victor Stinner8c62be82010-05-06 00:08:46 +00001125 if (!_PyVerify_fd(fd1))
1126 return 0;
1127 if (fd2 == _NO_CONSOLE_FILENO)
1128 return 0;
1129 if ((unsigned)fd2 < _NHANDLE_)
1130 return 1;
1131 else
1132 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001133}
1134#else
1135/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1136#define _PyVerify_fd_dup2(A, B) (1)
1137#endif
1138
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001139#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001140/* The following structure was copied from
1141 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1142 include doesn't seem to be present in the Windows SDK (at least as included
1143 with Visual Studio Express). */
1144typedef struct _REPARSE_DATA_BUFFER {
1145 ULONG ReparseTag;
1146 USHORT ReparseDataLength;
1147 USHORT Reserved;
1148 union {
1149 struct {
1150 USHORT SubstituteNameOffset;
1151 USHORT SubstituteNameLength;
1152 USHORT PrintNameOffset;
1153 USHORT PrintNameLength;
1154 ULONG Flags;
1155 WCHAR PathBuffer[1];
1156 } SymbolicLinkReparseBuffer;
1157
1158 struct {
1159 USHORT SubstituteNameOffset;
1160 USHORT SubstituteNameLength;
1161 USHORT PrintNameOffset;
1162 USHORT PrintNameLength;
1163 WCHAR PathBuffer[1];
1164 } MountPointReparseBuffer;
1165
1166 struct {
1167 UCHAR DataBuffer[1];
1168 } GenericReparseBuffer;
1169 };
1170} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1171
1172#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1173 GenericReparseBuffer)
1174#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1175
1176static int
Brian Curtind25aef52011-06-13 15:16:04 -05001177win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001178{
1179 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1180 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1181 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001182
1183 if (0 == DeviceIoControl(
1184 reparse_point_handle,
1185 FSCTL_GET_REPARSE_POINT,
1186 NULL, 0, /* in buffer */
1187 target_buffer, sizeof(target_buffer),
1188 &n_bytes_returned,
1189 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001190 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001191
1192 if (reparse_tag)
1193 *reparse_tag = rdb->ReparseTag;
1194
Brian Curtind25aef52011-06-13 15:16:04 -05001195 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001196}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001197
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001198#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001199
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001200/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001201#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001202/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001203** environ directly, we must obtain it with _NSGetEnviron(). See also
1204** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001205*/
1206#include <crt_externs.h>
1207static char **environ;
1208#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001209extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001210#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211
Barry Warsaw53699e91996-12-10 23:23:01 +00001212static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001213convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001214{
Victor Stinner8c62be82010-05-06 00:08:46 +00001215 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001216#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001217 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001218#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001219 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001220#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001221
Victor Stinner8c62be82010-05-06 00:08:46 +00001222 d = PyDict_New();
1223 if (d == NULL)
1224 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001225#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001226 if (environ == NULL)
1227 environ = *_NSGetEnviron();
1228#endif
1229#ifdef MS_WINDOWS
1230 /* _wenviron must be initialized in this way if the program is started
1231 through main() instead of wmain(). */
1232 _wgetenv(L"");
1233 if (_wenviron == NULL)
1234 return d;
1235 /* This part ignores errors */
1236 for (e = _wenviron; *e != NULL; e++) {
1237 PyObject *k;
1238 PyObject *v;
1239 wchar_t *p = wcschr(*e, L'=');
1240 if (p == NULL)
1241 continue;
1242 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1243 if (k == NULL) {
1244 PyErr_Clear();
1245 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001246 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001247 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1248 if (v == NULL) {
1249 PyErr_Clear();
1250 Py_DECREF(k);
1251 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001252 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001253 if (PyDict_GetItem(d, k) == NULL) {
1254 if (PyDict_SetItem(d, k, v) != 0)
1255 PyErr_Clear();
1256 }
1257 Py_DECREF(k);
1258 Py_DECREF(v);
1259 }
1260#else
1261 if (environ == NULL)
1262 return d;
1263 /* This part ignores errors */
1264 for (e = environ; *e != NULL; e++) {
1265 PyObject *k;
1266 PyObject *v;
1267 char *p = strchr(*e, '=');
1268 if (p == NULL)
1269 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001270 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001271 if (k == NULL) {
1272 PyErr_Clear();
1273 continue;
1274 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001275 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001276 if (v == NULL) {
1277 PyErr_Clear();
1278 Py_DECREF(k);
1279 continue;
1280 }
1281 if (PyDict_GetItem(d, k) == NULL) {
1282 if (PyDict_SetItem(d, k, v) != 0)
1283 PyErr_Clear();
1284 }
1285 Py_DECREF(k);
1286 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001287 }
1288#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001289 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001290}
1291
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001292/* Set a POSIX-specific error from errno, and return NULL */
1293
Barry Warsawd58d7641998-07-23 16:14:40 +00001294static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001295posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001296{
Victor Stinner8c62be82010-05-06 00:08:46 +00001297 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001298}
Mark Hammondef8b6542001-05-13 08:04:26 +00001299
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001300#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001301static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001302win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001303{
Victor Stinner8c62be82010-05-06 00:08:46 +00001304 /* XXX We should pass the function name along in the future.
1305 (winreg.c also wants to pass the function name.)
1306 This would however require an additional param to the
1307 Windows error object, which is non-trivial.
1308 */
1309 errno = GetLastError();
1310 if (filename)
1311 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1312 else
1313 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001314}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001315
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001316static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001317win32_error_object(char* function, PyObject* filename)
1318{
1319 /* XXX - see win32_error for comments on 'function' */
1320 errno = GetLastError();
1321 if (filename)
1322 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001323 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001324 errno,
1325 filename);
1326 else
1327 return PyErr_SetFromWindowsErr(errno);
1328}
1329
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001330#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331
Larry Hastings9cf065c2012-06-22 16:30:09 -07001332static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001333path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001334{
1335#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001336 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1337 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001338#else
Victor Stinner292c8352012-10-30 02:17:38 +01001339 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001340#endif
1341}
1342
Larry Hastings31826802013-10-19 00:09:25 -07001343
Larry Hastingsb0827312014-02-09 22:05:19 -08001344static PyObject *
1345path_error2(path_t *path, path_t *path2)
1346{
1347#ifdef MS_WINDOWS
1348 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1349 0, path->object, path2->object);
1350#else
1351 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1352 path->object, path2->object);
1353#endif
1354}
1355
1356
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001357/* POSIX generic methods */
1358
Barry Warsaw53699e91996-12-10 23:23:01 +00001359static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001360posix_fildes(PyObject *fdobj, int (*func)(int))
1361{
Victor Stinner8c62be82010-05-06 00:08:46 +00001362 int fd;
1363 int res;
1364 fd = PyObject_AsFileDescriptor(fdobj);
1365 if (fd < 0)
1366 return NULL;
1367 if (!_PyVerify_fd(fd))
1368 return posix_error();
1369 Py_BEGIN_ALLOW_THREADS
1370 res = (*func)(fd);
1371 Py_END_ALLOW_THREADS
1372 if (res < 0)
1373 return posix_error();
1374 Py_INCREF(Py_None);
1375 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001376}
Guido van Rossum21142a01999-01-08 21:05:37 +00001377
1378static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001379posix_1str(const char *func_name, PyObject *args, char *format,
1380 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001381{
Victor Stinner292c8352012-10-30 02:17:38 +01001382 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001383 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001384 memset(&path, 0, sizeof(path));
1385 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001386 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001387 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001388 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001389 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001390 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001391 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001392 if (res < 0) {
1393 path_error(&path);
1394 path_cleanup(&path);
1395 return NULL;
1396 }
1397 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001398 Py_INCREF(Py_None);
1399 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001400}
1401
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001402
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001403#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001404/* This is a reimplementation of the C library's chdir function,
1405 but one that produces Win32 errors instead of DOS error codes.
1406 chdir is essentially a wrapper around SetCurrentDirectory; however,
1407 it also needs to set "magic" environment variables indicating
1408 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001409static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001410win32_chdir(LPCSTR path)
1411{
Victor Stinner75875072013-11-24 19:23:25 +01001412 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 int result;
1414 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001415
Victor Stinner8c62be82010-05-06 00:08:46 +00001416 if(!SetCurrentDirectoryA(path))
1417 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001418 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001419 if (!result)
1420 return FALSE;
1421 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001422 than MAX_PATH-1 (not including the final null character). */
1423 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001424 if (strncmp(new_path, "\\\\", 2) == 0 ||
1425 strncmp(new_path, "//", 2) == 0)
1426 /* UNC path, nothing to do. */
1427 return TRUE;
1428 env[1] = new_path[0];
1429 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001430}
1431
1432/* The Unicode version differs from the ANSI version
1433 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001434static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001435win32_wchdir(LPCWSTR path)
1436{
Victor Stinner75875072013-11-24 19:23:25 +01001437 wchar_t _new_path[MAX_PATH], *new_path = _new_path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001438 int result;
1439 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001440
Victor Stinner8c62be82010-05-06 00:08:46 +00001441 if(!SetCurrentDirectoryW(path))
1442 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001443 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001444 if (!result)
1445 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001446 if (result > Py_ARRAY_LENGTH(new_path)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001447 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001448 if (!new_path) {
1449 SetLastError(ERROR_OUTOFMEMORY);
1450 return FALSE;
1451 }
1452 result = GetCurrentDirectoryW(result, new_path);
1453 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001454 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001455 return FALSE;
1456 }
1457 }
1458 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1459 wcsncmp(new_path, L"//", 2) == 0)
1460 /* UNC path, nothing to do. */
1461 return TRUE;
1462 env[1] = new_path[0];
1463 result = SetEnvironmentVariableW(env, new_path);
1464 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001465 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001466 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001467}
1468#endif
1469
Martin v. Löwis14694662006-02-03 12:54:16 +00001470#ifdef MS_WINDOWS
1471/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1472 - time stamps are restricted to second resolution
1473 - file modification times suffer from forth-and-back conversions between
1474 UTC and local time
1475 Therefore, we implement our own stat, based on the Win32 API directly.
1476*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001477#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001478
1479struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001480 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001481 __int64 st_ino;
1482 unsigned short st_mode;
1483 int st_nlink;
1484 int st_uid;
1485 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001486 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001487 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001488 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001489 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001490 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001491 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001492 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001493 int st_ctime_nsec;
1494};
1495
1496static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1497
1498static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001499FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001500{
Victor Stinner8c62be82010-05-06 00:08:46 +00001501 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1502 /* Cannot simply cast and dereference in_ptr,
1503 since it might not be aligned properly */
1504 __int64 in;
1505 memcpy(&in, in_ptr, sizeof(in));
1506 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001507 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001508}
1509
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001511time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001512{
Victor Stinner8c62be82010-05-06 00:08:46 +00001513 /* XXX endianness */
1514 __int64 out;
1515 out = time_in + secs_between_epochs;
1516 out = out * 10000000 + nsec_in / 100;
1517 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001518}
1519
Martin v. Löwis14694662006-02-03 12:54:16 +00001520/* Below, we *know* that ugo+r is 0444 */
1521#if _S_IREAD != 0400
1522#error Unsupported C library
1523#endif
1524static int
1525attributes_to_mode(DWORD attr)
1526{
Victor Stinner8c62be82010-05-06 00:08:46 +00001527 int m = 0;
1528 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1529 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1530 else
1531 m |= _S_IFREG;
1532 if (attr & FILE_ATTRIBUTE_READONLY)
1533 m |= 0444;
1534 else
1535 m |= 0666;
1536 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001537}
1538
1539static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001540attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001541{
Victor Stinner8c62be82010-05-06 00:08:46 +00001542 memset(result, 0, sizeof(*result));
1543 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1544 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001545 result->st_dev = info->dwVolumeSerialNumber;
1546 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1548 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1549 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001550 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001551 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001552 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1553 /* first clear the S_IFMT bits */
Christian Heimes99d61352013-06-23 23:56:05 +02001554 result->st_mode ^= (result->st_mode & S_IFMT);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001555 /* now set the bits that make this a symlink */
Christian Heimes99d61352013-06-23 23:56:05 +02001556 result->st_mode |= S_IFLNK;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001557 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001558
Victor Stinner8c62be82010-05-06 00:08:46 +00001559 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001560}
1561
Guido van Rossumd8faa362007-04-27 19:54:29 +00001562static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001563attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001564{
Victor Stinner8c62be82010-05-06 00:08:46 +00001565 HANDLE hFindFile;
1566 WIN32_FIND_DATAA FileData;
1567 hFindFile = FindFirstFileA(pszFile, &FileData);
1568 if (hFindFile == INVALID_HANDLE_VALUE)
1569 return FALSE;
1570 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001571 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001572 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001573 info->dwFileAttributes = FileData.dwFileAttributes;
1574 info->ftCreationTime = FileData.ftCreationTime;
1575 info->ftLastAccessTime = FileData.ftLastAccessTime;
1576 info->ftLastWriteTime = FileData.ftLastWriteTime;
1577 info->nFileSizeHigh = FileData.nFileSizeHigh;
1578 info->nFileSizeLow = FileData.nFileSizeLow;
1579/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001580 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1581 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001582 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001583}
1584
1585static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001586attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001587{
Victor Stinner8c62be82010-05-06 00:08:46 +00001588 HANDLE hFindFile;
1589 WIN32_FIND_DATAW FileData;
1590 hFindFile = FindFirstFileW(pszFile, &FileData);
1591 if (hFindFile == INVALID_HANDLE_VALUE)
1592 return FALSE;
1593 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001594 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001595 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001596 info->dwFileAttributes = FileData.dwFileAttributes;
1597 info->ftCreationTime = FileData.ftCreationTime;
1598 info->ftLastAccessTime = FileData.ftLastAccessTime;
1599 info->ftLastWriteTime = FileData.ftLastWriteTime;
1600 info->nFileSizeHigh = FileData.nFileSizeHigh;
1601 info->nFileSizeLow = FileData.nFileSizeLow;
1602/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001603 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1604 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001605 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001606}
1607
Brian Curtind25aef52011-06-13 15:16:04 -05001608/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001609static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001610static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1611 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001612static int
Brian Curtind25aef52011-06-13 15:16:04 -05001613check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001614{
Brian Curtind25aef52011-06-13 15:16:04 -05001615 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001616 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1617 DWORD);
1618
Brian Curtind25aef52011-06-13 15:16:04 -05001619 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001620 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001621 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001622 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001623 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1624 "GetFinalPathNameByHandleA");
1625 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1626 "GetFinalPathNameByHandleW");
1627 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1628 Py_GetFinalPathNameByHandleW;
1629 }
1630 return has_GetFinalPathNameByHandle;
1631}
1632
1633static BOOL
1634get_target_path(HANDLE hdl, wchar_t **target_path)
1635{
1636 int buf_size, result_length;
1637 wchar_t *buf;
1638
1639 /* We have a good handle to the target, use it to determine
1640 the target path name (then we'll call lstat on it). */
1641 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1642 VOLUME_NAME_DOS);
1643 if(!buf_size)
1644 return FALSE;
1645
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02001646 buf = PyMem_New(wchar_t, buf_size+1);
Brian Curtinc8be8402011-06-14 09:52:50 -05001647 if (!buf) {
1648 SetLastError(ERROR_OUTOFMEMORY);
1649 return FALSE;
1650 }
1651
Brian Curtind25aef52011-06-13 15:16:04 -05001652 result_length = Py_GetFinalPathNameByHandleW(hdl,
1653 buf, buf_size, VOLUME_NAME_DOS);
1654
1655 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001656 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001657 return FALSE;
1658 }
1659
1660 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001661 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001662 return FALSE;
1663 }
1664
1665 buf[result_length] = 0;
1666
1667 *target_path = buf;
1668 return TRUE;
1669}
1670
1671static int
1672win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1673 BOOL traverse);
1674static int
1675win32_xstat_impl(const char *path, struct win32_stat *result,
1676 BOOL traverse)
1677{
Victor Stinner26de69d2011-06-17 15:15:38 +02001678 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001679 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001680 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001681 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001682 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001683 const char *dot;
1684
Brian Curtind25aef52011-06-13 15:16:04 -05001685 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001686 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1687 traverse reparse point. */
1688 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001689 }
1690
Brian Curtinf5e76d02010-11-24 13:14:05 +00001691 hFile = CreateFileA(
1692 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001693 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001694 0, /* share mode */
1695 NULL, /* security attributes */
1696 OPEN_EXISTING,
1697 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001698 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1699 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001700 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001701 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1702 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001703 NULL);
1704
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001705 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001706 /* Either the target doesn't exist, or we don't have access to
1707 get a handle to it. If the former, we need to return an error.
1708 If the latter, we can use attributes_from_dir. */
1709 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001710 return -1;
1711 /* Could not get attributes on open file. Fall back to
1712 reading the directory. */
1713 if (!attributes_from_dir(path, &info, &reparse_tag))
1714 /* Very strange. This should not fail now */
1715 return -1;
1716 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1717 if (traverse) {
1718 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001719 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001720 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001721 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001722 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001723 } else {
1724 if (!GetFileInformationByHandle(hFile, &info)) {
1725 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001726 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001727 }
1728 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001729 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1730 return -1;
1731
1732 /* Close the outer open file handle now that we're about to
1733 reopen it with different flags. */
1734 if (!CloseHandle(hFile))
1735 return -1;
1736
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001737 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001738 /* In order to call GetFinalPathNameByHandle we need to open
1739 the file without the reparse handling flag set. */
1740 hFile2 = CreateFileA(
1741 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1742 NULL, OPEN_EXISTING,
1743 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1744 NULL);
1745 if (hFile2 == INVALID_HANDLE_VALUE)
1746 return -1;
1747
1748 if (!get_target_path(hFile2, &target_path))
1749 return -1;
1750
1751 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001752 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001753 return code;
1754 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001755 } else
1756 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001757 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001758 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001759
1760 /* Set S_IEXEC if it is an .exe, .bat, ... */
1761 dot = strrchr(path, '.');
1762 if (dot) {
1763 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1764 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1765 result->st_mode |= 0111;
1766 }
1767 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001768}
1769
1770static int
Brian Curtind25aef52011-06-13 15:16:04 -05001771win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1772 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001773{
1774 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001775 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001776 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001777 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001778 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001779 const wchar_t *dot;
1780
Brian Curtind25aef52011-06-13 15:16:04 -05001781 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001782 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1783 traverse reparse point. */
1784 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001785 }
1786
Brian Curtinf5e76d02010-11-24 13:14:05 +00001787 hFile = CreateFileW(
1788 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001789 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001790 0, /* share mode */
1791 NULL, /* security attributes */
1792 OPEN_EXISTING,
1793 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001794 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1795 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001796 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001797 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001798 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001799 NULL);
1800
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001801 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001802 /* Either the target doesn't exist, or we don't have access to
1803 get a handle to it. If the former, we need to return an error.
1804 If the latter, we can use attributes_from_dir. */
1805 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001806 return -1;
1807 /* Could not get attributes on open file. Fall back to
1808 reading the directory. */
1809 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1810 /* Very strange. This should not fail now */
1811 return -1;
1812 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1813 if (traverse) {
1814 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001815 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001816 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001817 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001818 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001819 } else {
1820 if (!GetFileInformationByHandle(hFile, &info)) {
1821 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001822 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001823 }
1824 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001825 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1826 return -1;
1827
1828 /* Close the outer open file handle now that we're about to
1829 reopen it with different flags. */
1830 if (!CloseHandle(hFile))
1831 return -1;
1832
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001833 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001834 /* In order to call GetFinalPathNameByHandle we need to open
1835 the file without the reparse handling flag set. */
1836 hFile2 = CreateFileW(
1837 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1838 NULL, OPEN_EXISTING,
1839 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1840 NULL);
1841 if (hFile2 == INVALID_HANDLE_VALUE)
1842 return -1;
1843
1844 if (!get_target_path(hFile2, &target_path))
1845 return -1;
1846
1847 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001848 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001849 return code;
1850 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001851 } else
1852 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001853 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001854 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001855
1856 /* Set S_IEXEC if it is an .exe, .bat, ... */
1857 dot = wcsrchr(path, '.');
1858 if (dot) {
1859 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1860 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1861 result->st_mode |= 0111;
1862 }
1863 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001864}
1865
1866static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001867win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001868{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001869 /* Protocol violation: we explicitly clear errno, instead of
1870 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001871 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001872 errno = 0;
1873 return code;
1874}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001875
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001876static int
1877win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1878{
1879 /* Protocol violation: we explicitly clear errno, instead of
1880 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001881 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001882 errno = 0;
1883 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001884}
Brian Curtind25aef52011-06-13 15:16:04 -05001885/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001886
1887 In Posix, stat automatically traverses symlinks and returns the stat
1888 structure for the target. In Windows, the equivalent GetFileAttributes by
1889 default does not traverse symlinks and instead returns attributes for
1890 the symlink.
1891
1892 Therefore, win32_lstat will get the attributes traditionally, and
1893 win32_stat will first explicitly resolve the symlink target and then will
1894 call win32_lstat on that result.
1895
Ezio Melotti4969f702011-03-15 05:59:46 +02001896 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001897
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001898static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001899win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001900{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001901 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001902}
1903
Victor Stinner8c62be82010-05-06 00:08:46 +00001904static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001905win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001906{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001907 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001908}
1909
1910static int
1911win32_stat(const char* path, struct win32_stat *result)
1912{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001913 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001914}
1915
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001916static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001917win32_stat_w(const wchar_t* path, struct win32_stat *result)
1918{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001919 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001920}
1921
1922static int
1923win32_fstat(int file_number, struct win32_stat *result)
1924{
Victor Stinner8c62be82010-05-06 00:08:46 +00001925 BY_HANDLE_FILE_INFORMATION info;
1926 HANDLE h;
1927 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001928
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001929 if (!_PyVerify_fd(file_number))
1930 h = INVALID_HANDLE_VALUE;
1931 else
1932 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001933
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 /* Protocol violation: we explicitly clear errno, instead of
1935 setting it to a POSIX error. Callers should use GetLastError. */
1936 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001937
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 if (h == INVALID_HANDLE_VALUE) {
1939 /* This is really a C library error (invalid file handle).
1940 We set the Win32 error to the closes one matching. */
1941 SetLastError(ERROR_INVALID_HANDLE);
1942 return -1;
1943 }
1944 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001945
Victor Stinner8c62be82010-05-06 00:08:46 +00001946 type = GetFileType(h);
1947 if (type == FILE_TYPE_UNKNOWN) {
1948 DWORD error = GetLastError();
1949 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001950 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001951 }
1952 /* else: valid but unknown file */
1953 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001954
Victor Stinner8c62be82010-05-06 00:08:46 +00001955 if (type != FILE_TYPE_DISK) {
1956 if (type == FILE_TYPE_CHAR)
1957 result->st_mode = _S_IFCHR;
1958 else if (type == FILE_TYPE_PIPE)
1959 result->st_mode = _S_IFIFO;
1960 return 0;
1961 }
1962
1963 if (!GetFileInformationByHandle(h, &info)) {
1964 return -1;
1965 }
1966
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001967 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001968 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001969 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1970 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001971}
1972
1973#endif /* MS_WINDOWS */
1974
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001975PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001976"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001977This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001978 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001979or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1980\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001981Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1982or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001983\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001984See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001985
1986static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001987 {"st_mode", "protection bits"},
1988 {"st_ino", "inode"},
1989 {"st_dev", "device"},
1990 {"st_nlink", "number of hard links"},
1991 {"st_uid", "user ID of owner"},
1992 {"st_gid", "group ID of owner"},
1993 {"st_size", "total size, in bytes"},
1994 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1995 {NULL, "integer time of last access"},
1996 {NULL, "integer time of last modification"},
1997 {NULL, "integer time of last change"},
1998 {"st_atime", "time of last access"},
1999 {"st_mtime", "time of last modification"},
2000 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07002001 {"st_atime_ns", "time of last access in nanoseconds"},
2002 {"st_mtime_ns", "time of last modification in nanoseconds"},
2003 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002004#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002005 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002006#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002007#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002008 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002009#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002010#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002011 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002012#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002013#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002015#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002016#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002017 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002018#endif
2019#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002020 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002021#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002023};
2024
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002025#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002026#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002027#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002028#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002029#endif
2030
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002031#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002032#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2033#else
2034#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2035#endif
2036
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002037#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002038#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2039#else
2040#define ST_RDEV_IDX ST_BLOCKS_IDX
2041#endif
2042
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002043#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2044#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2045#else
2046#define ST_FLAGS_IDX ST_RDEV_IDX
2047#endif
2048
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002049#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002050#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002051#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002052#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002053#endif
2054
2055#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2056#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2057#else
2058#define ST_BIRTHTIME_IDX ST_GEN_IDX
2059#endif
2060
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002061static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002062 "stat_result", /* name */
2063 stat_result__doc__, /* doc */
2064 stat_result_fields,
2065 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002066};
2067
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002068PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002069"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2070This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002071 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002072or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002073\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002074See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002075
2076static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 {"f_bsize", },
2078 {"f_frsize", },
2079 {"f_blocks", },
2080 {"f_bfree", },
2081 {"f_bavail", },
2082 {"f_files", },
2083 {"f_ffree", },
2084 {"f_favail", },
2085 {"f_flag", },
2086 {"f_namemax",},
2087 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002088};
2089
2090static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002091 "statvfs_result", /* name */
2092 statvfs_result__doc__, /* doc */
2093 statvfs_result_fields,
2094 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002095};
2096
Ross Lagerwall7807c352011-03-17 20:20:30 +02002097#if defined(HAVE_WAITID) && !defined(__APPLE__)
2098PyDoc_STRVAR(waitid_result__doc__,
2099"waitid_result: Result from waitid.\n\n\
2100This object may be accessed either as a tuple of\n\
2101 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2102or via the attributes si_pid, si_uid, and so on.\n\
2103\n\
2104See os.waitid for more information.");
2105
2106static PyStructSequence_Field waitid_result_fields[] = {
2107 {"si_pid", },
2108 {"si_uid", },
2109 {"si_signo", },
2110 {"si_status", },
2111 {"si_code", },
2112 {0}
2113};
2114
2115static PyStructSequence_Desc waitid_result_desc = {
2116 "waitid_result", /* name */
2117 waitid_result__doc__, /* doc */
2118 waitid_result_fields,
2119 5
2120};
2121static PyTypeObject WaitidResultType;
2122#endif
2123
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002124static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002125static PyTypeObject StatResultType;
2126static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002127#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002128static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002129#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002130static newfunc structseq_new;
2131
2132static PyObject *
2133statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2134{
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 PyStructSequence *result;
2136 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002137
Victor Stinner8c62be82010-05-06 00:08:46 +00002138 result = (PyStructSequence*)structseq_new(type, args, kwds);
2139 if (!result)
2140 return NULL;
2141 /* If we have been initialized from a tuple,
2142 st_?time might be set to None. Initialize it
2143 from the int slots. */
2144 for (i = 7; i <= 9; i++) {
2145 if (result->ob_item[i+3] == Py_None) {
2146 Py_DECREF(Py_None);
2147 Py_INCREF(result->ob_item[i]);
2148 result->ob_item[i+3] = result->ob_item[i];
2149 }
2150 }
2151 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002152}
2153
2154
2155
2156/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002157static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002158
2159PyDoc_STRVAR(stat_float_times__doc__,
2160"stat_float_times([newval]) -> oldval\n\n\
2161Determine whether os.[lf]stat represents time stamps as float objects.\n\
2162If newval is True, future calls to stat() return floats, if it is False,\n\
2163future calls return ints. \n\
2164If newval is omitted, return the current setting.\n");
2165
2166static PyObject*
2167stat_float_times(PyObject* self, PyObject *args)
2168{
Victor Stinner8c62be82010-05-06 00:08:46 +00002169 int newval = -1;
2170 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2171 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002172 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2173 "stat_float_times() is deprecated",
2174 1))
2175 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002176 if (newval == -1)
2177 /* Return old value */
2178 return PyBool_FromLong(_stat_float_times);
2179 _stat_float_times = newval;
2180 Py_INCREF(Py_None);
2181 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002182}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002183
Larry Hastings6fe20b32012-04-19 15:07:49 -07002184static PyObject *billion = NULL;
2185
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002186static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002187fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002188{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002189 PyObject *s = _PyLong_FromTime_t(sec);
2190 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2191 PyObject *s_in_ns = NULL;
2192 PyObject *ns_total = NULL;
2193 PyObject *float_s = NULL;
2194
2195 if (!(s && ns_fractional))
2196 goto exit;
2197
2198 s_in_ns = PyNumber_Multiply(s, billion);
2199 if (!s_in_ns)
2200 goto exit;
2201
2202 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2203 if (!ns_total)
2204 goto exit;
2205
Victor Stinner4195b5c2012-02-08 23:03:19 +01002206 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002207 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2208 if (!float_s)
2209 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002210 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002211 else {
2212 float_s = s;
2213 Py_INCREF(float_s);
2214 }
2215
2216 PyStructSequence_SET_ITEM(v, index, s);
2217 PyStructSequence_SET_ITEM(v, index+3, float_s);
2218 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2219 s = NULL;
2220 float_s = NULL;
2221 ns_total = NULL;
2222exit:
2223 Py_XDECREF(s);
2224 Py_XDECREF(ns_fractional);
2225 Py_XDECREF(s_in_ns);
2226 Py_XDECREF(ns_total);
2227 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002228}
2229
Tim Peters5aa91602002-01-30 05:46:57 +00002230/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002231 (used by posix_stat() and posix_fstat()) */
2232static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002233_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002234{
Victor Stinner8c62be82010-05-06 00:08:46 +00002235 unsigned long ansec, mnsec, cnsec;
2236 PyObject *v = PyStructSequence_New(&StatResultType);
2237 if (v == NULL)
2238 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002239
Victor Stinner8c62be82010-05-06 00:08:46 +00002240 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002241#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002242 PyStructSequence_SET_ITEM(v, 1,
2243 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002244#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002245 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002246#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002247#ifdef MS_WINDOWS
2248 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002249#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002250 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002251#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002252 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002253#if defined(MS_WINDOWS)
2254 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2255 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2256#else
2257 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2258 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2259#endif
Fred Drake699f3522000-06-29 21:12:41 +00002260#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002261 PyStructSequence_SET_ITEM(v, 6,
2262 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002263#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002264 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002265#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002266
Martin v. Löwis14694662006-02-03 12:54:16 +00002267#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002268 ansec = st->st_atim.tv_nsec;
2269 mnsec = st->st_mtim.tv_nsec;
2270 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002271#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002272 ansec = st->st_atimespec.tv_nsec;
2273 mnsec = st->st_mtimespec.tv_nsec;
2274 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002275#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002276 ansec = st->st_atime_nsec;
2277 mnsec = st->st_mtime_nsec;
2278 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002279#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002280 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002281#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002282 fill_time(v, 7, st->st_atime, ansec);
2283 fill_time(v, 8, st->st_mtime, mnsec);
2284 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002285
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002286#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002287 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2288 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002289#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002290#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002291 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2292 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002293#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002294#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002295 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2296 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002297#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002298#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002299 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2300 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002301#endif
2302#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002303 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002304 PyObject *val;
2305 unsigned long bsec,bnsec;
2306 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002307#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002308 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002309#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002310 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002311#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002312 if (_stat_float_times) {
2313 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2314 } else {
2315 val = PyLong_FromLong((long)bsec);
2316 }
2317 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2318 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002319 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002320#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002321#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002322 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2323 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002324#endif
Fred Drake699f3522000-06-29 21:12:41 +00002325
Victor Stinner8c62be82010-05-06 00:08:46 +00002326 if (PyErr_Occurred()) {
2327 Py_DECREF(v);
2328 return NULL;
2329 }
Fred Drake699f3522000-06-29 21:12:41 +00002330
Victor Stinner8c62be82010-05-06 00:08:46 +00002331 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002332}
2333
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002334/* POSIX methods */
2335
Guido van Rossum94f6f721999-01-06 18:42:14 +00002336
2337static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002338posix_do_stat(char *function_name, path_t *path,
2339 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002340{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002341 STRUCT_STAT st;
2342 int result;
2343
2344#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2345 if (follow_symlinks_specified(function_name, follow_symlinks))
2346 return NULL;
2347#endif
2348
2349 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2350 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2351 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2352 return NULL;
2353
2354 Py_BEGIN_ALLOW_THREADS
2355 if (path->fd != -1)
2356 result = FSTAT(path->fd, &st);
2357 else
2358#ifdef MS_WINDOWS
2359 if (path->wide) {
2360 if (follow_symlinks)
2361 result = win32_stat_w(path->wide, &st);
2362 else
2363 result = win32_lstat_w(path->wide, &st);
2364 }
2365 else
2366#endif
2367#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2368 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2369 result = LSTAT(path->narrow, &st);
2370 else
2371#endif
2372#ifdef HAVE_FSTATAT
2373 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2374 result = fstatat(dir_fd, path->narrow, &st,
2375 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2376 else
2377#endif
2378 result = STAT(path->narrow, &st);
2379 Py_END_ALLOW_THREADS
2380
Victor Stinner292c8352012-10-30 02:17:38 +01002381 if (result != 0) {
2382 return path_error(path);
2383 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002384
2385 return _pystat_fromstructstat(&st);
2386}
2387
Larry Hastings31826802013-10-19 00:09:25 -07002388#ifdef HAVE_FSTATAT
2389 #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter
2390#else
2391 #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable
2392#endif
2393
2394
Larry Hastings61272b72014-01-07 12:41:53 -08002395/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002396
2397class path_t_converter(CConverter):
2398
2399 type = "path_t"
2400 impl_by_reference = True
2401 parse_by_reference = True
2402
2403 converter = 'path_converter'
2404
2405 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002406 # right now path_t doesn't support default values.
2407 # to support a default value, you'll need to override initialize().
Larry Hastings7726ac92014-01-31 22:03:12 -08002408 if self.default is not unspecified:
2409 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002410
Larry Hastings7726ac92014-01-31 22:03:12 -08002411 if self.c_default is not None:
2412 fail("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002413
2414 self.nullable = nullable
2415 self.allow_fd = allow_fd
2416
Larry Hastings7726ac92014-01-31 22:03:12 -08002417 def pre_render(self):
2418 def strify(value):
2419 return str(int(bool(value)))
2420
2421 # add self.py_name here when merging with posixmodule conversion
Larry Hastings31826802013-10-19 00:09:25 -07002422 self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format(
2423 self.function.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002424 strify(self.nullable),
2425 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002426 )
2427
2428 def cleanup(self):
2429 return "path_cleanup(&" + self.name + ");\n"
2430
2431
2432class dir_fd_converter(CConverter):
2433 type = 'int'
2434 converter = 'OS_STAT_DIR_FD_CONVERTER'
2435
2436 def converter_init(self):
2437 if self.default in (unspecified, None):
2438 self.c_default = 'DEFAULT_DIR_FD'
2439
2440
Larry Hastings61272b72014-01-07 12:41:53 -08002441[python start generated code]*/
Larry Hastings7726ac92014-01-31 22:03:12 -08002442/*[python end generated code: output=da39a3ee5e6b4b0d input=5c9f456f53244fc3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002443
Larry Hastings61272b72014-01-07 12:41:53 -08002444/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002445
Larry Hastings2a727912014-01-16 11:32:01 -08002446os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002447
2448 path : path_t(allow_fd=True)
2449 Path to be examined; can be string, bytes, or open-file-descriptor int.
2450
2451 *
2452
2453 dir_fd : dir_fd = None
2454 If not None, it should be a file descriptor open to a directory,
2455 and path should be a relative string; path will then be relative to
2456 that directory.
2457
2458 follow_symlinks: bool = True
2459 If False, and the last element of the path is a symbolic link,
2460 stat will examine the symbolic link itself instead of the file
2461 the link points to.
2462
2463Perform a stat system call on the given path.
2464
2465dir_fd and follow_symlinks may not be implemented
2466 on your platform. If they are unavailable, using them will raise a
2467 NotImplementedError.
2468
2469It's an error to use dir_fd or follow_symlinks when specifying path as
2470 an open file descriptor.
2471
Larry Hastings61272b72014-01-07 12:41:53 -08002472[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002473
2474PyDoc_STRVAR(os_stat__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002475"stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n"
2476"--\n"
2477"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002478"Perform a stat system call on the given path.\n"
2479"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002480" path\n"
2481" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
2482" dir_fd\n"
2483" If not None, it should be a file descriptor open to a directory,\n"
2484" and path should be a relative string; path will then be relative to\n"
2485" that directory.\n"
2486" follow_symlinks\n"
2487" If False, and the last element of the path is a symbolic link,\n"
2488" stat will examine the symbolic link itself instead of the file\n"
2489" the link points to.\n"
2490"\n"
2491"dir_fd and follow_symlinks may not be implemented\n"
2492" on your platform. If they are unavailable, using them will raise a\n"
2493" NotImplementedError.\n"
2494"\n"
2495"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n"
2496" an open file descriptor.");
2497
2498#define OS_STAT_METHODDEF \
2499 {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002500
2501static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002502os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002503
2504static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002505os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002506{
Larry Hastings31826802013-10-19 00:09:25 -07002507 PyObject *return_value = NULL;
2508 static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2509 path_t path = PATH_T_INITIALIZE("stat", 0, 1);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002510 int dir_fd = DEFAULT_DIR_FD;
2511 int follow_symlinks = 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002512
Larry Hastings31826802013-10-19 00:09:25 -07002513 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2514 "O&|$O&p:stat", _keywords,
2515 path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks))
2516 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002517 return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002518
2519exit:
2520 /* Cleanup for path */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002521 path_cleanup(&path);
Larry Hastings31826802013-10-19 00:09:25 -07002522
Larry Hastings9cf065c2012-06-22 16:30:09 -07002523 return return_value;
2524}
2525
Larry Hastings31826802013-10-19 00:09:25 -07002526static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002527os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002528/*[clinic end generated code: output=f1dcaa5e24db9882 input=5ae155bd475fd20a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002529{
2530 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2531}
2532
Larry Hastings9cf065c2012-06-22 16:30:09 -07002533PyDoc_STRVAR(posix_lstat__doc__,
2534"lstat(path, *, dir_fd=None) -> stat result\n\n\
2535Like stat(), but do not follow symbolic links.\n\
2536Equivalent to stat(path, follow_symlinks=False).");
2537
2538static PyObject *
2539posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2540{
2541 static char *keywords[] = {"path", "dir_fd", NULL};
2542 path_t path;
2543 int dir_fd = DEFAULT_DIR_FD;
2544 int follow_symlinks = 0;
2545 PyObject *return_value;
2546
2547 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002548 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002549 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2550 path_converter, &path,
2551#ifdef HAVE_FSTATAT
2552 dir_fd_converter, &dir_fd
2553#else
2554 dir_fd_unavailable, &dir_fd
2555#endif
2556 ))
2557 return NULL;
Larry Hastings31826802013-10-19 00:09:25 -07002558 return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002559 path_cleanup(&path);
2560 return return_value;
2561}
2562
Larry Hastings31826802013-10-19 00:09:25 -07002563
2564#ifdef HAVE_FACCESSAT
2565 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter
2566#else
2567 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable
2568#endif
Larry Hastings61272b72014-01-07 12:41:53 -08002569/*[clinic input]
Larry Hastings2a727912014-01-16 11:32:01 -08002570os.access
Larry Hastings31826802013-10-19 00:09:25 -07002571
2572 path: path_t(allow_fd=True)
2573 Path to be tested; can be string, bytes, or open-file-descriptor int.
2574
2575 mode: int
2576 Operating-system mode bitfield. Can be F_OK to test existence,
2577 or the inclusive-OR of R_OK, W_OK, and X_OK.
2578
2579 *
2580
2581 dir_fd : dir_fd = None
2582 If not None, it should be a file descriptor open to a directory,
2583 and path should be relative; path will then be relative to that
2584 directory.
2585
2586 effective_ids: bool = False
2587 If True, access will use the effective uid/gid instead of
2588 the real uid/gid.
2589
2590 follow_symlinks: bool = True
2591 If False, and the last element of the path is a symbolic link,
2592 access will examine the symbolic link itself instead of the file
2593 the link points to.
2594
2595Use the real uid/gid to test for access to a path.
2596
2597{parameters}
2598dir_fd, effective_ids, and follow_symlinks may not be implemented
2599 on your platform. If they are unavailable, using them will raise a
2600 NotImplementedError.
2601
2602Note that most operations will use the effective uid/gid, therefore this
2603 routine can be used in a suid/sgid environment to test if the invoking user
2604 has the specified access to the path.
2605
Larry Hastings61272b72014-01-07 12:41:53 -08002606[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002607
2608PyDoc_STRVAR(os_access__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002609"access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n"
2610" follow_symlinks=True)\n"
2611"--\n"
2612"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002613"Use the real uid/gid to test for access to a path.\n"
2614"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002615" path\n"
2616" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
2617" mode\n"
2618" Operating-system mode bitfield. Can be F_OK to test existence,\n"
2619" or the inclusive-OR of R_OK, W_OK, and X_OK.\n"
2620" dir_fd\n"
2621" If not None, it should be a file descriptor open to a directory,\n"
2622" and path should be relative; path will then be relative to that\n"
2623" directory.\n"
2624" effective_ids\n"
2625" If True, access will use the effective uid/gid instead of\n"
2626" the real uid/gid.\n"
2627" follow_symlinks\n"
2628" If False, and the last element of the path is a symbolic link,\n"
2629" access will examine the symbolic link itself instead of the file\n"
2630" the link points to.\n"
2631"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002632"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
2633" on your platform. If they are unavailable, using them will raise a\n"
2634" NotImplementedError.\n"
2635"\n"
2636"Note that most operations will use the effective uid/gid, therefore this\n"
2637" routine can be used in a suid/sgid environment to test if the invoking user\n"
2638" has the specified access to the path.");
2639
2640#define OS_ACCESS_METHODDEF \
2641 {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -07002642
2643static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002644os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002645
2646static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002647os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002648{
Larry Hastings31826802013-10-19 00:09:25 -07002649 PyObject *return_value = NULL;
2650 static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL};
2651 path_t path = PATH_T_INITIALIZE("access", 0, 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00002652 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002653 int dir_fd = DEFAULT_DIR_FD;
2654 int effective_ids = 0;
2655 int follow_symlinks = 1;
Larry Hastings31826802013-10-19 00:09:25 -07002656
2657 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2658 "O&i|$O&pp:access", _keywords,
2659 path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks))
2660 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002661 return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002662
2663exit:
2664 /* Cleanup for path */
2665 path_cleanup(&path);
2666
2667 return return_value;
2668}
2669
2670static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002671os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002672/*[clinic end generated code: output=a6ed4f151be9df0f input=2e2e7594371f5b7e]*/
Larry Hastings31826802013-10-19 00:09:25 -07002673{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002674 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002675
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002676#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002677 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002678#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002679 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002680#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002681
Larry Hastings9cf065c2012-06-22 16:30:09 -07002682#ifndef HAVE_FACCESSAT
2683 if (follow_symlinks_specified("access", follow_symlinks))
2684 goto exit;
2685
2686 if (effective_ids) {
2687 argument_unavailable_error("access", "effective_ids");
2688 goto exit;
2689 }
2690#endif
2691
2692#ifdef MS_WINDOWS
2693 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002694 if (path->wide != NULL)
2695 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002696 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002697 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002698 Py_END_ALLOW_THREADS
2699
2700 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002701 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002702 * * we didn't get a -1, and
2703 * * write access wasn't requested,
2704 * * or the file isn't read-only,
2705 * * or it's a directory.
2706 * (Directories cannot be read-only on Windows.)
2707 */
2708 return_value = PyBool_FromLong(
Tim Golden23005082013-10-25 11:22:37 +01002709 (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002710 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002711 !(attr & FILE_ATTRIBUTE_READONLY) ||
2712 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2713#else
2714
2715 Py_BEGIN_ALLOW_THREADS
2716#ifdef HAVE_FACCESSAT
2717 if ((dir_fd != DEFAULT_DIR_FD) ||
2718 effective_ids ||
2719 !follow_symlinks) {
2720 int flags = 0;
2721 if (!follow_symlinks)
2722 flags |= AT_SYMLINK_NOFOLLOW;
2723 if (effective_ids)
2724 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002725 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002726 }
2727 else
2728#endif
Larry Hastings31826802013-10-19 00:09:25 -07002729 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002730 Py_END_ALLOW_THREADS
2731 return_value = PyBool_FromLong(!result);
2732#endif
2733
2734#ifndef HAVE_FACCESSAT
2735exit:
2736#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002737 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002738}
2739
Guido van Rossumd371ff11999-01-25 16:12:23 +00002740#ifndef F_OK
2741#define F_OK 0
2742#endif
2743#ifndef R_OK
2744#define R_OK 4
2745#endif
2746#ifndef W_OK
2747#define W_OK 2
2748#endif
2749#ifndef X_OK
2750#define X_OK 1
2751#endif
2752
Larry Hastings31826802013-10-19 00:09:25 -07002753
Guido van Rossumd371ff11999-01-25 16:12:23 +00002754#ifdef HAVE_TTYNAME
Larry Hastings31826802013-10-19 00:09:25 -07002755
Larry Hastings61272b72014-01-07 12:41:53 -08002756/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002757os.ttyname -> DecodeFSDefault
2758
2759 fd: int
2760 Integer file descriptor handle.
2761
2762 /
2763
2764Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002765[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002766
2767PyDoc_STRVAR(os_ttyname__doc__,
Larry Hastings2623c8c2014-02-08 22:15:29 -08002768"ttyname($module, fd, /)\n"
2769"--\n"
2770"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002771"Return the name of the terminal device connected to \'fd\'.\n"
2772"\n"
Larry Hastings31826802013-10-19 00:09:25 -07002773" fd\n"
2774" Integer file descriptor handle.");
2775
2776#define OS_TTYNAME_METHODDEF \
2777 {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__},
2778
2779static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002780os_ttyname_impl(PyModuleDef *module, int fd);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002781
2782static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002783os_ttyname(PyModuleDef *module, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002784{
Larry Hastings31826802013-10-19 00:09:25 -07002785 PyObject *return_value = NULL;
2786 int fd;
2787 char *_return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002788
Larry Hastings31826802013-10-19 00:09:25 -07002789 if (!PyArg_ParseTuple(args,
2790 "i:ttyname",
2791 &fd))
2792 goto exit;
Larry Hastingsed4a1c52013-11-18 09:32:13 -08002793 _return_value = os_ttyname_impl(module, fd);
Larry Hastings31826802013-10-19 00:09:25 -07002794 if (_return_value == NULL)
2795 goto exit;
2796 return_value = PyUnicode_DecodeFSDefault(_return_value);
2797
2798exit:
2799 return return_value;
2800}
2801
2802static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002803os_ttyname_impl(PyModuleDef *module, int fd)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002804/*[clinic end generated code: output=cee7bc4cffec01a2 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002805{
2806 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002807
Larry Hastings31826802013-10-19 00:09:25 -07002808 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002809 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002810 posix_error();
2811 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002812}
Larry Hastings31826802013-10-19 00:09:25 -07002813#else
2814#define OS_TTYNAME_METHODDEF
Guido van Rossumd371ff11999-01-25 16:12:23 +00002815#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002816
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002817#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002818PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002819"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002820Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002821
2822static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002823posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002824{
Victor Stinner8c62be82010-05-06 00:08:46 +00002825 char *ret;
2826 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002827
Greg Wardb48bc172000-03-01 21:51:56 +00002828#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002829 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002830#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002831 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002832#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002833 if (ret == NULL)
2834 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002835 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002836}
2837#endif
2838
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002839PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002840"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002841Change the current working directory to the specified path.\n\
2842\n\
2843path may always be specified as a string.\n\
2844On some platforms, path may also be specified as an open file descriptor.\n\
2845 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002846
Barry Warsaw53699e91996-12-10 23:23:01 +00002847static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002848posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002849{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002850 path_t path;
2851 int result;
2852 PyObject *return_value = NULL;
2853 static char *keywords[] = {"path", NULL};
2854
2855 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002856 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002857#ifdef HAVE_FCHDIR
2858 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002859#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002860 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2861 path_converter, &path
2862 ))
2863 return NULL;
2864
2865 Py_BEGIN_ALLOW_THREADS
2866#ifdef MS_WINDOWS
2867 if (path.wide)
2868 result = win32_wchdir(path.wide);
2869 else
2870 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002871 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002872#else
2873#ifdef HAVE_FCHDIR
2874 if (path.fd != -1)
2875 result = fchdir(path.fd);
2876 else
2877#endif
2878 result = chdir(path.narrow);
2879#endif
2880 Py_END_ALLOW_THREADS
2881
2882 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002883 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002884 goto exit;
2885 }
2886
2887 return_value = Py_None;
2888 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002889
Larry Hastings9cf065c2012-06-22 16:30:09 -07002890exit:
2891 path_cleanup(&path);
2892 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002893}
2894
Fred Drake4d1e64b2002-04-15 19:40:07 +00002895#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002896PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002897"fchdir(fd)\n\n\
2898Change to the directory of the given file descriptor. fd must be\n\
2899opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002900
2901static PyObject *
2902posix_fchdir(PyObject *self, PyObject *fdobj)
2903{
Victor Stinner8c62be82010-05-06 00:08:46 +00002904 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002905}
2906#endif /* HAVE_FCHDIR */
2907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002908
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002909PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002910"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2911Change the access permissions of a file.\n\
2912\n\
2913path may always be specified as a string.\n\
2914On some platforms, path may also be specified as an open file descriptor.\n\
2915 If this functionality is unavailable, using it raises an exception.\n\
2916If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2917 and path should be relative; path will then be relative to that directory.\n\
2918If follow_symlinks is False, and the last element of the path is a symbolic\n\
2919 link, chmod will modify the symbolic link itself instead of the file the\n\
2920 link points to.\n\
2921It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2922 an open file descriptor.\n\
2923dir_fd and follow_symlinks may not be implemented on your platform.\n\
2924 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002925
Barry Warsaw53699e91996-12-10 23:23:01 +00002926static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002927posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002928{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002929 path_t path;
2930 int mode;
2931 int dir_fd = DEFAULT_DIR_FD;
2932 int follow_symlinks = 1;
2933 int result;
2934 PyObject *return_value = NULL;
2935 static char *keywords[] = {"path", "mode", "dir_fd",
2936 "follow_symlinks", NULL};
2937
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002938#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002939 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002940#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002941
Larry Hastings9cf065c2012-06-22 16:30:09 -07002942#ifdef HAVE_FCHMODAT
2943 int fchmodat_nofollow_unsupported = 0;
2944#endif
2945
2946 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002947 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002948#ifdef HAVE_FCHMOD
2949 path.allow_fd = 1;
2950#endif
2951 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2952 path_converter, &path,
2953 &mode,
2954#ifdef HAVE_FCHMODAT
2955 dir_fd_converter, &dir_fd,
2956#else
2957 dir_fd_unavailable, &dir_fd,
2958#endif
2959 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002960 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002961
2962#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2963 if (follow_symlinks_specified("chmod", follow_symlinks))
2964 goto exit;
2965#endif
2966
2967#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002968 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002969 if (path.wide)
2970 attr = GetFileAttributesW(path.wide);
2971 else
2972 attr = GetFileAttributesA(path.narrow);
Tim Golden23005082013-10-25 11:22:37 +01002973 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002974 result = 0;
2975 else {
2976 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002977 attr &= ~FILE_ATTRIBUTE_READONLY;
2978 else
2979 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002980 if (path.wide)
2981 result = SetFileAttributesW(path.wide, attr);
2982 else
2983 result = SetFileAttributesA(path.narrow, attr);
2984 }
2985 Py_END_ALLOW_THREADS
2986
2987 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002988 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002989 goto exit;
2990 }
2991#else /* MS_WINDOWS */
2992 Py_BEGIN_ALLOW_THREADS
2993#ifdef HAVE_FCHMOD
2994 if (path.fd != -1)
2995 result = fchmod(path.fd, mode);
2996 else
2997#endif
2998#ifdef HAVE_LCHMOD
2999 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3000 result = lchmod(path.narrow, mode);
3001 else
3002#endif
3003#ifdef HAVE_FCHMODAT
3004 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
3005 /*
3006 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3007 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003008 * and then says it isn't implemented yet.
3009 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003010 *
3011 * Once it is supported, os.chmod will automatically
3012 * support dir_fd and follow_symlinks=False. (Hopefully.)
3013 * Until then, we need to be careful what exception we raise.
3014 */
3015 result = fchmodat(dir_fd, path.narrow, mode,
3016 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3017 /*
3018 * But wait! We can't throw the exception without allowing threads,
3019 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3020 */
3021 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003022 result &&
3023 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3024 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00003025 }
3026 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00003027#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003028 result = chmod(path.narrow, mode);
3029 Py_END_ALLOW_THREADS
3030
3031 if (result) {
3032#ifdef HAVE_FCHMODAT
3033 if (fchmodat_nofollow_unsupported) {
3034 if (dir_fd != DEFAULT_DIR_FD)
3035 dir_fd_and_follow_symlinks_invalid("chmod",
3036 dir_fd, follow_symlinks);
3037 else
3038 follow_symlinks_specified("chmod", follow_symlinks);
3039 }
3040 else
3041#endif
Victor Stinner292c8352012-10-30 02:17:38 +01003042 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003043 goto exit;
3044 }
3045#endif
3046
3047 Py_INCREF(Py_None);
3048 return_value = Py_None;
3049exit:
3050 path_cleanup(&path);
3051 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003052}
3053
Larry Hastings9cf065c2012-06-22 16:30:09 -07003054
Christian Heimes4e30a842007-11-30 22:12:06 +00003055#ifdef HAVE_FCHMOD
3056PyDoc_STRVAR(posix_fchmod__doc__,
3057"fchmod(fd, mode)\n\n\
3058Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003059descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003060
3061static PyObject *
3062posix_fchmod(PyObject *self, PyObject *args)
3063{
Victor Stinner8c62be82010-05-06 00:08:46 +00003064 int fd, mode, res;
3065 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
3066 return NULL;
3067 Py_BEGIN_ALLOW_THREADS
3068 res = fchmod(fd, mode);
3069 Py_END_ALLOW_THREADS
3070 if (res < 0)
3071 return posix_error();
3072 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003073}
3074#endif /* HAVE_FCHMOD */
3075
3076#ifdef HAVE_LCHMOD
3077PyDoc_STRVAR(posix_lchmod__doc__,
3078"lchmod(path, mode)\n\n\
3079Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003080affects the link itself rather than the target.\n\
3081Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003082
3083static PyObject *
3084posix_lchmod(PyObject *self, PyObject *args)
3085{
Victor Stinner292c8352012-10-30 02:17:38 +01003086 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003087 int i;
3088 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003089 memset(&path, 0, sizeof(path));
3090 path.function_name = "lchmod";
3091 if (!PyArg_ParseTuple(args, "O&i:lchmod",
3092 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00003093 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003094 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003095 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00003096 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003097 if (res < 0) {
3098 path_error(&path);
3099 path_cleanup(&path);
3100 return NULL;
3101 }
3102 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003103 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003104}
3105#endif /* HAVE_LCHMOD */
3106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003107
Thomas Wouterscf297e42007-02-23 15:07:44 +00003108#ifdef HAVE_CHFLAGS
3109PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110"chflags(path, flags, *, follow_symlinks=True)\n\n\
3111Set file flags.\n\
3112\n\
3113If follow_symlinks is False, and the last element of the path is a symbolic\n\
3114 link, chflags will change flags on the symbolic link itself instead of the\n\
3115 file the link points to.\n\
3116follow_symlinks may not be implemented on your platform. If it is\n\
3117unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003118
3119static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003120posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003121{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003122 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003123 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003124 int follow_symlinks = 1;
3125 int result;
Victor Stinner45e90392013-07-18 23:57:35 +02003126 PyObject *return_value = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003127 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
3128
3129 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003130 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003131 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
3132 path_converter, &path,
3133 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003134 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003135
3136#ifndef HAVE_LCHFLAGS
3137 if (follow_symlinks_specified("chflags", follow_symlinks))
3138 goto exit;
3139#endif
3140
Victor Stinner8c62be82010-05-06 00:08:46 +00003141 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003142#ifdef HAVE_LCHFLAGS
3143 if (!follow_symlinks)
3144 result = lchflags(path.narrow, flags);
3145 else
3146#endif
3147 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003148 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003149
3150 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003151 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003152 goto exit;
3153 }
3154
3155 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003156 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157
3158exit:
3159 path_cleanup(&path);
3160 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003161}
3162#endif /* HAVE_CHFLAGS */
3163
3164#ifdef HAVE_LCHFLAGS
3165PyDoc_STRVAR(posix_lchflags__doc__,
3166"lchflags(path, flags)\n\n\
3167Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003168This function will not follow symbolic links.\n\
3169Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003170
3171static PyObject *
3172posix_lchflags(PyObject *self, PyObject *args)
3173{
Victor Stinner292c8352012-10-30 02:17:38 +01003174 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003175 unsigned long flags;
3176 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003177 memset(&path, 0, sizeof(path));
3178 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00003179 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01003180 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00003181 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003182 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003183 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003184 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003185 if (res < 0) {
3186 path_error(&path);
3187 path_cleanup(&path);
3188 return NULL;
3189 }
3190 path_cleanup(&path);
3191 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003192}
3193#endif /* HAVE_LCHFLAGS */
3194
Martin v. Löwis244edc82001-10-04 22:44:26 +00003195#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003196PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003197"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003198Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00003199
3200static PyObject *
3201posix_chroot(PyObject *self, PyObject *args)
3202{
Victor Stinner292c8352012-10-30 02:17:38 +01003203 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00003204}
3205#endif
3206
Guido van Rossum21142a01999-01-08 21:05:37 +00003207#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003208PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003209"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003210force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003211
3212static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003213posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003214{
Stefan Krah0e803b32010-11-26 16:16:47 +00003215 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003216}
3217#endif /* HAVE_FSYNC */
3218
Ross Lagerwall7807c352011-03-17 20:20:30 +02003219#ifdef HAVE_SYNC
3220PyDoc_STRVAR(posix_sync__doc__,
3221"sync()\n\n\
3222Force write of everything to disk.");
3223
3224static PyObject *
3225posix_sync(PyObject *self, PyObject *noargs)
3226{
3227 Py_BEGIN_ALLOW_THREADS
3228 sync();
3229 Py_END_ALLOW_THREADS
3230 Py_RETURN_NONE;
3231}
3232#endif
3233
Guido van Rossum21142a01999-01-08 21:05:37 +00003234#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00003235
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003236#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003237extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3238#endif
3239
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003240PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003241"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003242force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003243 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003244
3245static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003246posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003247{
Stefan Krah0e803b32010-11-26 16:16:47 +00003248 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003249}
3250#endif /* HAVE_FDATASYNC */
3251
3252
Fredrik Lundh10723342000-07-10 16:38:09 +00003253#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003254PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003255"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3256Change the owner and group id of path to the numeric uid and gid.\n\
3257\n\
3258path may always be specified as a string.\n\
3259On some platforms, path may also be specified as an open file descriptor.\n\
3260 If this functionality is unavailable, using it raises an exception.\n\
3261If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3262 and path should be relative; path will then be relative to that directory.\n\
3263If follow_symlinks is False, and the last element of the path is a symbolic\n\
3264 link, chown will modify the symbolic link itself instead of the file the\n\
3265 link points to.\n\
3266It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3267 an open file descriptor.\n\
3268dir_fd and follow_symlinks may not be implemented on your platform.\n\
3269 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003270
Barry Warsaw53699e91996-12-10 23:23:01 +00003271static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003272posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003273{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003274 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003275 uid_t uid;
3276 gid_t gid;
3277 int dir_fd = DEFAULT_DIR_FD;
3278 int follow_symlinks = 1;
3279 int result;
3280 PyObject *return_value = NULL;
3281 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3282 "follow_symlinks", NULL};
3283
3284 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003285 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003286#ifdef HAVE_FCHOWN
3287 path.allow_fd = 1;
3288#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003289 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003290 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003291 _Py_Uid_Converter, &uid,
3292 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003293#ifdef HAVE_FCHOWNAT
3294 dir_fd_converter, &dir_fd,
3295#else
3296 dir_fd_unavailable, &dir_fd,
3297#endif
3298 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003299 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003300
3301#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3302 if (follow_symlinks_specified("chown", follow_symlinks))
3303 goto exit;
3304#endif
3305 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3306 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3307 goto exit;
3308
3309#ifdef __APPLE__
3310 /*
3311 * This is for Mac OS X 10.3, which doesn't have lchown.
3312 * (But we still have an lchown symbol because of weak-linking.)
3313 * It doesn't have fchownat either. So there's no possibility
3314 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003315 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003316 if ((!follow_symlinks) && (lchown == NULL)) {
3317 follow_symlinks_specified("chown", follow_symlinks);
3318 goto exit;
3319 }
3320#endif
3321
Victor Stinner8c62be82010-05-06 00:08:46 +00003322 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003323#ifdef HAVE_FCHOWN
3324 if (path.fd != -1)
3325 result = fchown(path.fd, uid, gid);
3326 else
3327#endif
3328#ifdef HAVE_LCHOWN
3329 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3330 result = lchown(path.narrow, uid, gid);
3331 else
3332#endif
3333#ifdef HAVE_FCHOWNAT
3334 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3335 result = fchownat(dir_fd, path.narrow, uid, gid,
3336 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3337 else
3338#endif
3339 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003341
3342 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003343 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003344 goto exit;
3345 }
3346
3347 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003348 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003349
3350exit:
3351 path_cleanup(&path);
3352 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003353}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003354#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003355
Christian Heimes4e30a842007-11-30 22:12:06 +00003356#ifdef HAVE_FCHOWN
3357PyDoc_STRVAR(posix_fchown__doc__,
3358"fchown(fd, uid, gid)\n\n\
3359Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003360fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003361
3362static PyObject *
3363posix_fchown(PyObject *self, PyObject *args)
3364{
Victor Stinner8c62be82010-05-06 00:08:46 +00003365 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003366 uid_t uid;
3367 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003369 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3370 _Py_Uid_Converter, &uid,
3371 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 return NULL;
3373 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003374 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003375 Py_END_ALLOW_THREADS
3376 if (res < 0)
3377 return posix_error();
3378 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003379}
3380#endif /* HAVE_FCHOWN */
3381
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003382#ifdef HAVE_LCHOWN
3383PyDoc_STRVAR(posix_lchown__doc__,
3384"lchown(path, uid, gid)\n\n\
3385Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386This function will not follow symbolic links.\n\
3387Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003388
3389static PyObject *
3390posix_lchown(PyObject *self, PyObject *args)
3391{
Victor Stinner292c8352012-10-30 02:17:38 +01003392 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003393 uid_t uid;
3394 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003395 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003396 memset(&path, 0, sizeof(path));
3397 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003398 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003399 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003400 _Py_Uid_Converter, &uid,
3401 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003402 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003403 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003404 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003406 if (res < 0) {
3407 path_error(&path);
3408 path_cleanup(&path);
3409 return NULL;
3410 }
3411 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 Py_INCREF(Py_None);
3413 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003414}
3415#endif /* HAVE_LCHOWN */
3416
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003417
Barry Warsaw53699e91996-12-10 23:23:01 +00003418static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003419posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003420{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003421 char *buf, *tmpbuf;
3422 char *cwd;
3423 const size_t chunk = 1024;
3424 size_t buflen = 0;
3425 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003426
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003427#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003429 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 wchar_t *wbuf2 = wbuf;
3431 PyObject *resobj;
3432 DWORD len;
3433 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003434 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003435 /* If the buffer is large enough, len does not include the
3436 terminating \0. If the buffer is too small, len includes
3437 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003438 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003439 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003440 if (wbuf2)
3441 len = GetCurrentDirectoryW(len, wbuf2);
3442 }
3443 Py_END_ALLOW_THREADS
3444 if (!wbuf2) {
3445 PyErr_NoMemory();
3446 return NULL;
3447 }
3448 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003449 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003450 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003451 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003452 }
3453 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003454 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003455 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 return resobj;
3457 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003458
3459 if (win32_warn_bytes_api())
3460 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003461#endif
3462
Victor Stinner4403d7d2015-04-25 00:16:10 +02003463 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003464 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003465 do {
3466 buflen += chunk;
3467 tmpbuf = PyMem_RawRealloc(buf, buflen);
3468 if (tmpbuf == NULL)
3469 break;
3470
3471 buf = tmpbuf;
3472 cwd = getcwd(buf, buflen);
3473 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003474 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003475
3476 if (cwd == NULL) {
3477 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003478 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003479 }
3480
Victor Stinner8c62be82010-05-06 00:08:46 +00003481 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003482 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3483 else
3484 obj = PyUnicode_DecodeFSDefault(buf);
3485 PyMem_RawFree(buf);
3486
3487 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003488}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003489
3490PyDoc_STRVAR(posix_getcwd__doc__,
3491"getcwd() -> path\n\n\
3492Return a unicode string representing the current working directory.");
3493
3494static PyObject *
3495posix_getcwd_unicode(PyObject *self)
3496{
3497 return posix_getcwd(0);
3498}
3499
3500PyDoc_STRVAR(posix_getcwdb__doc__,
3501"getcwdb() -> path\n\n\
3502Return a bytes string representing the current working directory.");
3503
3504static PyObject *
3505posix_getcwd_bytes(PyObject *self)
3506{
3507 return posix_getcwd(1);
3508}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003509
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3511#define HAVE_LINK 1
3512#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003513
Guido van Rossumb6775db1994-08-01 11:34:53 +00003514#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003515PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003516"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3517Create a hard link to a file.\n\
3518\n\
3519If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3520 descriptor open to a directory, and the respective path string (src or dst)\n\
3521 should be relative; the path will then be relative to that directory.\n\
3522If follow_symlinks is False, and the last element of src is a symbolic\n\
3523 link, link will create a link to the symbolic link itself instead of the\n\
3524 file the link points to.\n\
3525src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3526 platform. If they are unavailable, using them will raise a\n\
3527 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003528
Barry Warsaw53699e91996-12-10 23:23:01 +00003529static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003531{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 path_t src, dst;
3533 int src_dir_fd = DEFAULT_DIR_FD;
3534 int dst_dir_fd = DEFAULT_DIR_FD;
3535 int follow_symlinks = 1;
3536 PyObject *return_value = NULL;
3537 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3538 "follow_symlinks", NULL};
3539#ifdef MS_WINDOWS
3540 BOOL result;
3541#else
3542 int result;
3543#endif
3544
3545 memset(&src, 0, sizeof(src));
3546 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003547 src.function_name = "link";
3548 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3550 path_converter, &src,
3551 path_converter, &dst,
3552 dir_fd_converter, &src_dir_fd,
3553 dir_fd_converter, &dst_dir_fd,
3554 &follow_symlinks))
3555 return NULL;
3556
3557#ifndef HAVE_LINKAT
3558 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3559 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3560 goto exit;
3561 }
3562#endif
3563
3564 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3565 PyErr_SetString(PyExc_NotImplementedError,
3566 "link: src and dst must be the same type");
3567 goto exit;
3568 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003569
Brian Curtin1b9df392010-11-24 20:24:31 +00003570#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003571 Py_BEGIN_ALLOW_THREADS
3572 if (src.wide)
3573 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3574 else
3575 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3576 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003577
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08003579 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003581 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003582#else
3583 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003584#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003585 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3586 (dst_dir_fd != DEFAULT_DIR_FD) ||
3587 (!follow_symlinks))
3588 result = linkat(src_dir_fd, src.narrow,
3589 dst_dir_fd, dst.narrow,
3590 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3591 else
3592#endif
3593 result = link(src.narrow, dst.narrow);
3594 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003595
Larry Hastings9cf065c2012-06-22 16:30:09 -07003596 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08003597 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003599 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003600#endif
3601
3602 return_value = Py_None;
3603 Py_INCREF(Py_None);
3604
3605exit:
3606 path_cleanup(&src);
3607 path_cleanup(&dst);
3608 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003609}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003610#endif
3611
Brian Curtin1b9df392010-11-24 20:24:31 +00003612
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003613
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003614PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003615"listdir(path='.') -> list_of_filenames\n\n\
3616Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003617The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003618entries '.' and '..' even if they are present in the directory.\n\
3619\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003620path can be specified as either str or bytes. If path is bytes,\n\
3621 the filenames returned will also be bytes; in all other circumstances\n\
3622 the filenames returned will be str.\n\
3623On some platforms, path may also be specified as an open file descriptor;\n\
3624 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003626
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003627#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003628static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003629_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003630{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003631 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632 PyObject *v;
3633 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3634 BOOL result;
3635 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003636 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003637 char *bufptr = namebuf;
3638 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003639 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003640 PyObject *po = NULL;
3641 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003642
Gregory P. Smith40a21602013-03-20 20:52:50 -07003643 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003644 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003645 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003646
Gregory P. Smith40a21602013-03-20 20:52:50 -07003647 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003648 po_wchars = L".";
3649 len = 1;
3650 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003651 po_wchars = path->wide;
3652 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003653 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003654 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003655 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003656 if (!wnamebuf) {
3657 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003658 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003659 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003660 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003662 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003663 if (wch != SEP && wch != ALTSEP && wch != L':')
3664 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003665 wcscpy(wnamebuf + len, L"*.*");
3666 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003667 if ((list = PyList_New(0)) == NULL) {
3668 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003669 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003670 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003672 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003673 if (hFindFile == INVALID_HANDLE_VALUE) {
3674 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003675 if (error == ERROR_FILE_NOT_FOUND)
3676 goto exit;
3677 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003678 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003679 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003680 }
3681 do {
3682 /* Skip over . and .. */
3683 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3684 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003685 v = PyUnicode_FromWideChar(wFileData.cFileName,
3686 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003687 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003688 Py_DECREF(list);
3689 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003690 break;
3691 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003692 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003693 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003694 Py_DECREF(list);
3695 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 break;
3697 }
3698 Py_DECREF(v);
3699 }
3700 Py_BEGIN_ALLOW_THREADS
3701 result = FindNextFileW(hFindFile, &wFileData);
3702 Py_END_ALLOW_THREADS
3703 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3704 it got to the end of the directory. */
3705 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003706 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003707 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003708 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 }
3710 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003711
Larry Hastings9cf065c2012-06-22 16:30:09 -07003712 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003713 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003714 strcpy(namebuf, path->narrow);
3715 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003716 if (len > 0) {
3717 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003718 if (ch != '\\' && ch != '/' && ch != ':')
3719 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003720 strcpy(namebuf + len, "*.*");
3721 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003722
Larry Hastings9cf065c2012-06-22 16:30:09 -07003723 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003724 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003725
Antoine Pitroub73caab2010-08-09 23:39:31 +00003726 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003727 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003728 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003729 if (hFindFile == INVALID_HANDLE_VALUE) {
3730 int error = GetLastError();
3731 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003732 goto exit;
3733 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003734 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003735 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003736 }
3737 do {
3738 /* Skip over . and .. */
3739 if (strcmp(FileData.cFileName, ".") != 0 &&
3740 strcmp(FileData.cFileName, "..") != 0) {
3741 v = PyBytes_FromString(FileData.cFileName);
3742 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003743 Py_DECREF(list);
3744 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003745 break;
3746 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003747 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003748 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003749 Py_DECREF(list);
3750 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003751 break;
3752 }
3753 Py_DECREF(v);
3754 }
3755 Py_BEGIN_ALLOW_THREADS
3756 result = FindNextFile(hFindFile, &FileData);
3757 Py_END_ALLOW_THREADS
3758 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3759 it got to the end of the directory. */
3760 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003761 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003762 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003763 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003764 }
3765 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003766
Larry Hastings9cf065c2012-06-22 16:30:09 -07003767exit:
3768 if (hFindFile != INVALID_HANDLE_VALUE) {
3769 if (FindClose(hFindFile) == FALSE) {
3770 if (list != NULL) {
3771 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003772 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003773 }
3774 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003775 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003776 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003777
Larry Hastings9cf065c2012-06-22 16:30:09 -07003778 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003779} /* end of _listdir_windows_no_opendir */
3780
3781#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3782
3783static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003784_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003785{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003786 PyObject *v;
3787 DIR *dirp = NULL;
3788 struct dirent *ep;
3789 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003790#ifdef HAVE_FDOPENDIR
3791 int fd = -1;
3792#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003793
Victor Stinner8c62be82010-05-06 00:08:46 +00003794 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003795#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003796 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003797 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003798 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003799 if (fd == -1)
3800 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003801
Larry Hastingsfdaea062012-06-25 04:42:23 -07003802 return_str = 1;
3803
Larry Hastings9cf065c2012-06-22 16:30:09 -07003804 Py_BEGIN_ALLOW_THREADS
3805 dirp = fdopendir(fd);
3806 Py_END_ALLOW_THREADS
3807 }
3808 else
3809#endif
3810 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003811 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003812 if (path->narrow) {
3813 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003814 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003815 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003816 }
3817 else {
3818 name = ".";
3819 return_str = 1;
3820 }
3821
Larry Hastings9cf065c2012-06-22 16:30:09 -07003822 Py_BEGIN_ALLOW_THREADS
3823 dirp = opendir(name);
3824 Py_END_ALLOW_THREADS
3825 }
3826
3827 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003828 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003829#ifdef HAVE_FDOPENDIR
3830 if (fd != -1) {
3831 Py_BEGIN_ALLOW_THREADS
3832 close(fd);
3833 Py_END_ALLOW_THREADS
3834 }
3835#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003836 goto exit;
3837 }
3838 if ((list = PyList_New(0)) == NULL) {
3839 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003840 }
3841 for (;;) {
3842 errno = 0;
3843 Py_BEGIN_ALLOW_THREADS
3844 ep = readdir(dirp);
3845 Py_END_ALLOW_THREADS
3846 if (ep == NULL) {
3847 if (errno == 0) {
3848 break;
3849 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003850 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003851 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003852 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003853 }
3854 }
3855 if (ep->d_name[0] == '.' &&
3856 (NAMLEN(ep) == 1 ||
3857 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3858 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003859 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003860 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3861 else
3862 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003863 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003864 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003865 break;
3866 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003867 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003868 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003869 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003870 break;
3871 }
3872 Py_DECREF(v);
3873 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003874
Larry Hastings9cf065c2012-06-22 16:30:09 -07003875exit:
3876 if (dirp != NULL) {
3877 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003878#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003879 if (fd > -1)
3880 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003881#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003882 closedir(dirp);
3883 Py_END_ALLOW_THREADS
3884 }
3885
Larry Hastings9cf065c2012-06-22 16:30:09 -07003886 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003887} /* end of _posix_listdir */
3888#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003889
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003890static PyObject *
3891posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3892{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003893 path_t path;
3894 PyObject *list = NULL;
3895 static char *keywords[] = {"path", NULL};
3896 PyObject *return_value;
3897
3898 memset(&path, 0, sizeof(path));
3899 path.function_name = "listdir";
3900 path.nullable = 1;
3901#ifdef HAVE_FDOPENDIR
3902 path.allow_fd = 1;
3903 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003904#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003905
3906 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3907 path_converter, &path)) {
3908 return NULL;
3909 }
3910
3911#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3912 return_value = _listdir_windows_no_opendir(&path, list);
3913#else
3914 return_value = _posix_listdir(&path, list);
3915#endif
3916 path_cleanup(&path);
3917 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003918}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003919
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003920#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003921/* A helper function for abspath on win32 */
3922static PyObject *
3923posix__getfullpathname(PyObject *self, PyObject *args)
3924{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003925 const char *path;
Victor Stinner75875072013-11-24 19:23:25 +01003926 char outbuf[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00003927 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003928 PyObject *po;
3929
3930 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3931 {
3932 wchar_t *wpath;
Victor Stinner75875072013-11-24 19:23:25 +01003933 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003934 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003935 DWORD result;
3936 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003937
3938 wpath = PyUnicode_AsUnicode(po);
3939 if (wpath == NULL)
3940 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003941 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003942 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003943 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003944 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003945 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003946 if (!woutbufp)
3947 return PyErr_NoMemory();
3948 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3949 }
3950 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003951 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003953 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003954 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003955 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003956 return v;
3957 }
3958 /* Drop the argument parsing error as narrow strings
3959 are also valid. */
3960 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003961
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003962 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3963 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003964 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003965 if (win32_warn_bytes_api())
3966 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003967 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003968 outbuf, &temp)) {
3969 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003970 return NULL;
3971 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003972 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3973 return PyUnicode_Decode(outbuf, strlen(outbuf),
3974 Py_FileSystemDefaultEncoding, NULL);
3975 }
3976 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003977} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003978
Brian Curtind25aef52011-06-13 15:16:04 -05003979
Brian Curtinf5e76d02010-11-24 13:14:05 +00003980
Brian Curtind40e6f72010-07-08 21:39:08 +00003981/* A helper function for samepath on windows */
3982static PyObject *
3983posix__getfinalpathname(PyObject *self, PyObject *args)
3984{
3985 HANDLE hFile;
3986 int buf_size;
3987 wchar_t *target_path;
3988 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003989 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003990 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003991
Victor Stinnereb5657a2011-09-30 01:44:27 +02003992 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003993 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003994 path = PyUnicode_AsUnicode(po);
3995 if (path == NULL)
3996 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003997
3998 if(!check_GetFinalPathNameByHandle()) {
3999 /* If the OS doesn't have GetFinalPathNameByHandle, return a
4000 NotImplementedError. */
4001 return PyErr_Format(PyExc_NotImplementedError,
4002 "GetFinalPathNameByHandle not available on this platform");
4003 }
4004
4005 hFile = CreateFileW(
4006 path,
4007 0, /* desired access */
4008 0, /* share mode */
4009 NULL, /* security attributes */
4010 OPEN_EXISTING,
4011 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4012 FILE_FLAG_BACKUP_SEMANTICS,
4013 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004014
Victor Stinnereb5657a2011-09-30 01:44:27 +02004015 if(hFile == INVALID_HANDLE_VALUE)
4016 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00004017
4018 /* We have a good handle to the target, use it to determine the
4019 target path name. */
4020 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
4021
4022 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02004023 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00004024
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004025 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00004026 if(!target_path)
4027 return PyErr_NoMemory();
4028
4029 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
4030 buf_size, VOLUME_NAME_DOS);
4031 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02004032 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00004033
4034 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02004035 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00004036
4037 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004038 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02004039 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004040 return result;
4041
4042} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00004043
Brian Curtin95d028f2011-06-09 09:10:38 -05004044PyDoc_STRVAR(posix__isdir__doc__,
4045"Return true if the pathname refers to an existing directory.");
4046
Brian Curtin9c669cc2011-06-08 18:17:18 -05004047static PyObject *
4048posix__isdir(PyObject *self, PyObject *args)
4049{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004050 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004051 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004052 DWORD attributes;
4053
4054 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02004055 wchar_t *wpath = PyUnicode_AsUnicode(po);
4056 if (wpath == NULL)
4057 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004058
4059 attributes = GetFileAttributesW(wpath);
4060 if (attributes == INVALID_FILE_ATTRIBUTES)
4061 Py_RETURN_FALSE;
4062 goto check;
4063 }
4064 /* Drop the argument parsing error as narrow strings
4065 are also valid. */
4066 PyErr_Clear();
4067
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004068 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05004069 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004070 if (win32_warn_bytes_api())
4071 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004072 attributes = GetFileAttributesA(path);
4073 if (attributes == INVALID_FILE_ATTRIBUTES)
4074 Py_RETURN_FALSE;
4075
4076check:
4077 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4078 Py_RETURN_TRUE;
4079 else
4080 Py_RETURN_FALSE;
4081}
Tim Golden6b528062013-08-01 12:44:00 +01004082
4083PyDoc_STRVAR(posix__getvolumepathname__doc__,
4084"Return volume mount point of the specified path.");
4085
4086/* A helper function for ismount on windows */
4087static PyObject *
4088posix__getvolumepathname(PyObject *self, PyObject *args)
4089{
4090 PyObject *po, *result;
4091 wchar_t *path, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004092 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004093 BOOL ret;
4094
4095 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
4096 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004097 path = PyUnicode_AsUnicodeAndSize(po, &buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004098 if (path == NULL)
4099 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004100 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01004101
4102 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01004103 buflen = Py_MAX(buflen, MAX_PATH);
4104
4105 if (buflen > DWORD_MAX) {
4106 PyErr_SetString(PyExc_OverflowError, "path too long");
4107 return NULL;
4108 }
4109
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004110 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004111 if (mountpath == NULL)
4112 return PyErr_NoMemory();
4113
4114 Py_BEGIN_ALLOW_THREADS
Christian Heimes85ba92a2013-11-18 10:30:42 +01004115 ret = GetVolumePathNameW(path, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004116 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004117 Py_END_ALLOW_THREADS
4118
4119 if (!ret) {
4120 result = win32_error_object("_getvolumepathname", po);
4121 goto exit;
4122 }
4123 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4124
4125exit:
4126 PyMem_Free(mountpath);
4127 return result;
4128}
4129/* end of posix__getvolumepathname */
4130
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004131#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004132
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004133PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4135Create a directory.\n\
4136\n\
4137If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4138 and path should be relative; path will then be relative to that directory.\n\
4139dir_fd may not be implemented on your platform.\n\
4140 If it is unavailable, using it will raise a NotImplementedError.\n\
4141\n\
4142The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004143
Barry Warsaw53699e91996-12-10 23:23:01 +00004144static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004145posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004146{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004147 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004148 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004149 int dir_fd = DEFAULT_DIR_FD;
4150 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
4151 PyObject *return_value = NULL;
4152 int result;
4153
4154 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004155 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004156 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4157 path_converter, &path, &mode,
4158#ifdef HAVE_MKDIRAT
4159 dir_fd_converter, &dir_fd
4160#else
4161 dir_fd_unavailable, &dir_fd
4162#endif
4163 ))
4164 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004165
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004166#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004167 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004168 if (path.wide)
4169 result = CreateDirectoryW(path.wide, NULL);
4170 else
4171 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004172 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004173
Larry Hastings9cf065c2012-06-22 16:30:09 -07004174 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004175 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004176 goto exit;
4177 }
4178#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004179 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004180#if HAVE_MKDIRAT
4181 if (dir_fd != DEFAULT_DIR_FD)
4182 result = mkdirat(dir_fd, path.narrow, mode);
4183 else
4184#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004185#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004186 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004187#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004188 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004189#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004190 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004191 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01004192 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004193 goto exit;
4194 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004195#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004196 return_value = Py_None;
4197 Py_INCREF(Py_None);
4198exit:
4199 path_cleanup(&path);
4200 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004201}
4202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004203
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004204/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4205#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004206#include <sys/resource.h>
4207#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004208
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004209
4210#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004211PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004212"nice(inc) -> new_priority\n\n\
4213Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004214
Barry Warsaw53699e91996-12-10 23:23:01 +00004215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004216posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004217{
Victor Stinner8c62be82010-05-06 00:08:46 +00004218 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004219
Victor Stinner8c62be82010-05-06 00:08:46 +00004220 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4221 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004222
Victor Stinner8c62be82010-05-06 00:08:46 +00004223 /* There are two flavours of 'nice': one that returns the new
4224 priority (as required by almost all standards out there) and the
4225 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4226 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004227
Victor Stinner8c62be82010-05-06 00:08:46 +00004228 If we are of the nice family that returns the new priority, we
4229 need to clear errno before the call, and check if errno is filled
4230 before calling posix_error() on a returnvalue of -1, because the
4231 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004232
Victor Stinner8c62be82010-05-06 00:08:46 +00004233 errno = 0;
4234 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004235#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004236 if (value == 0)
4237 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004238#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004239 if (value == -1 && errno != 0)
4240 /* either nice() or getpriority() returned an error */
4241 return posix_error();
4242 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004243}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004244#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004245
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004246
4247#ifdef HAVE_GETPRIORITY
4248PyDoc_STRVAR(posix_getpriority__doc__,
4249"getpriority(which, who) -> current_priority\n\n\
4250Get program scheduling priority.");
4251
4252static PyObject *
4253posix_getpriority(PyObject *self, PyObject *args)
4254{
4255 int which, who, retval;
4256
4257 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4258 return NULL;
4259 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004260 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004261 if (errno != 0)
4262 return posix_error();
4263 return PyLong_FromLong((long)retval);
4264}
4265#endif /* HAVE_GETPRIORITY */
4266
4267
4268#ifdef HAVE_SETPRIORITY
4269PyDoc_STRVAR(posix_setpriority__doc__,
4270"setpriority(which, who, prio) -> None\n\n\
4271Set program scheduling priority.");
4272
4273static PyObject *
4274posix_setpriority(PyObject *self, PyObject *args)
4275{
4276 int which, who, prio, retval;
4277
4278 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4279 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004280 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004281 if (retval == -1)
4282 return posix_error();
4283 Py_RETURN_NONE;
4284}
4285#endif /* HAVE_SETPRIORITY */
4286
4287
Barry Warsaw53699e91996-12-10 23:23:01 +00004288static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004289internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004290{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004291 char *function_name = is_replace ? "replace" : "rename";
4292 path_t src;
4293 path_t dst;
4294 int src_dir_fd = DEFAULT_DIR_FD;
4295 int dst_dir_fd = DEFAULT_DIR_FD;
4296 int dir_fd_specified;
4297 PyObject *return_value = NULL;
4298 char format[24];
4299 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4300
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004301#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004302 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004303 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004304#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004305 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004306#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004307
4308 memset(&src, 0, sizeof(src));
4309 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01004310 src.function_name = function_name;
4311 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004312 strcpy(format, "O&O&|$O&O&:");
4313 strcat(format, function_name);
4314 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4315 path_converter, &src,
4316 path_converter, &dst,
4317 dir_fd_converter, &src_dir_fd,
4318 dir_fd_converter, &dst_dir_fd))
4319 return NULL;
4320
4321 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4322 (dst_dir_fd != DEFAULT_DIR_FD);
4323#ifndef HAVE_RENAMEAT
4324 if (dir_fd_specified) {
4325 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4326 goto exit;
4327 }
4328#endif
4329
4330 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4331 PyErr_Format(PyExc_ValueError,
4332 "%s: src and dst must be the same type", function_name);
4333 goto exit;
4334 }
4335
4336#ifdef MS_WINDOWS
4337 Py_BEGIN_ALLOW_THREADS
4338 if (src.wide)
4339 result = MoveFileExW(src.wide, dst.wide, flags);
4340 else
4341 result = MoveFileExA(src.narrow, dst.narrow, flags);
4342 Py_END_ALLOW_THREADS
4343
4344 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08004345 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004346 goto exit;
4347 }
4348
4349#else
4350 Py_BEGIN_ALLOW_THREADS
4351#ifdef HAVE_RENAMEAT
4352 if (dir_fd_specified)
4353 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4354 else
4355#endif
4356 result = rename(src.narrow, dst.narrow);
4357 Py_END_ALLOW_THREADS
4358
4359 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08004360 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004361 goto exit;
4362 }
4363#endif
4364
4365 Py_INCREF(Py_None);
4366 return_value = Py_None;
4367exit:
4368 path_cleanup(&src);
4369 path_cleanup(&dst);
4370 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004371}
4372
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004373PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004374"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4375Rename a file or directory.\n\
4376\n\
4377If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4378 descriptor open to a directory, and the respective path string (src or dst)\n\
4379 should be relative; the path will then be relative to that directory.\n\
4380src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4381 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004382
4383static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004384posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004385{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004386 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004387}
4388
4389PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004390"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4391Rename a file or directory, overwriting the destination.\n\
4392\n\
4393If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4394 descriptor open to a directory, and the respective path string (src or dst)\n\
4395 should be relative; the path will then be relative to that directory.\n\
4396src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4397 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004398
4399static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004400posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004401{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004402 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004403}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004404
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004405PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004406"rmdir(path, *, dir_fd=None)\n\n\
4407Remove a directory.\n\
4408\n\
4409If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4410 and path should be relative; path will then be relative to that directory.\n\
4411dir_fd may not be implemented on your platform.\n\
4412 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004413
Barry Warsaw53699e91996-12-10 23:23:01 +00004414static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004415posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004416{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004417 path_t path;
4418 int dir_fd = DEFAULT_DIR_FD;
4419 static char *keywords[] = {"path", "dir_fd", NULL};
4420 int result;
4421 PyObject *return_value = NULL;
4422
4423 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004424 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004425 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4426 path_converter, &path,
4427#ifdef HAVE_UNLINKAT
4428 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004429#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004430 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004431#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004432 ))
4433 return NULL;
4434
4435 Py_BEGIN_ALLOW_THREADS
4436#ifdef MS_WINDOWS
4437 if (path.wide)
4438 result = RemoveDirectoryW(path.wide);
4439 else
4440 result = RemoveDirectoryA(path.narrow);
4441 result = !result; /* Windows, success=1, UNIX, success=0 */
4442#else
4443#ifdef HAVE_UNLINKAT
4444 if (dir_fd != DEFAULT_DIR_FD)
4445 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4446 else
4447#endif
4448 result = rmdir(path.narrow);
4449#endif
4450 Py_END_ALLOW_THREADS
4451
4452 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004453 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004454 goto exit;
4455 }
4456
4457 return_value = Py_None;
4458 Py_INCREF(Py_None);
4459
4460exit:
4461 path_cleanup(&path);
4462 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004463}
4464
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004465
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004466#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004467PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004468"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004469Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004470
Barry Warsaw53699e91996-12-10 23:23:01 +00004471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004472posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004473{
Victor Stinner8c62be82010-05-06 00:08:46 +00004474 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004475#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004476 wchar_t *command;
4477 if (!PyArg_ParseTuple(args, "u:system", &command))
4478 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004479
Victor Stinner8c62be82010-05-06 00:08:46 +00004480 Py_BEGIN_ALLOW_THREADS
4481 sts = _wsystem(command);
4482 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004483#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004484 PyObject *command_obj;
4485 char *command;
4486 if (!PyArg_ParseTuple(args, "O&:system",
4487 PyUnicode_FSConverter, &command_obj))
4488 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004489
Victor Stinner8c62be82010-05-06 00:08:46 +00004490 command = PyBytes_AsString(command_obj);
4491 Py_BEGIN_ALLOW_THREADS
4492 sts = system(command);
4493 Py_END_ALLOW_THREADS
4494 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004495#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004496 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004497}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004498#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004499
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004500
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004501PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004502"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004503Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004504
Barry Warsaw53699e91996-12-10 23:23:01 +00004505static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004506posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004507{
Victor Stinner8c62be82010-05-06 00:08:46 +00004508 int i;
4509 if (!PyArg_ParseTuple(args, "i:umask", &i))
4510 return NULL;
4511 i = (int)umask(i);
4512 if (i < 0)
4513 return posix_error();
4514 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004515}
4516
Brian Curtind40e6f72010-07-08 21:39:08 +00004517#ifdef MS_WINDOWS
4518
4519/* override the default DeleteFileW behavior so that directory
4520symlinks can be removed with this function, the same as with
4521Unix symlinks */
4522BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4523{
4524 WIN32_FILE_ATTRIBUTE_DATA info;
4525 WIN32_FIND_DATAW find_data;
4526 HANDLE find_data_handle;
4527 int is_directory = 0;
4528 int is_link = 0;
4529
4530 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4531 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004532
Brian Curtind40e6f72010-07-08 21:39:08 +00004533 /* Get WIN32_FIND_DATA structure for the path to determine if
4534 it is a symlink */
4535 if(is_directory &&
4536 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4537 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4538
4539 if(find_data_handle != INVALID_HANDLE_VALUE) {
4540 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4541 FindClose(find_data_handle);
4542 }
4543 }
4544 }
4545
4546 if (is_directory && is_link)
4547 return RemoveDirectoryW(lpFileName);
4548
4549 return DeleteFileW(lpFileName);
4550}
4551#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004552
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004553PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004554"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004555Remove a file (same as remove()).\n\
4556\n\
4557If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4558 and path should be relative; path will then be relative to that directory.\n\
4559dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004560 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004561
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004562PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004563"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004564Remove a file (same as unlink()).\n\
4565\n\
4566If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4567 and path should be relative; path will then be relative to that directory.\n\
4568dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004569 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004570
Barry Warsaw53699e91996-12-10 23:23:01 +00004571static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004573{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574 path_t path;
4575 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004576 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004577 int result;
4578 PyObject *return_value = NULL;
4579
4580 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004581 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004582 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004583 path_converter, &path,
4584#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004585 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004586#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004587 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004588#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004589 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590 return NULL;
4591
4592 Py_BEGIN_ALLOW_THREADS
4593#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004594 if (path.wide)
4595 result = Py_DeleteFileW(path.wide);
4596 else
4597 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598 result = !result; /* Windows, success=1, UNIX, success=0 */
4599#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004600#ifdef HAVE_UNLINKAT
4601 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004602 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004603 else
4604#endif /* HAVE_UNLINKAT */
4605 result = unlink(path.narrow);
4606#endif
4607 Py_END_ALLOW_THREADS
4608
4609 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004610 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004611 goto exit;
4612 }
4613
4614 return_value = Py_None;
4615 Py_INCREF(Py_None);
4616
4617exit:
4618 path_cleanup(&path);
4619 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004620}
4621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004623PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004624"uname() -> uname_result\n\n\
4625Return an object identifying the current operating system.\n\
4626The object behaves like a named tuple with the following fields:\n\
4627 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004628
Larry Hastings605a62d2012-06-24 04:33:36 -07004629static PyStructSequence_Field uname_result_fields[] = {
4630 {"sysname", "operating system name"},
4631 {"nodename", "name of machine on network (implementation-defined)"},
4632 {"release", "operating system release"},
4633 {"version", "operating system version"},
4634 {"machine", "hardware identifier"},
4635 {NULL}
4636};
4637
4638PyDoc_STRVAR(uname_result__doc__,
4639"uname_result: Result from os.uname().\n\n\
4640This object may be accessed either as a tuple of\n\
4641 (sysname, nodename, release, version, machine),\n\
4642or via the attributes sysname, nodename, release, version, and machine.\n\
4643\n\
4644See os.uname for more information.");
4645
4646static PyStructSequence_Desc uname_result_desc = {
4647 "uname_result", /* name */
4648 uname_result__doc__, /* doc */
4649 uname_result_fields,
4650 5
4651};
4652
4653static PyTypeObject UnameResultType;
4654
4655
4656#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004657static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004658posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004659{
Victor Stinner8c62be82010-05-06 00:08:46 +00004660 struct utsname u;
4661 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004662 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004663
Victor Stinner8c62be82010-05-06 00:08:46 +00004664 Py_BEGIN_ALLOW_THREADS
4665 res = uname(&u);
4666 Py_END_ALLOW_THREADS
4667 if (res < 0)
4668 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004669
4670 value = PyStructSequence_New(&UnameResultType);
4671 if (value == NULL)
4672 return NULL;
4673
4674#define SET(i, field) \
4675 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004676 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004677 if (!o) { \
4678 Py_DECREF(value); \
4679 return NULL; \
4680 } \
4681 PyStructSequence_SET_ITEM(value, i, o); \
4682 } \
4683
4684 SET(0, u.sysname);
4685 SET(1, u.nodename);
4686 SET(2, u.release);
4687 SET(3, u.version);
4688 SET(4, u.machine);
4689
4690#undef SET
4691
4692 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004693}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004694#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004695
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004696
Larry Hastings9cf065c2012-06-22 16:30:09 -07004697PyDoc_STRVAR(posix_utime__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00004698"utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004699Set the access and modified time of path.\n\
4700\n\
4701path may always be specified as a string.\n\
4702On some platforms, path may also be specified as an open file descriptor.\n\
4703 If this functionality is unavailable, using it raises an exception.\n\
4704\n\
4705If times is not None, it must be a tuple (atime, mtime);\n\
4706 atime and mtime should be expressed as float seconds since the epoch.\n\
Martin Panterbf19d162015-09-09 01:01:13 +00004707If ns is specified, it must be a tuple (atime_ns, mtime_ns);\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4709 since the epoch.\n\
Martin Panterbf19d162015-09-09 01:01:13 +00004710If times is None and ns is unspecified, utime uses the current time.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004711Specifying tuples for both times and ns is an error.\n\
4712\n\
4713If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4714 and path should be relative; path will then be relative to that directory.\n\
4715If follow_symlinks is False, and the last element of the path is a symbolic\n\
4716 link, utime will modify the symbolic link itself instead of the file the\n\
4717 link points to.\n\
4718It is an error to use dir_fd or follow_symlinks when specifying path\n\
4719 as an open file descriptor.\n\
4720dir_fd and follow_symlinks may not be available on your platform.\n\
4721 If they are unavailable, using them will raise a NotImplementedError.");
4722
4723typedef struct {
4724 int now;
4725 time_t atime_s;
4726 long atime_ns;
4727 time_t mtime_s;
4728 long mtime_ns;
4729} utime_t;
4730
4731/*
Victor Stinner484df002014-10-09 13:52:31 +02004732 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004733 * they also intentionally leak the declaration of a pointer named "time"
4734 */
4735#define UTIME_TO_TIMESPEC \
4736 struct timespec ts[2]; \
4737 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004738 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004739 time = NULL; \
4740 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004741 ts[0].tv_sec = ut->atime_s; \
4742 ts[0].tv_nsec = ut->atime_ns; \
4743 ts[1].tv_sec = ut->mtime_s; \
4744 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 time = ts; \
4746 } \
4747
4748#define UTIME_TO_TIMEVAL \
4749 struct timeval tv[2]; \
4750 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004751 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004752 time = NULL; \
4753 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004754 tv[0].tv_sec = ut->atime_s; \
4755 tv[0].tv_usec = ut->atime_ns / 1000; \
4756 tv[1].tv_sec = ut->mtime_s; \
4757 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 time = tv; \
4759 } \
4760
4761#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004762 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004764 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 time = NULL; \
4766 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004767 u.actime = ut->atime_s; \
4768 u.modtime = ut->mtime_s; \
4769 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770 }
4771
4772#define UTIME_TO_TIME_T \
4773 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004774 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004775 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004776 time = NULL; \
4777 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004778 timet[0] = ut->atime_s; \
4779 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004780 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004781 } \
4782
4783
Victor Stinner528a9ab2015-09-03 21:30:26 +02004784#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004785
4786static int
Victor Stinner484df002014-10-09 13:52:31 +02004787utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004788{
4789#ifdef HAVE_UTIMENSAT
4790 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4791 UTIME_TO_TIMESPEC;
4792 return utimensat(dir_fd, path, time, flags);
4793#elif defined(HAVE_FUTIMESAT)
4794 UTIME_TO_TIMEVAL;
4795 /*
4796 * follow_symlinks will never be false here;
4797 * we only allow !follow_symlinks and dir_fd together
4798 * if we have utimensat()
4799 */
4800 assert(follow_symlinks);
4801 return futimesat(dir_fd, path, time);
4802#endif
4803}
4804
4805#endif
4806
Victor Stinner528a9ab2015-09-03 21:30:26 +02004807#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004808
4809static int
Victor Stinner484df002014-10-09 13:52:31 +02004810utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811{
4812#ifdef HAVE_FUTIMENS
4813 UTIME_TO_TIMESPEC;
4814 return futimens(fd, time);
4815#else
4816 UTIME_TO_TIMEVAL;
4817 return futimes(fd, time);
4818#endif
4819}
4820
4821#endif
4822
4823
4824#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4825 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4826
4827#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4828
4829static int
Victor Stinner484df002014-10-09 13:52:31 +02004830utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004831{
4832#ifdef HAVE_UTIMENSAT
4833 UTIME_TO_TIMESPEC;
4834 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4835#else
4836 UTIME_TO_TIMEVAL;
4837 return lutimes(path, time);
4838#endif
4839}
4840
4841#endif
4842
4843#ifndef MS_WINDOWS
4844
4845static int
Victor Stinner484df002014-10-09 13:52:31 +02004846utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004847{
4848#ifdef HAVE_UTIMENSAT
4849 UTIME_TO_TIMESPEC;
4850 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4851#elif defined(HAVE_UTIMES)
4852 UTIME_TO_TIMEVAL;
4853 return utimes(path, time);
4854#elif defined(HAVE_UTIME_H)
4855 UTIME_TO_UTIMBUF;
4856 return utime(path, time);
4857#else
4858 UTIME_TO_TIME_T;
4859 return utime(path, time);
4860#endif
4861}
4862
4863#endif
4864
Larry Hastings76ad59b2012-05-03 00:30:07 -07004865static int
4866split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4867{
4868 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004869 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004870 divmod = PyNumber_Divmod(py_long, billion);
4871 if (!divmod)
4872 goto exit;
4873 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4874 if ((*s == -1) && PyErr_Occurred())
4875 goto exit;
4876 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004877 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004878 goto exit;
4879
4880 result = 1;
4881exit:
4882 Py_XDECREF(divmod);
4883 return result;
4884}
4885
Larry Hastings9cf065c2012-06-22 16:30:09 -07004886static PyObject *
4887posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004888{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004889 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004890 PyObject *times = NULL;
4891 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004892 int dir_fd = DEFAULT_DIR_FD;
4893 int follow_symlinks = 1;
4894 char *keywords[] = {"path", "times", "ns", "dir_fd",
4895 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004896
Larry Hastings9cf065c2012-06-22 16:30:09 -07004897 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004898
Larry Hastings9cf065c2012-06-22 16:30:09 -07004899#ifdef MS_WINDOWS
4900 HANDLE hFile;
4901 FILETIME atime, mtime;
4902#else
4903 int result;
4904#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004905
Larry Hastings9cf065c2012-06-22 16:30:09 -07004906 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004907
Larry Hastings9cf065c2012-06-22 16:30:09 -07004908 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004909 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004910 memset(&utime, 0, sizeof(utime_t));
Victor Stinner528a9ab2015-09-03 21:30:26 +02004911#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004912 path.allow_fd = 1;
4913#endif
4914 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4915 "O&|O$OO&p:utime", keywords,
4916 path_converter, &path,
4917 &times, &ns,
Victor Stinner528a9ab2015-09-03 21:30:26 +02004918#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004919 dir_fd_converter, &dir_fd,
4920#else
4921 dir_fd_unavailable, &dir_fd,
4922#endif
4923 &follow_symlinks
4924 ))
4925 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004926
Larry Hastings9cf065c2012-06-22 16:30:09 -07004927 if (times && (times != Py_None) && ns) {
4928 PyErr_SetString(PyExc_ValueError,
4929 "utime: you may specify either 'times'"
4930 " or 'ns' but not both");
4931 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004932 }
4933
4934 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004935 time_t a_sec, m_sec;
4936 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004937 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004938 PyErr_SetString(PyExc_TypeError,
4939 "utime: 'times' must be either"
4940 " a tuple of two ints or None");
4941 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004942 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004943 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004944 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004945 &a_sec, &a_nsec, _PyTime_ROUND_DOWN) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004946 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004947 &m_sec, &m_nsec, _PyTime_ROUND_DOWN) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004948 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004949 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004950 utime.atime_s = a_sec;
4951 utime.atime_ns = a_nsec;
4952 utime.mtime_s = m_sec;
4953 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004954 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004955 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004956 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004957 PyErr_SetString(PyExc_TypeError,
4958 "utime: 'ns' must be a tuple of two ints");
4959 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004960 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004961 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004962 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004963 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004964 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004965 &utime.mtime_s, &utime.mtime_ns)) {
4966 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004967 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004968 }
4969 else {
4970 /* times and ns are both None/unspecified. use "now". */
4971 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004972 }
4973
Larry Hastings9cf065c2012-06-22 16:30:09 -07004974#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4975 if (follow_symlinks_specified("utime", follow_symlinks))
4976 goto exit;
4977#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004978
Larry Hastings9cf065c2012-06-22 16:30:09 -07004979 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4980 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4981 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4982 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004983
Larry Hastings9cf065c2012-06-22 16:30:09 -07004984#if !defined(HAVE_UTIMENSAT)
4985 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004986 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004987 "utime: cannot use dir_fd and follow_symlinks "
4988 "together on this platform");
4989 goto exit;
4990 }
4991#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004992
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004993#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004994 Py_BEGIN_ALLOW_THREADS
4995 if (path.wide)
4996 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004997 NULL, OPEN_EXISTING,
4998 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004999 else
5000 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00005001 NULL, OPEN_EXISTING,
5002 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005003 Py_END_ALLOW_THREADS
5004 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01005005 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005006 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07005007 }
5008
Larry Hastings9cf065c2012-06-22 16:30:09 -07005009 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005010 GetSystemTimeAsFileTime(&mtime);
5011 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005012 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005013 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005014 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5015 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005016 }
5017 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5018 /* Avoid putting the file name into the error here,
5019 as that may confuse the user into believing that
5020 something is wrong with the file, when it also
5021 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005022 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005023 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005025#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005026 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005027
Larry Hastings9cf065c2012-06-22 16:30:09 -07005028#if UTIME_HAVE_NOFOLLOW_SYMLINKS
5029 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
5030 result = utime_nofollow_symlinks(&utime, path.narrow);
5031 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005032#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005033
Victor Stinner528a9ab2015-09-03 21:30:26 +02005034#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005035 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
5036 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
5037 else
5038#endif
5039
Victor Stinner528a9ab2015-09-03 21:30:26 +02005040#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005041 if (path.fd != -1)
5042 result = utime_fd(&utime, path.fd);
5043 else
5044#endif
5045
5046 result = utime_default(&utime, path.narrow);
5047
5048 Py_END_ALLOW_THREADS
5049
5050 if (result < 0) {
5051 /* see previous comment about not putting filename in error here */
5052 return_value = posix_error();
5053 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005054 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005055
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005056#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005057
5058 Py_INCREF(Py_None);
5059 return_value = Py_None;
5060
5061exit:
5062 path_cleanup(&path);
5063#ifdef MS_WINDOWS
5064 if (hFile != INVALID_HANDLE_VALUE)
5065 CloseHandle(hFile);
5066#endif
5067 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005068}
5069
Guido van Rossum3b066191991-06-04 19:40:25 +00005070/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005071
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005072PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005073"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005074Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005075
Barry Warsaw53699e91996-12-10 23:23:01 +00005076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005077posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005078{
Victor Stinner8c62be82010-05-06 00:08:46 +00005079 int sts;
5080 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5081 return NULL;
5082 _exit(sts);
5083 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005084}
5085
Martin v. Löwis114619e2002-10-07 06:44:21 +00005086#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5087static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00005088free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005089{
Victor Stinner8c62be82010-05-06 00:08:46 +00005090 Py_ssize_t i;
5091 for (i = 0; i < count; i++)
5092 PyMem_Free(array[i]);
5093 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005094}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005095
Antoine Pitrou69f71142009-05-24 21:25:49 +00005096static
Martin v. Löwis011e8422009-05-05 04:43:17 +00005097int fsconvert_strdup(PyObject *o, char**out)
5098{
Victor Stinner8c62be82010-05-06 00:08:46 +00005099 PyObject *bytes;
5100 Py_ssize_t size;
5101 if (!PyUnicode_FSConverter(o, &bytes))
5102 return 0;
5103 size = PyBytes_GET_SIZE(bytes);
5104 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01005105 if (!*out) {
5106 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01005108 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 memcpy(*out, PyBytes_AsString(bytes), size+1);
5110 Py_DECREF(bytes);
5111 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005112}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005113#endif
5114
Ross Lagerwall7807c352011-03-17 20:20:30 +02005115#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005116static char**
5117parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5118{
Victor Stinner8c62be82010-05-06 00:08:46 +00005119 char **envlist;
5120 Py_ssize_t i, pos, envc;
5121 PyObject *keys=NULL, *vals=NULL;
5122 PyObject *key, *val, *key2, *val2;
5123 char *p, *k, *v;
5124 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005125
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 i = PyMapping_Size(env);
5127 if (i < 0)
5128 return NULL;
5129 envlist = PyMem_NEW(char *, i + 1);
5130 if (envlist == NULL) {
5131 PyErr_NoMemory();
5132 return NULL;
5133 }
5134 envc = 0;
5135 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005136 if (!keys)
5137 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005138 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005139 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005140 goto error;
5141 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5142 PyErr_Format(PyExc_TypeError,
5143 "env.keys() or env.values() is not a list");
5144 goto error;
5145 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005146
Victor Stinner8c62be82010-05-06 00:08:46 +00005147 for (pos = 0; pos < i; pos++) {
5148 key = PyList_GetItem(keys, pos);
5149 val = PyList_GetItem(vals, pos);
5150 if (!key || !val)
5151 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005152
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 if (PyUnicode_FSConverter(key, &key2) == 0)
5154 goto error;
5155 if (PyUnicode_FSConverter(val, &val2) == 0) {
5156 Py_DECREF(key2);
5157 goto error;
5158 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005159
Victor Stinner8c62be82010-05-06 00:08:46 +00005160 k = PyBytes_AsString(key2);
5161 v = PyBytes_AsString(val2);
5162 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005163
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 p = PyMem_NEW(char, len);
5165 if (p == NULL) {
5166 PyErr_NoMemory();
5167 Py_DECREF(key2);
5168 Py_DECREF(val2);
5169 goto error;
5170 }
5171 PyOS_snprintf(p, len, "%s=%s", k, v);
5172 envlist[envc++] = p;
5173 Py_DECREF(key2);
5174 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 }
5176 Py_DECREF(vals);
5177 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005178
Victor Stinner8c62be82010-05-06 00:08:46 +00005179 envlist[envc] = 0;
5180 *envc_ptr = envc;
5181 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005182
5183error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005184 Py_XDECREF(keys);
5185 Py_XDECREF(vals);
5186 while (--envc >= 0)
5187 PyMem_DEL(envlist[envc]);
5188 PyMem_DEL(envlist);
5189 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005190}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005191
Ross Lagerwall7807c352011-03-17 20:20:30 +02005192static char**
5193parse_arglist(PyObject* argv, Py_ssize_t *argc)
5194{
5195 int i;
5196 char **argvlist = PyMem_NEW(char *, *argc+1);
5197 if (argvlist == NULL) {
5198 PyErr_NoMemory();
5199 return NULL;
5200 }
5201 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005202 PyObject* item = PySequence_ITEM(argv, i);
5203 if (item == NULL)
5204 goto fail;
5205 if (!fsconvert_strdup(item, &argvlist[i])) {
5206 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005207 goto fail;
5208 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005209 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005210 }
5211 argvlist[*argc] = NULL;
5212 return argvlist;
5213fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005214 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005215 free_string_array(argvlist, *argc);
5216 return NULL;
5217}
5218#endif
5219
5220#ifdef HAVE_EXECV
5221PyDoc_STRVAR(posix_execv__doc__,
5222"execv(path, args)\n\n\
5223Execute an executable path with arguments, replacing current process.\n\
5224\n\
5225 path: path of executable file\n\
5226 args: tuple or list of strings");
5227
5228static PyObject *
5229posix_execv(PyObject *self, PyObject *args)
5230{
5231 PyObject *opath;
5232 char *path;
5233 PyObject *argv;
5234 char **argvlist;
5235 Py_ssize_t argc;
5236
5237 /* execv has two arguments: (path, argv), where
5238 argv is a list or tuple of strings. */
5239
5240 if (!PyArg_ParseTuple(args, "O&O:execv",
5241 PyUnicode_FSConverter,
5242 &opath, &argv))
5243 return NULL;
5244 path = PyBytes_AsString(opath);
5245 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5246 PyErr_SetString(PyExc_TypeError,
5247 "execv() arg 2 must be a tuple or list");
5248 Py_DECREF(opath);
5249 return NULL;
5250 }
5251 argc = PySequence_Size(argv);
5252 if (argc < 1) {
5253 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5254 Py_DECREF(opath);
5255 return NULL;
5256 }
5257
5258 argvlist = parse_arglist(argv, &argc);
5259 if (argvlist == NULL) {
5260 Py_DECREF(opath);
5261 return NULL;
5262 }
5263
5264 execv(path, argvlist);
5265
5266 /* If we get here it's definitely an error */
5267
5268 free_string_array(argvlist, argc);
5269 Py_DECREF(opath);
5270 return posix_error();
5271}
5272
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005273PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005274"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005275Execute a path with arguments and environment, replacing current process.\n\
5276\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005277 path: path of executable file\n\
5278 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005279 env: dictionary of strings mapping to strings\n\
5280\n\
5281On some platforms, you may specify an open file descriptor for path;\n\
5282 execve will execute the program the file descriptor is open to.\n\
5283 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005284
Barry Warsaw53699e91996-12-10 23:23:01 +00005285static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005286posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005287{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005288 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005289 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005290 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005291 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005292 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005293 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005294
Victor Stinner8c62be82010-05-06 00:08:46 +00005295 /* execve has three arguments: (path, argv, env), where
5296 argv is a list or tuple of strings and env is a dictionary
5297 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005298
Larry Hastings9cf065c2012-06-22 16:30:09 -07005299 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005300 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005301#ifdef HAVE_FEXECVE
5302 path.allow_fd = 1;
5303#endif
5304 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5305 path_converter, &path,
5306 &argv, &env
5307 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005308 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005309
Ross Lagerwall7807c352011-03-17 20:20:30 +02005310 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005311 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005312 "execve: argv must be a tuple or list");
5313 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005315 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005316 if (!PyMapping_Check(env)) {
5317 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005318 "execve: environment must be a mapping object");
5319 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005320 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005321
Ross Lagerwall7807c352011-03-17 20:20:30 +02005322 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005323 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005324 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005325 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005326
Victor Stinner8c62be82010-05-06 00:08:46 +00005327 envlist = parse_envlist(env, &envc);
5328 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005329 goto fail;
5330
Larry Hastings9cf065c2012-06-22 16:30:09 -07005331#ifdef HAVE_FEXECVE
5332 if (path.fd > -1)
5333 fexecve(path.fd, argvlist, envlist);
5334 else
5335#endif
5336 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005337
5338 /* If we get here it's definitely an error */
5339
Victor Stinner292c8352012-10-30 02:17:38 +01005340 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005341
5342 while (--envc >= 0)
5343 PyMem_DEL(envlist[envc]);
5344 PyMem_DEL(envlist);
5345 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005346 if (argvlist)
5347 free_string_array(argvlist, argc);
5348 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005349 return NULL;
5350}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005351#endif /* HAVE_EXECV */
5352
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005353
Guido van Rossuma1065681999-01-25 23:20:23 +00005354#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005355PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005356"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005357Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005358\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005359 mode: mode of process creation\n\
5360 path: path of executable file\n\
5361 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005362
5363static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005364posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005365{
Victor Stinner8c62be82010-05-06 00:08:46 +00005366 PyObject *opath;
5367 char *path;
5368 PyObject *argv;
5369 char **argvlist;
5370 int mode, i;
5371 Py_ssize_t argc;
5372 Py_intptr_t spawnval;
5373 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005374
Victor Stinner8c62be82010-05-06 00:08:46 +00005375 /* spawnv has three arguments: (mode, path, argv), where
5376 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005377
Victor Stinner8c62be82010-05-06 00:08:46 +00005378 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5379 PyUnicode_FSConverter,
5380 &opath, &argv))
5381 return NULL;
5382 path = PyBytes_AsString(opath);
5383 if (PyList_Check(argv)) {
5384 argc = PyList_Size(argv);
5385 getitem = PyList_GetItem;
5386 }
5387 else if (PyTuple_Check(argv)) {
5388 argc = PyTuple_Size(argv);
5389 getitem = PyTuple_GetItem;
5390 }
5391 else {
5392 PyErr_SetString(PyExc_TypeError,
5393 "spawnv() arg 2 must be a tuple or list");
5394 Py_DECREF(opath);
5395 return NULL;
5396 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005397
Victor Stinner8c62be82010-05-06 00:08:46 +00005398 argvlist = PyMem_NEW(char *, argc+1);
5399 if (argvlist == NULL) {
5400 Py_DECREF(opath);
5401 return PyErr_NoMemory();
5402 }
5403 for (i = 0; i < argc; i++) {
5404 if (!fsconvert_strdup((*getitem)(argv, i),
5405 &argvlist[i])) {
5406 free_string_array(argvlist, i);
5407 PyErr_SetString(
5408 PyExc_TypeError,
5409 "spawnv() arg 2 must contain only strings");
5410 Py_DECREF(opath);
5411 return NULL;
5412 }
5413 }
5414 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005415
Victor Stinner8c62be82010-05-06 00:08:46 +00005416 if (mode == _OLD_P_OVERLAY)
5417 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005418
Victor Stinner8c62be82010-05-06 00:08:46 +00005419 Py_BEGIN_ALLOW_THREADS
5420 spawnval = _spawnv(mode, path, argvlist);
5421 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005422
Victor Stinner8c62be82010-05-06 00:08:46 +00005423 free_string_array(argvlist, argc);
5424 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005425
Victor Stinner8c62be82010-05-06 00:08:46 +00005426 if (spawnval == -1)
5427 return posix_error();
5428 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005429 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005430}
5431
5432
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005433PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005434"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005435Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005436\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005437 mode: mode of process creation\n\
5438 path: path of executable file\n\
5439 args: tuple or list of arguments\n\
5440 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005441
5442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005443posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005444{
Victor Stinner8c62be82010-05-06 00:08:46 +00005445 PyObject *opath;
5446 char *path;
5447 PyObject *argv, *env;
5448 char **argvlist;
5449 char **envlist;
5450 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005451 int mode;
5452 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005453 Py_intptr_t spawnval;
5454 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5455 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005456
Victor Stinner8c62be82010-05-06 00:08:46 +00005457 /* spawnve has four arguments: (mode, path, argv, env), where
5458 argv is a list or tuple of strings and env is a dictionary
5459 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005460
Victor Stinner8c62be82010-05-06 00:08:46 +00005461 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5462 PyUnicode_FSConverter,
5463 &opath, &argv, &env))
5464 return NULL;
5465 path = PyBytes_AsString(opath);
5466 if (PyList_Check(argv)) {
5467 argc = PyList_Size(argv);
5468 getitem = PyList_GetItem;
5469 }
5470 else if (PyTuple_Check(argv)) {
5471 argc = PyTuple_Size(argv);
5472 getitem = PyTuple_GetItem;
5473 }
5474 else {
5475 PyErr_SetString(PyExc_TypeError,
5476 "spawnve() arg 2 must be a tuple or list");
5477 goto fail_0;
5478 }
5479 if (!PyMapping_Check(env)) {
5480 PyErr_SetString(PyExc_TypeError,
5481 "spawnve() arg 3 must be a mapping object");
5482 goto fail_0;
5483 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005484
Victor Stinner8c62be82010-05-06 00:08:46 +00005485 argvlist = PyMem_NEW(char *, argc+1);
5486 if (argvlist == NULL) {
5487 PyErr_NoMemory();
5488 goto fail_0;
5489 }
5490 for (i = 0; i < argc; i++) {
5491 if (!fsconvert_strdup((*getitem)(argv, i),
5492 &argvlist[i]))
5493 {
5494 lastarg = i;
5495 goto fail_1;
5496 }
5497 }
5498 lastarg = argc;
5499 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005500
Victor Stinner8c62be82010-05-06 00:08:46 +00005501 envlist = parse_envlist(env, &envc);
5502 if (envlist == NULL)
5503 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005504
Victor Stinner8c62be82010-05-06 00:08:46 +00005505 if (mode == _OLD_P_OVERLAY)
5506 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005507
Victor Stinner8c62be82010-05-06 00:08:46 +00005508 Py_BEGIN_ALLOW_THREADS
5509 spawnval = _spawnve(mode, path, argvlist, envlist);
5510 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005511
Victor Stinner8c62be82010-05-06 00:08:46 +00005512 if (spawnval == -1)
5513 (void) posix_error();
5514 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005515 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005516
Victor Stinner8c62be82010-05-06 00:08:46 +00005517 while (--envc >= 0)
5518 PyMem_DEL(envlist[envc]);
5519 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005520 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005521 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005522 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005523 Py_DECREF(opath);
5524 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005525}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005526
Guido van Rossuma1065681999-01-25 23:20:23 +00005527#endif /* HAVE_SPAWNV */
5528
5529
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005530#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005531PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005532"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005533Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5534\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005535Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005536
5537static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005538posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005539{
Victor Stinner8c62be82010-05-06 00:08:46 +00005540 pid_t pid;
5541 int result = 0;
5542 _PyImport_AcquireLock();
5543 pid = fork1();
5544 if (pid == 0) {
5545 /* child: this clobbers and resets the import lock. */
5546 PyOS_AfterFork();
5547 } else {
5548 /* parent: release the import lock. */
5549 result = _PyImport_ReleaseLock();
5550 }
5551 if (pid == -1)
5552 return posix_error();
5553 if (result < 0) {
5554 /* Don't clobber the OSError if the fork failed. */
5555 PyErr_SetString(PyExc_RuntimeError,
5556 "not holding the import lock");
5557 return NULL;
5558 }
5559 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005560}
5561#endif
5562
5563
Guido van Rossumad0ee831995-03-01 10:34:45 +00005564#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005565PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005566"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005567Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005568Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005569
Barry Warsaw53699e91996-12-10 23:23:01 +00005570static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005571posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005572{
Victor Stinner8c62be82010-05-06 00:08:46 +00005573 pid_t pid;
5574 int result = 0;
5575 _PyImport_AcquireLock();
5576 pid = fork();
5577 if (pid == 0) {
5578 /* child: this clobbers and resets the import lock. */
5579 PyOS_AfterFork();
5580 } else {
5581 /* parent: release the import lock. */
5582 result = _PyImport_ReleaseLock();
5583 }
5584 if (pid == -1)
5585 return posix_error();
5586 if (result < 0) {
5587 /* Don't clobber the OSError if the fork failed. */
5588 PyErr_SetString(PyExc_RuntimeError,
5589 "not holding the import lock");
5590 return NULL;
5591 }
5592 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005593}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005594#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005595
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005596#ifdef HAVE_SCHED_H
5597
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005598#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5599
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005600PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5601"sched_get_priority_max(policy)\n\n\
5602Get the maximum scheduling priority for *policy*.");
5603
5604static PyObject *
5605posix_sched_get_priority_max(PyObject *self, PyObject *args)
5606{
5607 int policy, max;
5608
5609 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5610 return NULL;
5611 max = sched_get_priority_max(policy);
5612 if (max < 0)
5613 return posix_error();
5614 return PyLong_FromLong(max);
5615}
5616
5617PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5618"sched_get_priority_min(policy)\n\n\
5619Get the minimum scheduling priority for *policy*.");
5620
5621static PyObject *
5622posix_sched_get_priority_min(PyObject *self, PyObject *args)
5623{
5624 int policy, min;
5625
5626 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5627 return NULL;
5628 min = sched_get_priority_min(policy);
5629 if (min < 0)
5630 return posix_error();
5631 return PyLong_FromLong(min);
5632}
5633
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005634#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5635
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005636#ifdef HAVE_SCHED_SETSCHEDULER
5637
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005638PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5639"sched_getscheduler(pid)\n\n\
5640Get the scheduling policy for the process with a PID of *pid*.\n\
5641Passing a PID of 0 returns the scheduling policy for the calling process.");
5642
5643static PyObject *
5644posix_sched_getscheduler(PyObject *self, PyObject *args)
5645{
5646 pid_t pid;
5647 int policy;
5648
5649 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5650 return NULL;
5651 policy = sched_getscheduler(pid);
5652 if (policy < 0)
5653 return posix_error();
5654 return PyLong_FromLong(policy);
5655}
5656
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005657#endif
5658
5659#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5660
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005661static PyObject *
5662sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5663{
5664 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005665 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005666
5667 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5668 return NULL;
5669 res = PyStructSequence_New(type);
5670 if (!res)
5671 return NULL;
5672 Py_INCREF(priority);
5673 PyStructSequence_SET_ITEM(res, 0, priority);
5674 return res;
5675}
5676
5677PyDoc_STRVAR(sched_param__doc__,
5678"sched_param(sched_priority): A scheduling parameter.\n\n\
5679Current has only one field: sched_priority");
5680
5681static PyStructSequence_Field sched_param_fields[] = {
5682 {"sched_priority", "the scheduling priority"},
5683 {0}
5684};
5685
5686static PyStructSequence_Desc sched_param_desc = {
5687 "sched_param", /* name */
5688 sched_param__doc__, /* doc */
5689 sched_param_fields,
5690 1
5691};
5692
5693static int
5694convert_sched_param(PyObject *param, struct sched_param *res)
5695{
5696 long priority;
5697
5698 if (Py_TYPE(param) != &SchedParamType) {
5699 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5700 return 0;
5701 }
5702 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5703 if (priority == -1 && PyErr_Occurred())
5704 return 0;
5705 if (priority > INT_MAX || priority < INT_MIN) {
5706 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5707 return 0;
5708 }
5709 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5710 return 1;
5711}
5712
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005713#endif
5714
5715#ifdef HAVE_SCHED_SETSCHEDULER
5716
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005717PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5718"sched_setscheduler(pid, policy, param)\n\n\
5719Set the scheduling policy, *policy*, for *pid*.\n\
5720If *pid* is 0, the calling process is changed.\n\
5721*param* is an instance of sched_param.");
5722
5723static PyObject *
5724posix_sched_setscheduler(PyObject *self, PyObject *args)
5725{
5726 pid_t pid;
5727 int policy;
5728 struct sched_param param;
5729
5730 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5731 &pid, &policy, &convert_sched_param, &param))
5732 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005733
5734 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005735 ** sched_setscheduler() returns 0 in Linux, but the previous
5736 ** scheduling policy under Solaris/Illumos, and others.
5737 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005738 */
5739 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005740 return posix_error();
5741 Py_RETURN_NONE;
5742}
5743
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005744#endif
5745
5746#ifdef HAVE_SCHED_SETPARAM
5747
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005748PyDoc_STRVAR(posix_sched_getparam__doc__,
5749"sched_getparam(pid) -> sched_param\n\n\
5750Returns scheduling parameters for the process with *pid* as an instance of the\n\
5751sched_param class. A PID of 0 means the calling process.");
5752
5753static PyObject *
5754posix_sched_getparam(PyObject *self, PyObject *args)
5755{
5756 pid_t pid;
5757 struct sched_param param;
5758 PyObject *res, *priority;
5759
5760 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5761 return NULL;
5762 if (sched_getparam(pid, &param))
5763 return posix_error();
5764 res = PyStructSequence_New(&SchedParamType);
5765 if (!res)
5766 return NULL;
5767 priority = PyLong_FromLong(param.sched_priority);
5768 if (!priority) {
5769 Py_DECREF(res);
5770 return NULL;
5771 }
5772 PyStructSequence_SET_ITEM(res, 0, priority);
5773 return res;
5774}
5775
5776PyDoc_STRVAR(posix_sched_setparam__doc__,
5777"sched_setparam(pid, param)\n\n\
5778Set scheduling parameters for a process with PID *pid*.\n\
5779A PID of 0 means the calling process.");
5780
5781static PyObject *
5782posix_sched_setparam(PyObject *self, PyObject *args)
5783{
5784 pid_t pid;
5785 struct sched_param param;
5786
5787 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5788 &pid, &convert_sched_param, &param))
5789 return NULL;
5790 if (sched_setparam(pid, &param))
5791 return posix_error();
5792 Py_RETURN_NONE;
5793}
5794
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005795#endif
5796
5797#ifdef HAVE_SCHED_RR_GET_INTERVAL
5798
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005799PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5800"sched_rr_get_interval(pid) -> float\n\n\
5801Return the round-robin quantum for the process with PID *pid* in seconds.");
5802
5803static PyObject *
5804posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5805{
5806 pid_t pid;
5807 struct timespec interval;
5808
5809 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5810 return NULL;
5811 if (sched_rr_get_interval(pid, &interval))
5812 return posix_error();
5813 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5814}
5815
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005816#endif
5817
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005818PyDoc_STRVAR(posix_sched_yield__doc__,
5819"sched_yield()\n\n\
5820Voluntarily relinquish the CPU.");
5821
5822static PyObject *
5823posix_sched_yield(PyObject *self, PyObject *noargs)
5824{
5825 if (sched_yield())
5826 return posix_error();
5827 Py_RETURN_NONE;
5828}
5829
Benjamin Peterson2740af82011-08-02 17:41:34 -05005830#ifdef HAVE_SCHED_SETAFFINITY
5831
Antoine Pitrou84869872012-08-04 16:16:35 +02005832/* The minimum number of CPUs allocated in a cpu_set_t */
5833static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005834
5835PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5836"sched_setaffinity(pid, cpu_set)\n\n\
5837Set the affinity of the process with PID *pid* to *cpu_set*.");
5838
5839static PyObject *
5840posix_sched_setaffinity(PyObject *self, PyObject *args)
5841{
5842 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005843 int ncpus;
5844 size_t setsize;
5845 cpu_set_t *mask = NULL;
5846 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005847
Antoine Pitrou84869872012-08-04 16:16:35 +02005848 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5849 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005850 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005851
5852 iterator = PyObject_GetIter(iterable);
5853 if (iterator == NULL)
5854 return NULL;
5855
5856 ncpus = NCPUS_START;
5857 setsize = CPU_ALLOC_SIZE(ncpus);
5858 mask = CPU_ALLOC(ncpus);
5859 if (mask == NULL) {
5860 PyErr_NoMemory();
5861 goto error;
5862 }
5863 CPU_ZERO_S(setsize, mask);
5864
5865 while ((item = PyIter_Next(iterator))) {
5866 long cpu;
5867 if (!PyLong_Check(item)) {
5868 PyErr_Format(PyExc_TypeError,
5869 "expected an iterator of ints, "
5870 "but iterator yielded %R",
5871 Py_TYPE(item));
5872 Py_DECREF(item);
5873 goto error;
5874 }
5875 cpu = PyLong_AsLong(item);
5876 Py_DECREF(item);
5877 if (cpu < 0) {
5878 if (!PyErr_Occurred())
5879 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5880 goto error;
5881 }
5882 if (cpu > INT_MAX - 1) {
5883 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5884 goto error;
5885 }
5886 if (cpu >= ncpus) {
5887 /* Grow CPU mask to fit the CPU number */
5888 int newncpus = ncpus;
5889 cpu_set_t *newmask;
5890 size_t newsetsize;
5891 while (newncpus <= cpu) {
5892 if (newncpus > INT_MAX / 2)
5893 newncpus = cpu + 1;
5894 else
5895 newncpus = newncpus * 2;
5896 }
5897 newmask = CPU_ALLOC(newncpus);
5898 if (newmask == NULL) {
5899 PyErr_NoMemory();
5900 goto error;
5901 }
5902 newsetsize = CPU_ALLOC_SIZE(newncpus);
5903 CPU_ZERO_S(newsetsize, newmask);
5904 memcpy(newmask, mask, setsize);
5905 CPU_FREE(mask);
5906 setsize = newsetsize;
5907 mask = newmask;
5908 ncpus = newncpus;
5909 }
5910 CPU_SET_S(cpu, setsize, mask);
5911 }
5912 Py_CLEAR(iterator);
5913
5914 if (sched_setaffinity(pid, setsize, mask)) {
5915 posix_error();
5916 goto error;
5917 }
5918 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005919 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005920
5921error:
5922 if (mask)
5923 CPU_FREE(mask);
5924 Py_XDECREF(iterator);
5925 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005926}
5927
5928PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5929"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5930Return the affinity of the process with PID *pid*.\n\
5931The returned cpu_set will be of size *ncpus*.");
5932
5933static PyObject *
5934posix_sched_getaffinity(PyObject *self, PyObject *args)
5935{
5936 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005937 int cpu, ncpus, count;
5938 size_t setsize;
5939 cpu_set_t *mask = NULL;
5940 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005941
Antoine Pitrou84869872012-08-04 16:16:35 +02005942 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5943 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005944 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005945
5946 ncpus = NCPUS_START;
5947 while (1) {
5948 setsize = CPU_ALLOC_SIZE(ncpus);
5949 mask = CPU_ALLOC(ncpus);
5950 if (mask == NULL)
5951 return PyErr_NoMemory();
5952 if (sched_getaffinity(pid, setsize, mask) == 0)
5953 break;
5954 CPU_FREE(mask);
5955 if (errno != EINVAL)
5956 return posix_error();
5957 if (ncpus > INT_MAX / 2) {
5958 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5959 "a large enough CPU set");
5960 return NULL;
5961 }
5962 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005963 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005964
5965 res = PySet_New(NULL);
5966 if (res == NULL)
5967 goto error;
5968 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5969 if (CPU_ISSET_S(cpu, setsize, mask)) {
5970 PyObject *cpu_num = PyLong_FromLong(cpu);
5971 --count;
5972 if (cpu_num == NULL)
5973 goto error;
5974 if (PySet_Add(res, cpu_num)) {
5975 Py_DECREF(cpu_num);
5976 goto error;
5977 }
5978 Py_DECREF(cpu_num);
5979 }
5980 }
5981 CPU_FREE(mask);
5982 return res;
5983
5984error:
5985 if (mask)
5986 CPU_FREE(mask);
5987 Py_XDECREF(res);
5988 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005989}
5990
Benjamin Peterson2740af82011-08-02 17:41:34 -05005991#endif /* HAVE_SCHED_SETAFFINITY */
5992
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005993#endif /* HAVE_SCHED_H */
5994
Neal Norwitzb59798b2003-03-21 01:43:31 +00005995/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005996/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5997#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005998#define DEV_PTY_FILE "/dev/ptc"
5999#define HAVE_DEV_PTMX
6000#else
6001#define DEV_PTY_FILE "/dev/ptmx"
6002#endif
6003
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006004#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006005#ifdef HAVE_PTY_H
6006#include <pty.h>
6007#else
6008#ifdef HAVE_LIBUTIL_H
6009#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006010#else
6011#ifdef HAVE_UTIL_H
6012#include <util.h>
6013#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006014#endif /* HAVE_LIBUTIL_H */
6015#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006016#ifdef HAVE_STROPTS_H
6017#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006018#endif
6019#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006020
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006021#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006022PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006023"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006024Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006025
6026static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006027posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006028{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006029 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006030#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006031 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006032#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006033#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006034 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006035#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006037#endif
6038#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006039
Thomas Wouters70c21a12000-07-14 14:28:33 +00006040#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006041 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006042 goto posix_error;
6043
6044 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6045 goto error;
6046 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6047 goto error;
6048
Neal Norwitzb59798b2003-03-21 01:43:31 +00006049#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006050 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6051 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006052 goto posix_error;
6053 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6054 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006055
Victor Stinnerdaf45552013-08-28 00:53:59 +02006056 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006057 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006058 goto posix_error;
6059
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006060#else
Victor Stinner000de532013-11-25 23:19:58 +01006061 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006062 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006063 goto posix_error;
6064
Victor Stinner8c62be82010-05-06 00:08:46 +00006065 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006066
Victor Stinner8c62be82010-05-06 00:08:46 +00006067 /* change permission of slave */
6068 if (grantpt(master_fd) < 0) {
6069 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006070 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006072
Victor Stinner8c62be82010-05-06 00:08:46 +00006073 /* unlock slave */
6074 if (unlockpt(master_fd) < 0) {
6075 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006076 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006078
Victor Stinner8c62be82010-05-06 00:08:46 +00006079 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006080
Victor Stinner8c62be82010-05-06 00:08:46 +00006081 slave_name = ptsname(master_fd); /* get name of slave */
6082 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006083 goto posix_error;
6084
6085 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00006086 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006087 goto posix_error;
Victor Stinner000de532013-11-25 23:19:58 +01006088
6089 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6090 goto posix_error;
6091
Neal Norwitzb59798b2003-03-21 01:43:31 +00006092#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006093 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6094 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006095#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006096 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006097#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006098#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006099#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006100
Victor Stinner8c62be82010-05-06 00:08:46 +00006101 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006102
Victor Stinnerdaf45552013-08-28 00:53:59 +02006103posix_error:
6104 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006105#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006106error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006107#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02006108 if (master_fd != -1)
6109 close(master_fd);
6110 if (slave_fd != -1)
6111 close(slave_fd);
6112 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006113}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006114#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006115
6116#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006117PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006118"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006119Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6120Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006121To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006122
6123static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006124posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006125{
Victor Stinner8c62be82010-05-06 00:08:46 +00006126 int master_fd = -1, result = 0;
6127 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006128
Victor Stinner8c62be82010-05-06 00:08:46 +00006129 _PyImport_AcquireLock();
6130 pid = forkpty(&master_fd, NULL, NULL, NULL);
6131 if (pid == 0) {
6132 /* child: this clobbers and resets the import lock. */
6133 PyOS_AfterFork();
6134 } else {
6135 /* parent: release the import lock. */
6136 result = _PyImport_ReleaseLock();
6137 }
6138 if (pid == -1)
6139 return posix_error();
6140 if (result < 0) {
6141 /* Don't clobber the OSError if the fork failed. */
6142 PyErr_SetString(PyExc_RuntimeError,
6143 "not holding the import lock");
6144 return NULL;
6145 }
6146 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006147}
6148#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006149
Ross Lagerwall7807c352011-03-17 20:20:30 +02006150
Guido van Rossumad0ee831995-03-01 10:34:45 +00006151#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006152PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006153"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006154Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006155
Barry Warsaw53699e91996-12-10 23:23:01 +00006156static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006157posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006158{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006159 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006160}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006161#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006163
Guido van Rossumad0ee831995-03-01 10:34:45 +00006164#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006165PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006166"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006167Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006168
Barry Warsaw53699e91996-12-10 23:23:01 +00006169static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006170posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006171{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006172 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006173}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006174#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006176
Guido van Rossumad0ee831995-03-01 10:34:45 +00006177#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006178PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006179"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006180Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006181
Barry Warsaw53699e91996-12-10 23:23:01 +00006182static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006183posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006184{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006185 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006186}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006187#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006188
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006189
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006190PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006191"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006192Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006193
Barry Warsaw53699e91996-12-10 23:23:01 +00006194static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006195posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006196{
Victor Stinner8c62be82010-05-06 00:08:46 +00006197 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006198}
6199
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006200#ifdef HAVE_GETGROUPLIST
6201PyDoc_STRVAR(posix_getgrouplist__doc__,
6202"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6203Returns a list of groups to which a user belongs.\n\n\
6204 user: username to lookup\n\
6205 group: base group id of the user");
6206
6207static PyObject *
6208posix_getgrouplist(PyObject *self, PyObject *args)
6209{
6210#ifdef NGROUPS_MAX
6211#define MAX_GROUPS NGROUPS_MAX
6212#else
6213 /* defined to be 16 on Solaris7, so this should be a small number */
6214#define MAX_GROUPS 64
6215#endif
6216
6217 const char *user;
6218 int i, ngroups;
6219 PyObject *list;
6220#ifdef __APPLE__
6221 int *groups, basegid;
6222#else
6223 gid_t *groups, basegid;
6224#endif
6225 ngroups = MAX_GROUPS;
6226
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006227#ifdef __APPLE__
6228 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006229 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006230#else
6231 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6232 _Py_Gid_Converter, &basegid))
6233 return NULL;
6234#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006235
6236#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006237 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006238#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006239 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006240#endif
6241 if (groups == NULL)
6242 return PyErr_NoMemory();
6243
6244 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6245 PyMem_Del(groups);
6246 return posix_error();
6247 }
6248
6249 list = PyList_New(ngroups);
6250 if (list == NULL) {
6251 PyMem_Del(groups);
6252 return NULL;
6253 }
6254
6255 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006256#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006257 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006258#else
6259 PyObject *o = _PyLong_FromGid(groups[i]);
6260#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006261 if (o == NULL) {
6262 Py_DECREF(list);
6263 PyMem_Del(groups);
6264 return NULL;
6265 }
6266 PyList_SET_ITEM(list, i, o);
6267 }
6268
6269 PyMem_Del(groups);
6270
6271 return list;
6272}
6273#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006274
Fred Drakec9680921999-12-13 16:37:25 +00006275#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006276PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006277"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006278Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006279
6280static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006281posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006282{
6283 PyObject *result = NULL;
6284
Fred Drakec9680921999-12-13 16:37:25 +00006285#ifdef NGROUPS_MAX
6286#define MAX_GROUPS NGROUPS_MAX
6287#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006289#define MAX_GROUPS 64
6290#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006291 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006292
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006293 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006294 * This is a helper variable to store the intermediate result when
6295 * that happens.
6296 *
6297 * To keep the code readable the OSX behaviour is unconditional,
6298 * according to the POSIX spec this should be safe on all unix-y
6299 * systems.
6300 */
6301 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006303
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006304#ifdef __APPLE__
6305 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6306 * there are more groups than can fit in grouplist. Therefore, on OS X
6307 * always first call getgroups with length 0 to get the actual number
6308 * of groups.
6309 */
6310 n = getgroups(0, NULL);
6311 if (n < 0) {
6312 return posix_error();
6313 } else if (n <= MAX_GROUPS) {
6314 /* groups will fit in existing array */
6315 alt_grouplist = grouplist;
6316 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006317 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006318 if (alt_grouplist == NULL) {
6319 errno = EINVAL;
6320 return posix_error();
6321 }
6322 }
6323
6324 n = getgroups(n, alt_grouplist);
6325 if (n == -1) {
6326 if (alt_grouplist != grouplist) {
6327 PyMem_Free(alt_grouplist);
6328 }
6329 return posix_error();
6330 }
6331#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006332 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006333 if (n < 0) {
6334 if (errno == EINVAL) {
6335 n = getgroups(0, NULL);
6336 if (n == -1) {
6337 return posix_error();
6338 }
6339 if (n == 0) {
6340 /* Avoid malloc(0) */
6341 alt_grouplist = grouplist;
6342 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006343 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006344 if (alt_grouplist == NULL) {
6345 errno = EINVAL;
6346 return posix_error();
6347 }
6348 n = getgroups(n, alt_grouplist);
6349 if (n == -1) {
6350 PyMem_Free(alt_grouplist);
6351 return posix_error();
6352 }
6353 }
6354 } else {
6355 return posix_error();
6356 }
6357 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006358#endif
6359
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006360 result = PyList_New(n);
6361 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006362 int i;
6363 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006364 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006366 Py_DECREF(result);
6367 result = NULL;
6368 break;
Fred Drakec9680921999-12-13 16:37:25 +00006369 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006370 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006371 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006372 }
6373
6374 if (alt_grouplist != grouplist) {
6375 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006376 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006377
Fred Drakec9680921999-12-13 16:37:25 +00006378 return result;
6379}
6380#endif
6381
Antoine Pitroub7572f02009-12-02 20:46:48 +00006382#ifdef HAVE_INITGROUPS
6383PyDoc_STRVAR(posix_initgroups__doc__,
6384"initgroups(username, gid) -> None\n\n\
6385Call the system initgroups() to initialize the group access list with all of\n\
6386the groups of which the specified username is a member, plus the specified\n\
6387group id.");
6388
6389static PyObject *
6390posix_initgroups(PyObject *self, PyObject *args)
6391{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006392 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006393 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006394 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006395#ifdef __APPLE__
6396 int gid;
6397#else
6398 gid_t gid;
6399#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006400
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006401#ifdef __APPLE__
6402 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6403 PyUnicode_FSConverter, &oname,
6404 &gid))
6405#else
6406 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6407 PyUnicode_FSConverter, &oname,
6408 _Py_Gid_Converter, &gid))
6409#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006410 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006411 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006412
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006413 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006414 Py_DECREF(oname);
6415 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006416 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006417
Victor Stinner8c62be82010-05-06 00:08:46 +00006418 Py_INCREF(Py_None);
6419 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006420}
6421#endif
6422
Martin v. Löwis606edc12002-06-13 21:09:11 +00006423#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006424PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006425"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006426Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006427
6428static PyObject *
6429posix_getpgid(PyObject *self, PyObject *args)
6430{
Victor Stinner8c62be82010-05-06 00:08:46 +00006431 pid_t pid, pgid;
6432 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6433 return NULL;
6434 pgid = getpgid(pid);
6435 if (pgid < 0)
6436 return posix_error();
6437 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006438}
6439#endif /* HAVE_GETPGID */
6440
6441
Guido van Rossumb6775db1994-08-01 11:34:53 +00006442#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006443PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006444"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006445Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006446
Barry Warsaw53699e91996-12-10 23:23:01 +00006447static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006448posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006449{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006450#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006451 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006452#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006454#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006455}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006456#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006457
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006458
Guido van Rossumb6775db1994-08-01 11:34:53 +00006459#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006460PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006461"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006462Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006463
Barry Warsaw53699e91996-12-10 23:23:01 +00006464static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006465posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006466{
Guido van Rossum64933891994-10-20 21:56:42 +00006467#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006468 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006469#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006470 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006471#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006472 return posix_error();
6473 Py_INCREF(Py_None);
6474 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006475}
6476
Guido van Rossumb6775db1994-08-01 11:34:53 +00006477#endif /* HAVE_SETPGRP */
6478
Guido van Rossumad0ee831995-03-01 10:34:45 +00006479#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006480
6481#ifdef MS_WINDOWS
6482#include <tlhelp32.h>
6483
6484static PyObject*
6485win32_getppid()
6486{
6487 HANDLE snapshot;
6488 pid_t mypid;
6489 PyObject* result = NULL;
6490 BOOL have_record;
6491 PROCESSENTRY32 pe;
6492
6493 mypid = getpid(); /* This function never fails */
6494
6495 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6496 if (snapshot == INVALID_HANDLE_VALUE)
6497 return PyErr_SetFromWindowsErr(GetLastError());
6498
6499 pe.dwSize = sizeof(pe);
6500 have_record = Process32First(snapshot, &pe);
6501 while (have_record) {
6502 if (mypid == (pid_t)pe.th32ProcessID) {
6503 /* We could cache the ulong value in a static variable. */
6504 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6505 break;
6506 }
6507
6508 have_record = Process32Next(snapshot, &pe);
6509 }
6510
6511 /* If our loop exits and our pid was not found (result will be NULL)
6512 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6513 * error anyway, so let's raise it. */
6514 if (!result)
6515 result = PyErr_SetFromWindowsErr(GetLastError());
6516
6517 CloseHandle(snapshot);
6518
6519 return result;
6520}
6521#endif /*MS_WINDOWS*/
6522
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006523PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006524"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006525Return the parent's process id. If the parent process has already exited,\n\
6526Windows machines will still return its id; others systems will return the id\n\
6527of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006528
Barry Warsaw53699e91996-12-10 23:23:01 +00006529static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006530posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006531{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006532#ifdef MS_WINDOWS
6533 return win32_getppid();
6534#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006535 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006536#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006537}
6538#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006539
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006540
Fred Drake12c6e2d1999-12-14 21:25:03 +00006541#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006542PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006543"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006544Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006545
6546static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006547posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006548{
Victor Stinner8c62be82010-05-06 00:08:46 +00006549 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006550#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006551 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006552 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006553
6554 if (GetUserNameW(user_name, &num_chars)) {
6555 /* num_chars is the number of unicode chars plus null terminator */
6556 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006557 }
6558 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006559 result = PyErr_SetFromWindowsErr(GetLastError());
6560#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006561 char *name;
6562 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006563
Victor Stinner8c62be82010-05-06 00:08:46 +00006564 errno = 0;
6565 name = getlogin();
6566 if (name == NULL) {
6567 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006568 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006569 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006570 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006571 }
6572 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006573 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006574 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006575#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006576 return result;
6577}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006578#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006579
Guido van Rossumad0ee831995-03-01 10:34:45 +00006580#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006581PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006582"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006583Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006584
Barry Warsaw53699e91996-12-10 23:23:01 +00006585static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006586posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006587{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006588 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006589}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006590#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006591
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006592
Guido van Rossumad0ee831995-03-01 10:34:45 +00006593#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006594PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006595"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006596Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006597
Barry Warsaw53699e91996-12-10 23:23:01 +00006598static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006599posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006600{
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 pid_t pid;
6602 int sig;
6603 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6604 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 if (kill(pid, sig) == -1)
6606 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 Py_INCREF(Py_None);
6608 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006609}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006610#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006611
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006612#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006613PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006614"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006615Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006616
6617static PyObject *
6618posix_killpg(PyObject *self, PyObject *args)
6619{
Victor Stinner8c62be82010-05-06 00:08:46 +00006620 int sig;
6621 pid_t pgid;
6622 /* XXX some man pages make the `pgid` parameter an int, others
6623 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6624 take the same type. Moreover, pid_t is always at least as wide as
6625 int (else compilation of this module fails), which is safe. */
6626 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6627 return NULL;
6628 if (killpg(pgid, sig) == -1)
6629 return posix_error();
6630 Py_INCREF(Py_None);
6631 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006632}
6633#endif
6634
Brian Curtineb24d742010-04-12 17:16:38 +00006635#ifdef MS_WINDOWS
6636PyDoc_STRVAR(win32_kill__doc__,
6637"kill(pid, sig)\n\n\
6638Kill a process with a signal.");
6639
6640static PyObject *
6641win32_kill(PyObject *self, PyObject *args)
6642{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006643 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006644 pid_t pid;
6645 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006647
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006648 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006650
Victor Stinner8c62be82010-05-06 00:08:46 +00006651 /* Console processes which share a common console can be sent CTRL+C or
6652 CTRL+BREAK events, provided they handle said events. */
6653 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006654 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006655 err = GetLastError();
6656 PyErr_SetFromWindowsErr(err);
6657 }
6658 else
6659 Py_RETURN_NONE;
6660 }
Brian Curtineb24d742010-04-12 17:16:38 +00006661
Victor Stinner8c62be82010-05-06 00:08:46 +00006662 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6663 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006664 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 if (handle == NULL) {
6666 err = GetLastError();
6667 return PyErr_SetFromWindowsErr(err);
6668 }
Brian Curtineb24d742010-04-12 17:16:38 +00006669
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 if (TerminateProcess(handle, sig) == 0) {
6671 err = GetLastError();
6672 result = PyErr_SetFromWindowsErr(err);
6673 } else {
6674 Py_INCREF(Py_None);
6675 result = Py_None;
6676 }
Brian Curtineb24d742010-04-12 17:16:38 +00006677
Victor Stinner8c62be82010-05-06 00:08:46 +00006678 CloseHandle(handle);
6679 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006680}
6681#endif /* MS_WINDOWS */
6682
Guido van Rossumc0125471996-06-28 18:55:32 +00006683#ifdef HAVE_PLOCK
6684
6685#ifdef HAVE_SYS_LOCK_H
6686#include <sys/lock.h>
6687#endif
6688
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006689PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006690"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006691Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006692
Barry Warsaw53699e91996-12-10 23:23:01 +00006693static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006694posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006695{
Victor Stinner8c62be82010-05-06 00:08:46 +00006696 int op;
6697 if (!PyArg_ParseTuple(args, "i:plock", &op))
6698 return NULL;
6699 if (plock(op) == -1)
6700 return posix_error();
6701 Py_INCREF(Py_None);
6702 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006703}
6704#endif
6705
Guido van Rossumb6775db1994-08-01 11:34:53 +00006706#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006707PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006708"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006709Set the current process's user id.");
6710
Barry Warsaw53699e91996-12-10 23:23:01 +00006711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006712posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006713{
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006715 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006716 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006717 if (setuid(uid) < 0)
6718 return posix_error();
6719 Py_INCREF(Py_None);
6720 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006721}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006722#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006723
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006724
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006725#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006726PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006727"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006728Set the current process's effective user id.");
6729
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006730static PyObject *
6731posix_seteuid (PyObject *self, PyObject *args)
6732{
Victor Stinner8c62be82010-05-06 00:08:46 +00006733 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006734 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006735 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006736 if (seteuid(euid) < 0) {
6737 return posix_error();
6738 } else {
6739 Py_INCREF(Py_None);
6740 return Py_None;
6741 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006742}
6743#endif /* HAVE_SETEUID */
6744
6745#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006746PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006747"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006748Set the current process's effective group id.");
6749
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006750static PyObject *
6751posix_setegid (PyObject *self, PyObject *args)
6752{
Victor Stinner8c62be82010-05-06 00:08:46 +00006753 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006754 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006755 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006756 if (setegid(egid) < 0) {
6757 return posix_error();
6758 } else {
6759 Py_INCREF(Py_None);
6760 return Py_None;
6761 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006762}
6763#endif /* HAVE_SETEGID */
6764
6765#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006766PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006767"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006768Set the current process's real and effective user ids.");
6769
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006770static PyObject *
6771posix_setreuid (PyObject *self, PyObject *args)
6772{
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006774 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6775 _Py_Uid_Converter, &ruid,
6776 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 if (setreuid(ruid, euid) < 0) {
6779 return posix_error();
6780 } else {
6781 Py_INCREF(Py_None);
6782 return Py_None;
6783 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006784}
6785#endif /* HAVE_SETREUID */
6786
6787#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006788PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006789"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006790Set the current process's real and effective group ids.");
6791
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006792static PyObject *
6793posix_setregid (PyObject *self, PyObject *args)
6794{
Victor Stinner8c62be82010-05-06 00:08:46 +00006795 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006796 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6797 _Py_Gid_Converter, &rgid,
6798 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 if (setregid(rgid, egid) < 0) {
6801 return posix_error();
6802 } else {
6803 Py_INCREF(Py_None);
6804 return Py_None;
6805 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006806}
6807#endif /* HAVE_SETREGID */
6808
Guido van Rossumb6775db1994-08-01 11:34:53 +00006809#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006810PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006811"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006813
Barry Warsaw53699e91996-12-10 23:23:01 +00006814static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006815posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006816{
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006818 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 if (setgid(gid) < 0)
6821 return posix_error();
6822 Py_INCREF(Py_None);
6823 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006824}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006825#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006826
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006827#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006828PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006829"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006830Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006831
6832static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006833posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006834{
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 int i, len;
6836 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006837
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 if (!PySequence_Check(groups)) {
6839 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6840 return NULL;
6841 }
6842 len = PySequence_Size(groups);
6843 if (len > MAX_GROUPS) {
6844 PyErr_SetString(PyExc_ValueError, "too many groups");
6845 return NULL;
6846 }
6847 for(i = 0; i < len; i++) {
6848 PyObject *elem;
6849 elem = PySequence_GetItem(groups, i);
6850 if (!elem)
6851 return NULL;
6852 if (!PyLong_Check(elem)) {
6853 PyErr_SetString(PyExc_TypeError,
6854 "groups must be integers");
6855 Py_DECREF(elem);
6856 return NULL;
6857 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006858 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 Py_DECREF(elem);
6860 return NULL;
6861 }
6862 }
6863 Py_DECREF(elem);
6864 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006865
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 if (setgroups(len, grouplist) < 0)
6867 return posix_error();
6868 Py_INCREF(Py_None);
6869 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006870}
6871#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006872
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006873#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6874static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006875wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006876{
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 PyObject *result;
6878 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006879 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006880
Victor Stinner8c62be82010-05-06 00:08:46 +00006881 if (pid == -1)
6882 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006883
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 if (struct_rusage == NULL) {
6885 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6886 if (m == NULL)
6887 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006888 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 Py_DECREF(m);
6890 if (struct_rusage == NULL)
6891 return NULL;
6892 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006893
Victor Stinner8c62be82010-05-06 00:08:46 +00006894 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6895 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6896 if (!result)
6897 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006898
6899#ifndef doubletime
6900#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6901#endif
6902
Victor Stinner8c62be82010-05-06 00:08:46 +00006903 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006904 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006905 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006906 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006907#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6909 SET_INT(result, 2, ru->ru_maxrss);
6910 SET_INT(result, 3, ru->ru_ixrss);
6911 SET_INT(result, 4, ru->ru_idrss);
6912 SET_INT(result, 5, ru->ru_isrss);
6913 SET_INT(result, 6, ru->ru_minflt);
6914 SET_INT(result, 7, ru->ru_majflt);
6915 SET_INT(result, 8, ru->ru_nswap);
6916 SET_INT(result, 9, ru->ru_inblock);
6917 SET_INT(result, 10, ru->ru_oublock);
6918 SET_INT(result, 11, ru->ru_msgsnd);
6919 SET_INT(result, 12, ru->ru_msgrcv);
6920 SET_INT(result, 13, ru->ru_nsignals);
6921 SET_INT(result, 14, ru->ru_nvcsw);
6922 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006923#undef SET_INT
6924
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 if (PyErr_Occurred()) {
6926 Py_DECREF(result);
6927 return NULL;
6928 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006929
Victor Stinner8c62be82010-05-06 00:08:46 +00006930 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006931}
6932#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6933
6934#ifdef HAVE_WAIT3
6935PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006936"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006937Wait for completion of a child process.");
6938
6939static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006940posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006941{
Victor Stinner8c62be82010-05-06 00:08:46 +00006942 pid_t pid;
6943 int options;
6944 struct rusage ru;
6945 WAIT_TYPE status;
6946 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006947
Victor Stinner4195b5c2012-02-08 23:03:19 +01006948 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006950
Victor Stinner8c62be82010-05-06 00:08:46 +00006951 Py_BEGIN_ALLOW_THREADS
6952 pid = wait3(&status, options, &ru);
6953 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006954
Victor Stinner4195b5c2012-02-08 23:03:19 +01006955 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006956}
6957#endif /* HAVE_WAIT3 */
6958
6959#ifdef HAVE_WAIT4
6960PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006961"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006962Wait for completion of a given child process.");
6963
6964static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006965posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006966{
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 pid_t pid;
6968 int options;
6969 struct rusage ru;
6970 WAIT_TYPE status;
6971 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006972
Victor Stinner4195b5c2012-02-08 23:03:19 +01006973 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006975
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 Py_BEGIN_ALLOW_THREADS
6977 pid = wait4(pid, &status, options, &ru);
6978 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006979
Victor Stinner4195b5c2012-02-08 23:03:19 +01006980 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006981}
6982#endif /* HAVE_WAIT4 */
6983
Ross Lagerwall7807c352011-03-17 20:20:30 +02006984#if defined(HAVE_WAITID) && !defined(__APPLE__)
6985PyDoc_STRVAR(posix_waitid__doc__,
6986"waitid(idtype, id, options) -> waitid_result\n\n\
6987Wait for the completion of one or more child processes.\n\n\
6988idtype can be P_PID, P_PGID or P_ALL.\n\
6989id specifies the pid to wait on.\n\
6990options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6991or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6992Returns either waitid_result or None if WNOHANG is specified and there are\n\
6993no children in a waitable state.");
6994
6995static PyObject *
6996posix_waitid(PyObject *self, PyObject *args)
6997{
6998 PyObject *result;
6999 idtype_t idtype;
7000 id_t id;
7001 int options, res;
7002 siginfo_t si;
7003 si.si_pid = 0;
7004 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
7005 return NULL;
7006 Py_BEGIN_ALLOW_THREADS
7007 res = waitid(idtype, id, &si, options);
7008 Py_END_ALLOW_THREADS
7009 if (res == -1)
7010 return posix_error();
7011
7012 if (si.si_pid == 0)
7013 Py_RETURN_NONE;
7014
7015 result = PyStructSequence_New(&WaitidResultType);
7016 if (!result)
7017 return NULL;
7018
7019 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007020 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007021 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7022 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7023 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7024 if (PyErr_Occurred()) {
7025 Py_DECREF(result);
7026 return NULL;
7027 }
7028
7029 return result;
7030}
7031#endif
7032
Guido van Rossumb6775db1994-08-01 11:34:53 +00007033#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007034PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007035"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007036Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007037
Barry Warsaw53699e91996-12-10 23:23:01 +00007038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007039posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007040{
Victor Stinner8c62be82010-05-06 00:08:46 +00007041 pid_t pid;
7042 int options;
7043 WAIT_TYPE status;
7044 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007045
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7047 return NULL;
7048 Py_BEGIN_ALLOW_THREADS
7049 pid = waitpid(pid, &status, options);
7050 Py_END_ALLOW_THREADS
7051 if (pid == -1)
7052 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007053
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007055}
7056
Tim Petersab034fa2002-02-01 11:27:43 +00007057#elif defined(HAVE_CWAIT)
7058
7059/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007060PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007061"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007062"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007063
7064static PyObject *
7065posix_waitpid(PyObject *self, PyObject *args)
7066{
Victor Stinner8c62be82010-05-06 00:08:46 +00007067 Py_intptr_t pid;
7068 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007069
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007070 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007071 return NULL;
7072 Py_BEGIN_ALLOW_THREADS
7073 pid = _cwait(&status, pid, options);
7074 Py_END_ALLOW_THREADS
7075 if (pid == -1)
7076 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007077
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007079 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007080}
7081#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007082
Guido van Rossumad0ee831995-03-01 10:34:45 +00007083#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007084PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007085"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007086Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007087
Barry Warsaw53699e91996-12-10 23:23:01 +00007088static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007089posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007090{
Victor Stinner8c62be82010-05-06 00:08:46 +00007091 pid_t pid;
7092 WAIT_TYPE status;
7093 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007094
Victor Stinner8c62be82010-05-06 00:08:46 +00007095 Py_BEGIN_ALLOW_THREADS
7096 pid = wait(&status);
7097 Py_END_ALLOW_THREADS
7098 if (pid == -1)
7099 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007100
Victor Stinner8c62be82010-05-06 00:08:46 +00007101 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007102}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007103#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007104
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007105
Larry Hastings9cf065c2012-06-22 16:30:09 -07007106#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7107PyDoc_STRVAR(readlink__doc__,
7108"readlink(path, *, dir_fd=None) -> path\n\n\
7109Return a string representing the path to which the symbolic link points.\n\
7110\n\
7111If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7112 and path should be relative; path will then be relative to that directory.\n\
7113dir_fd may not be implemented on your platform.\n\
7114 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007115#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007116
Guido van Rossumb6775db1994-08-01 11:34:53 +00007117#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007118
Barry Warsaw53699e91996-12-10 23:23:01 +00007119static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007120posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007121{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122 path_t path;
7123 int dir_fd = DEFAULT_DIR_FD;
7124 char buffer[MAXPATHLEN];
7125 ssize_t length;
7126 PyObject *return_value = NULL;
7127 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007128
Larry Hastings9cf065c2012-06-22 16:30:09 -07007129 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007130 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007131 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7132 path_converter, &path,
7133#ifdef HAVE_READLINKAT
7134 dir_fd_converter, &dir_fd
7135#else
7136 dir_fd_unavailable, &dir_fd
7137#endif
7138 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007139 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007140
Victor Stinner8c62be82010-05-06 00:08:46 +00007141 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007142#ifdef HAVE_READLINKAT
7143 if (dir_fd != DEFAULT_DIR_FD)
7144 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007145 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007146#endif
7147 length = readlink(path.narrow, buffer, sizeof(buffer));
7148 Py_END_ALLOW_THREADS
7149
7150 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007151 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007152 goto exit;
7153 }
7154
7155 if (PyUnicode_Check(path.object))
7156 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7157 else
7158 return_value = PyBytes_FromStringAndSize(buffer, length);
7159exit:
7160 path_cleanup(&path);
7161 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007162}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007163
7164
Guido van Rossumb6775db1994-08-01 11:34:53 +00007165#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007166
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007167
Larry Hastings9cf065c2012-06-22 16:30:09 -07007168#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007169PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007170"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7171Create a symbolic link pointing to src named dst.\n\n\
7172target_is_directory is required on Windows if the target is to be\n\
7173 interpreted as a directory. (On Windows, symlink requires\n\
7174 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7175 target_is_directory is ignored on non-Windows platforms.\n\
7176\n\
7177If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7178 and path should be relative; path will then be relative to that directory.\n\
7179dir_fd may not be implemented on your platform.\n\
7180 If it is unavailable, using it will raise a NotImplementedError.");
7181
7182#if defined(MS_WINDOWS)
7183
7184/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7185static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7186static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007187
Larry Hastings9cf065c2012-06-22 16:30:09 -07007188static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007189check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007190{
7191 HINSTANCE hKernel32;
7192 /* only recheck */
7193 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7194 return 1;
7195 hKernel32 = GetModuleHandleW(L"KERNEL32");
7196 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7197 "CreateSymbolicLinkW");
7198 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7199 "CreateSymbolicLinkA");
7200 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7201}
7202
Victor Stinner31b3b922013-06-05 01:49:17 +02007203/* Remove the last portion of the path */
7204static void
7205_dirnameW(WCHAR *path)
7206{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007207 WCHAR *ptr;
7208
7209 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007210 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007211 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007212 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007213 }
7214 *ptr = 0;
7215}
7216
Victor Stinner31b3b922013-06-05 01:49:17 +02007217/* Remove the last portion of the path */
7218static void
7219_dirnameA(char *path)
7220{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007221 char *ptr;
7222
7223 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007224 for(ptr = path + strlen(path); ptr != path; ptr--) {
7225 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007226 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007227 }
7228 *ptr = 0;
7229}
7230
Victor Stinner31b3b922013-06-05 01:49:17 +02007231/* Is this path absolute? */
7232static int
7233_is_absW(const WCHAR *path)
7234{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007235 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7236
7237}
7238
Victor Stinner31b3b922013-06-05 01:49:17 +02007239/* Is this path absolute? */
7240static int
7241_is_absA(const char *path)
7242{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007243 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7244
7245}
7246
Victor Stinner31b3b922013-06-05 01:49:17 +02007247/* join root and rest with a backslash */
7248static void
7249_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7250{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007251 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007252
Victor Stinner31b3b922013-06-05 01:49:17 +02007253 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007254 wcscpy(dest_path, rest);
7255 return;
7256 }
7257
7258 root_len = wcslen(root);
7259
7260 wcscpy(dest_path, root);
7261 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007262 dest_path[root_len] = L'\\';
7263 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007264 }
7265 wcscpy(dest_path+root_len, rest);
7266}
7267
Victor Stinner31b3b922013-06-05 01:49:17 +02007268/* join root and rest with a backslash */
7269static void
7270_joinA(char *dest_path, const char *root, const char *rest)
7271{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007272 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007273
Victor Stinner31b3b922013-06-05 01:49:17 +02007274 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007275 strcpy(dest_path, rest);
7276 return;
7277 }
7278
7279 root_len = strlen(root);
7280
7281 strcpy(dest_path, root);
7282 if(root_len) {
7283 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007284 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007285 }
7286 strcpy(dest_path+root_len, rest);
7287}
7288
Victor Stinner31b3b922013-06-05 01:49:17 +02007289/* Return True if the path at src relative to dest is a directory */
7290static int
7291_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007292{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007293 WIN32_FILE_ATTRIBUTE_DATA src_info;
7294 WCHAR dest_parent[MAX_PATH];
7295 WCHAR src_resolved[MAX_PATH] = L"";
7296
7297 /* dest_parent = os.path.dirname(dest) */
7298 wcscpy(dest_parent, dest);
7299 _dirnameW(dest_parent);
7300 /* src_resolved = os.path.join(dest_parent, src) */
7301 _joinW(src_resolved, dest_parent, src);
7302 return (
7303 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7304 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7305 );
7306}
7307
Victor Stinner31b3b922013-06-05 01:49:17 +02007308/* Return True if the path at src relative to dest is a directory */
7309static int
7310_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007311{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007312 WIN32_FILE_ATTRIBUTE_DATA src_info;
7313 char dest_parent[MAX_PATH];
7314 char src_resolved[MAX_PATH] = "";
7315
7316 /* dest_parent = os.path.dirname(dest) */
7317 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007318 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007319 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007320 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007321 return (
7322 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7323 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7324 );
7325}
7326
Larry Hastings9cf065c2012-06-22 16:30:09 -07007327#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007328
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007329static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007330posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007331{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007332 path_t src;
7333 path_t dst;
7334 int dir_fd = DEFAULT_DIR_FD;
7335 int target_is_directory = 0;
7336 static char *keywords[] = {"src", "dst", "target_is_directory",
7337 "dir_fd", NULL};
7338 PyObject *return_value;
7339#ifdef MS_WINDOWS
7340 DWORD result;
7341#else
7342 int result;
7343#endif
7344
7345 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007346 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007347 src.argument_name = "src";
7348 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007349 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007350 dst.argument_name = "dst";
7351
7352#ifdef MS_WINDOWS
7353 if (!check_CreateSymbolicLink()) {
7354 PyErr_SetString(PyExc_NotImplementedError,
7355 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007356 return NULL;
7357 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007358 if (!win32_can_symlink) {
7359 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007360 return NULL;
7361 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007362#endif
7363
7364 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7365 keywords,
7366 path_converter, &src,
7367 path_converter, &dst,
7368 &target_is_directory,
7369#ifdef HAVE_SYMLINKAT
7370 dir_fd_converter, &dir_fd
7371#else
7372 dir_fd_unavailable, &dir_fd
7373#endif
7374 ))
7375 return NULL;
7376
7377 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7378 PyErr_SetString(PyExc_ValueError,
7379 "symlink: src and dst must be the same type");
7380 return_value = NULL;
7381 goto exit;
7382 }
7383
7384#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007385
Larry Hastings9cf065c2012-06-22 16:30:09 -07007386 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007387 if (dst.wide) {
7388 /* if src is a directory, ensure target_is_directory==1 */
7389 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007390 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7391 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007392 }
7393 else {
7394 /* if src is a directory, ensure target_is_directory==1 */
7395 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007396 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7397 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007398 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007399 Py_END_ALLOW_THREADS
7400
7401 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08007402 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007403 goto exit;
7404 }
7405
7406#else
7407
7408 Py_BEGIN_ALLOW_THREADS
7409#if HAVE_SYMLINKAT
7410 if (dir_fd != DEFAULT_DIR_FD)
7411 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7412 else
7413#endif
7414 result = symlink(src.narrow, dst.narrow);
7415 Py_END_ALLOW_THREADS
7416
7417 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08007418 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007419 goto exit;
7420 }
7421#endif
7422
7423 return_value = Py_None;
7424 Py_INCREF(Py_None);
7425 goto exit; /* silence "unused label" warning */
7426exit:
7427 path_cleanup(&src);
7428 path_cleanup(&dst);
7429 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007430}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007431
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007432#endif /* HAVE_SYMLINK */
7433
Larry Hastings9cf065c2012-06-22 16:30:09 -07007434
Brian Curtind40e6f72010-07-08 21:39:08 +00007435#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7436
Brian Curtind40e6f72010-07-08 21:39:08 +00007437static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007438win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007439{
7440 wchar_t *path;
7441 DWORD n_bytes_returned;
7442 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007443 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007444 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007445 HANDLE reparse_point_handle;
7446
7447 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7448 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7449 wchar_t *print_name;
7450
Larry Hastings9cf065c2012-06-22 16:30:09 -07007451 static char *keywords[] = {"path", "dir_fd", NULL};
7452
7453 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7454 &po,
7455 dir_fd_unavailable, &dir_fd
7456 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007457 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007458
Victor Stinnereb5657a2011-09-30 01:44:27 +02007459 path = PyUnicode_AsUnicode(po);
7460 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007461 return NULL;
7462
7463 /* First get a handle to the reparse point */
7464 Py_BEGIN_ALLOW_THREADS
7465 reparse_point_handle = CreateFileW(
7466 path,
7467 0,
7468 0,
7469 0,
7470 OPEN_EXISTING,
7471 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7472 0);
7473 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007474
Brian Curtind40e6f72010-07-08 21:39:08 +00007475 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007476 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007477
Brian Curtind40e6f72010-07-08 21:39:08 +00007478 Py_BEGIN_ALLOW_THREADS
7479 /* New call DeviceIoControl to read the reparse point */
7480 io_result = DeviceIoControl(
7481 reparse_point_handle,
7482 FSCTL_GET_REPARSE_POINT,
7483 0, 0, /* in buffer */
7484 target_buffer, sizeof(target_buffer),
7485 &n_bytes_returned,
7486 0 /* we're not using OVERLAPPED_IO */
7487 );
7488 CloseHandle(reparse_point_handle);
7489 Py_END_ALLOW_THREADS
7490
7491 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007492 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007493
7494 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7495 {
7496 PyErr_SetString(PyExc_ValueError,
7497 "not a symbolic link");
7498 return NULL;
7499 }
Brian Curtin74e45612010-07-09 15:58:59 +00007500 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7501 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7502
7503 result = PyUnicode_FromWideChar(print_name,
7504 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007505 return result;
7506}
7507
7508#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7509
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007510
Larry Hastings605a62d2012-06-24 04:33:36 -07007511static PyStructSequence_Field times_result_fields[] = {
7512 {"user", "user time"},
7513 {"system", "system time"},
7514 {"children_user", "user time of children"},
7515 {"children_system", "system time of children"},
7516 {"elapsed", "elapsed time since an arbitrary point in the past"},
7517 {NULL}
7518};
7519
7520PyDoc_STRVAR(times_result__doc__,
7521"times_result: Result from os.times().\n\n\
7522This object may be accessed either as a tuple of\n\
7523 (user, system, children_user, children_system, elapsed),\n\
7524or via the attributes user, system, children_user, children_system,\n\
7525and elapsed.\n\
7526\n\
7527See os.times for more information.");
7528
7529static PyStructSequence_Desc times_result_desc = {
7530 "times_result", /* name */
7531 times_result__doc__, /* doc */
7532 times_result_fields,
7533 5
7534};
7535
7536static PyTypeObject TimesResultType;
7537
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007538#ifdef MS_WINDOWS
7539#define HAVE_TIMES /* mandatory, for the method table */
7540#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007541
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007542#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007543
7544static PyObject *
7545build_times_result(double user, double system,
7546 double children_user, double children_system,
7547 double elapsed)
7548{
7549 PyObject *value = PyStructSequence_New(&TimesResultType);
7550 if (value == NULL)
7551 return NULL;
7552
7553#define SET(i, field) \
7554 { \
7555 PyObject *o = PyFloat_FromDouble(field); \
7556 if (!o) { \
7557 Py_DECREF(value); \
7558 return NULL; \
7559 } \
7560 PyStructSequence_SET_ITEM(value, i, o); \
7561 } \
7562
7563 SET(0, user);
7564 SET(1, system);
7565 SET(2, children_user);
7566 SET(3, children_system);
7567 SET(4, elapsed);
7568
7569#undef SET
7570
7571 return value;
7572}
7573
7574PyDoc_STRVAR(posix_times__doc__,
7575"times() -> times_result\n\n\
7576Return an object containing floating point numbers indicating process\n\
7577times. The object behaves like a named tuple with these fields:\n\
7578 (utime, stime, cutime, cstime, elapsed_time)");
7579
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007580#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007581static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007582posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007583{
Victor Stinner8c62be82010-05-06 00:08:46 +00007584 FILETIME create, exit, kernel, user;
7585 HANDLE hProc;
7586 hProc = GetCurrentProcess();
7587 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7588 /* The fields of a FILETIME structure are the hi and lo part
7589 of a 64-bit value expressed in 100 nanosecond units.
7590 1e7 is one second in such units; 1e-7 the inverse.
7591 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7592 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007593 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007594 (double)(user.dwHighDateTime*429.4967296 +
7595 user.dwLowDateTime*1e-7),
7596 (double)(kernel.dwHighDateTime*429.4967296 +
7597 kernel.dwLowDateTime*1e-7),
7598 (double)0,
7599 (double)0,
7600 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007601}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007602#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007603#define NEED_TICKS_PER_SECOND
7604static long ticks_per_second = -1;
7605static PyObject *
7606posix_times(PyObject *self, PyObject *noargs)
7607{
7608 struct tms t;
7609 clock_t c;
7610 errno = 0;
7611 c = times(&t);
7612 if (c == (clock_t) -1)
7613 return posix_error();
7614 return build_times_result(
7615 (double)t.tms_utime / ticks_per_second,
7616 (double)t.tms_stime / ticks_per_second,
7617 (double)t.tms_cutime / ticks_per_second,
7618 (double)t.tms_cstime / ticks_per_second,
7619 (double)c / ticks_per_second);
7620}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007621#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007622
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007623#endif /* HAVE_TIMES */
7624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007625
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007626#ifdef HAVE_GETSID
7627PyDoc_STRVAR(posix_getsid__doc__,
7628"getsid(pid) -> sid\n\n\
7629Call the system call getsid().");
7630
7631static PyObject *
7632posix_getsid(PyObject *self, PyObject *args)
7633{
Victor Stinner8c62be82010-05-06 00:08:46 +00007634 pid_t pid;
7635 int sid;
7636 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7637 return NULL;
7638 sid = getsid(pid);
7639 if (sid < 0)
7640 return posix_error();
7641 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007642}
7643#endif /* HAVE_GETSID */
7644
7645
Guido van Rossumb6775db1994-08-01 11:34:53 +00007646#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007647PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007648"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007649Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007650
Barry Warsaw53699e91996-12-10 23:23:01 +00007651static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007652posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007653{
Victor Stinner8c62be82010-05-06 00:08:46 +00007654 if (setsid() < 0)
7655 return posix_error();
7656 Py_INCREF(Py_None);
7657 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007658}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007659#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007660
Guido van Rossumb6775db1994-08-01 11:34:53 +00007661#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007662PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007663"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007664Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007665
Barry Warsaw53699e91996-12-10 23:23:01 +00007666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007667posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007668{
Victor Stinner8c62be82010-05-06 00:08:46 +00007669 pid_t pid;
7670 int pgrp;
7671 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7672 return NULL;
7673 if (setpgid(pid, pgrp) < 0)
7674 return posix_error();
7675 Py_INCREF(Py_None);
7676 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007677}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007678#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007679
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007680
Guido van Rossumb6775db1994-08-01 11:34:53 +00007681#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007682PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007683"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007684Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007685
Barry Warsaw53699e91996-12-10 23:23:01 +00007686static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007687posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007688{
Victor Stinner8c62be82010-05-06 00:08:46 +00007689 int fd;
7690 pid_t pgid;
7691 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7692 return NULL;
7693 pgid = tcgetpgrp(fd);
7694 if (pgid < 0)
7695 return posix_error();
7696 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007697}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007698#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007699
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007700
Guido van Rossumb6775db1994-08-01 11:34:53 +00007701#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007702PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007703"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007704Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007705
Barry Warsaw53699e91996-12-10 23:23:01 +00007706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007707posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007708{
Victor Stinner8c62be82010-05-06 00:08:46 +00007709 int fd;
7710 pid_t pgid;
7711 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7712 return NULL;
7713 if (tcsetpgrp(fd, pgid) < 0)
7714 return posix_error();
7715 Py_INCREF(Py_None);
7716 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007717}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007718#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007719
Guido van Rossum687dd131993-05-17 08:34:16 +00007720/* Functions acting on file descriptors */
7721
Victor Stinnerdaf45552013-08-28 00:53:59 +02007722#ifdef O_CLOEXEC
7723extern int _Py_open_cloexec_works;
7724#endif
7725
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007726PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007727"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7728Open a file for low level IO. Returns a file handle (integer).\n\
7729\n\
7730If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7731 and path should be relative; path will then be relative to that directory.\n\
7732dir_fd may not be implemented on your platform.\n\
7733 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007734
Barry Warsaw53699e91996-12-10 23:23:01 +00007735static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007736posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007737{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007738 path_t path;
7739 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007740 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007741 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007742 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007743 PyObject *return_value = NULL;
7744 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Victor Stinnerdaf45552013-08-28 00:53:59 +02007745#ifdef O_CLOEXEC
7746 int *atomic_flag_works = &_Py_open_cloexec_works;
7747#elif !defined(MS_WINDOWS)
7748 int *atomic_flag_works = NULL;
7749#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007750
Larry Hastings9cf065c2012-06-22 16:30:09 -07007751 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007752 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007753 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7754 path_converter, &path,
7755 &flags, &mode,
7756#ifdef HAVE_OPENAT
7757 dir_fd_converter, &dir_fd
7758#else
7759 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007760#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007761 ))
7762 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007763
Victor Stinnerdaf45552013-08-28 00:53:59 +02007764#ifdef MS_WINDOWS
7765 flags |= O_NOINHERIT;
7766#elif defined(O_CLOEXEC)
7767 flags |= O_CLOEXEC;
7768#endif
7769
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007771#ifdef MS_WINDOWS
7772 if (path.wide)
7773 fd = _wopen(path.wide, flags, mode);
7774 else
7775#endif
7776#ifdef HAVE_OPENAT
7777 if (dir_fd != DEFAULT_DIR_FD)
7778 fd = openat(dir_fd, path.narrow, flags, mode);
7779 else
7780#endif
7781 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007782 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007783
Larry Hastings9cf065c2012-06-22 16:30:09 -07007784 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007785 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007786 goto exit;
7787 }
7788
Victor Stinnerdaf45552013-08-28 00:53:59 +02007789#ifndef MS_WINDOWS
7790 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7791 close(fd);
7792 goto exit;
7793 }
7794#endif
7795
Larry Hastings9cf065c2012-06-22 16:30:09 -07007796 return_value = PyLong_FromLong((long)fd);
7797
7798exit:
7799 path_cleanup(&path);
7800 return return_value;
7801}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007802
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007803PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007804"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007805Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007806
Benjamin Peterson932bba32014-02-11 10:16:16 -05007807/*
7808The underscore at end of function name avoids a name clash with the libc
7809function posix_close.
7810*/
Barry Warsaw53699e91996-12-10 23:23:01 +00007811static PyObject *
Benjamin Peterson932bba32014-02-11 10:16:16 -05007812posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007813{
Victor Stinner8c62be82010-05-06 00:08:46 +00007814 int fd, res;
7815 if (!PyArg_ParseTuple(args, "i:close", &fd))
7816 return NULL;
7817 if (!_PyVerify_fd(fd))
7818 return posix_error();
7819 Py_BEGIN_ALLOW_THREADS
7820 res = close(fd);
7821 Py_END_ALLOW_THREADS
7822 if (res < 0)
7823 return posix_error();
7824 Py_INCREF(Py_None);
7825 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007826}
7827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007828
Victor Stinner8c62be82010-05-06 00:08:46 +00007829PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007830"closerange(fd_low, fd_high)\n\n\
7831Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7832
7833static PyObject *
7834posix_closerange(PyObject *self, PyObject *args)
7835{
Victor Stinner8c62be82010-05-06 00:08:46 +00007836 int fd_from, fd_to, i;
7837 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7838 return NULL;
7839 Py_BEGIN_ALLOW_THREADS
7840 for (i = fd_from; i < fd_to; i++)
7841 if (_PyVerify_fd(i))
7842 close(i);
7843 Py_END_ALLOW_THREADS
7844 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007845}
7846
7847
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007848PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007849"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007850Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007851
Barry Warsaw53699e91996-12-10 23:23:01 +00007852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007853posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007854{
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 int fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007856
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7858 return NULL;
Tim Golden23005082013-10-25 11:22:37 +01007859
Victor Stinnerdaf45552013-08-28 00:53:59 +02007860 fd = _Py_dup(fd);
7861 if (fd == -1)
7862 return NULL;
7863
Victor Stinner8c62be82010-05-06 00:08:46 +00007864 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007865}
7866
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007867
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007868PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007869"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007870Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007871
Barry Warsaw53699e91996-12-10 23:23:01 +00007872static PyObject *
Victor Stinnerdaf45552013-08-28 00:53:59 +02007873posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007874{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007875 static char *keywords[] = {"fd", "fd2", "inheritable", NULL};
7876 int fd, fd2;
7877 int inheritable = 1;
7878 int res;
7879#if defined(HAVE_DUP3) && \
7880 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7881 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7882 int dup3_works = -1;
7883#endif
7884
7885 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords,
7886 &fd, &fd2, &inheritable))
Victor Stinner8c62be82010-05-06 00:08:46 +00007887 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007888
Victor Stinner8c62be82010-05-06 00:08:46 +00007889 if (!_PyVerify_fd_dup2(fd, fd2))
7890 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007891
7892#ifdef MS_WINDOWS
7893 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007894 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007895 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007896 if (res < 0)
7897 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007898
7899 /* Character files like console cannot be make non-inheritable */
7900 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7901 close(fd2);
7902 return NULL;
7903 }
7904
7905#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7906 Py_BEGIN_ALLOW_THREADS
7907 if (!inheritable)
7908 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7909 else
7910 res = dup2(fd, fd2);
7911 Py_END_ALLOW_THREADS
7912 if (res < 0)
7913 return posix_error();
7914
7915#else
7916
7917#ifdef HAVE_DUP3
7918 if (!inheritable && dup3_works != 0) {
7919 Py_BEGIN_ALLOW_THREADS
7920 res = dup3(fd, fd2, O_CLOEXEC);
7921 Py_END_ALLOW_THREADS
7922 if (res < 0) {
7923 if (dup3_works == -1)
7924 dup3_works = (errno != ENOSYS);
7925 if (dup3_works)
7926 return posix_error();
7927 }
7928 }
7929
7930 if (inheritable || dup3_works == 0)
7931 {
7932#endif
7933 Py_BEGIN_ALLOW_THREADS
7934 res = dup2(fd, fd2);
7935 Py_END_ALLOW_THREADS
7936 if (res < 0)
7937 return posix_error();
7938
7939 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7940 close(fd2);
7941 return NULL;
7942 }
7943#ifdef HAVE_DUP3
7944 }
7945#endif
7946
7947#endif
7948
Victor Stinner8c62be82010-05-06 00:08:46 +00007949 Py_INCREF(Py_None);
7950 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007951}
7952
Ross Lagerwall7807c352011-03-17 20:20:30 +02007953#ifdef HAVE_LOCKF
7954PyDoc_STRVAR(posix_lockf__doc__,
7955"lockf(fd, cmd, len)\n\n\
7956Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7957fd is an open file descriptor.\n\
7958cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7959F_TEST.\n\
7960len specifies the section of the file to lock.");
7961
7962static PyObject *
7963posix_lockf(PyObject *self, PyObject *args)
7964{
7965 int fd, cmd, res;
7966 off_t len;
7967 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7968 &fd, &cmd, _parse_off_t, &len))
7969 return NULL;
7970
7971 Py_BEGIN_ALLOW_THREADS
7972 res = lockf(fd, cmd, len);
7973 Py_END_ALLOW_THREADS
7974
7975 if (res < 0)
7976 return posix_error();
7977
7978 Py_RETURN_NONE;
7979}
7980#endif
7981
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007982
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007983PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007984"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007985Set the current position of a file descriptor.\n\
7986Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007987
Barry Warsaw53699e91996-12-10 23:23:01 +00007988static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007989posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007990{
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007992#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007994#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007996#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007997 PyObject *posobj;
7998 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00008000#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008001 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8002 switch (how) {
8003 case 0: how = SEEK_SET; break;
8004 case 1: how = SEEK_CUR; break;
8005 case 2: how = SEEK_END; break;
8006 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008007#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008008
Ross Lagerwall8e749672011-03-17 21:54:07 +02008009#if !defined(HAVE_LARGEFILE_SUPPORT)
8010 pos = PyLong_AsLong(posobj);
8011#else
8012 pos = PyLong_AsLongLong(posobj);
8013#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 if (PyErr_Occurred())
8015 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008016
Victor Stinner8c62be82010-05-06 00:08:46 +00008017 if (!_PyVerify_fd(fd))
8018 return posix_error();
8019 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008020#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00008022#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008023 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00008024#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 Py_END_ALLOW_THREADS
8026 if (res < 0)
8027 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008028
8029#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008030 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008031#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008032 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008033#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008034}
8035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008036
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008037PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008038"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008039Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008040
Barry Warsaw53699e91996-12-10 23:23:01 +00008041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008042posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008043{
Victor Stinner8c62be82010-05-06 00:08:46 +00008044 int fd, size;
8045 Py_ssize_t n;
8046 PyObject *buffer;
8047 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
8048 return NULL;
8049 if (size < 0) {
8050 errno = EINVAL;
8051 return posix_error();
8052 }
8053 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8054 if (buffer == NULL)
8055 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00008056 if (!_PyVerify_fd(fd)) {
8057 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00008058 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00008059 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008060 Py_BEGIN_ALLOW_THREADS
8061 n = read(fd, PyBytes_AS_STRING(buffer), size);
8062 Py_END_ALLOW_THREADS
8063 if (n < 0) {
8064 Py_DECREF(buffer);
8065 return posix_error();
8066 }
8067 if (n != size)
8068 _PyBytes_Resize(&buffer, n);
8069 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008070}
8071
Ross Lagerwall7807c352011-03-17 20:20:30 +02008072#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8073 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008074static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008075iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8076{
8077 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008078 Py_ssize_t blen, total = 0;
8079
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008080 *iov = PyMem_New(struct iovec, cnt);
8081 if (*iov == NULL) {
8082 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008083 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008084 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008085
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008086 *buf = PyMem_New(Py_buffer, cnt);
8087 if (*buf == NULL) {
8088 PyMem_Del(*iov);
8089 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008090 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008091 }
8092
8093 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008094 PyObject *item = PySequence_GetItem(seq, i);
8095 if (item == NULL)
8096 goto fail;
8097 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8098 Py_DECREF(item);
8099 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008100 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008101 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008102 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008103 blen = (*buf)[i].len;
8104 (*iov)[i].iov_len = blen;
8105 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008106 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008107 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008108
8109fail:
8110 PyMem_Del(*iov);
8111 for (j = 0; j < i; j++) {
8112 PyBuffer_Release(&(*buf)[j]);
8113 }
8114 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008115 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008116}
8117
8118static void
8119iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8120{
8121 int i;
8122 PyMem_Del(iov);
8123 for (i = 0; i < cnt; i++) {
8124 PyBuffer_Release(&buf[i]);
8125 }
8126 PyMem_Del(buf);
8127}
8128#endif
8129
Ross Lagerwall7807c352011-03-17 20:20:30 +02008130#ifdef HAVE_READV
8131PyDoc_STRVAR(posix_readv__doc__,
8132"readv(fd, buffers) -> bytesread\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008133Read from a file descriptor fd into a number of mutable, bytes-like\n\
8134objects (\"buffers\"). readv will transfer data into each buffer\n\
8135until it is full and then move on to the next buffer in the sequence\n\
8136to hold the rest of the data.\n\n\
8137readv returns the total number of bytes read (which may be less than\n\
8138the total capacity of all the buffers.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008139
8140static PyObject *
8141posix_readv(PyObject *self, PyObject *args)
8142{
8143 int fd, cnt;
8144 Py_ssize_t n;
8145 PyObject *seq;
8146 struct iovec *iov;
8147 Py_buffer *buf;
8148
8149 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8150 return NULL;
8151 if (!PySequence_Check(seq)) {
8152 PyErr_SetString(PyExc_TypeError,
8153 "readv() arg 2 must be a sequence");
8154 return NULL;
8155 }
8156 cnt = PySequence_Size(seq);
8157
Victor Stinner57ddf782014-01-08 15:21:28 +01008158 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE) < 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008159 return NULL;
8160
8161 Py_BEGIN_ALLOW_THREADS
8162 n = readv(fd, iov, cnt);
8163 Py_END_ALLOW_THREADS
8164
8165 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008166 if (n < 0)
8167 return posix_error();
8168
Ross Lagerwall7807c352011-03-17 20:20:30 +02008169 return PyLong_FromSsize_t(n);
8170}
8171#endif
8172
8173#ifdef HAVE_PREAD
8174PyDoc_STRVAR(posix_pread__doc__,
8175"pread(fd, buffersize, offset) -> string\n\n\
8176Read from a file descriptor, fd, at a position of offset. It will read up\n\
8177to buffersize number of bytes. The file offset remains unchanged.");
8178
8179static PyObject *
8180posix_pread(PyObject *self, PyObject *args)
8181{
8182 int fd, size;
8183 off_t offset;
8184 Py_ssize_t n;
8185 PyObject *buffer;
8186 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8187 return NULL;
8188
8189 if (size < 0) {
8190 errno = EINVAL;
8191 return posix_error();
8192 }
8193 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8194 if (buffer == NULL)
8195 return NULL;
8196 if (!_PyVerify_fd(fd)) {
8197 Py_DECREF(buffer);
8198 return posix_error();
8199 }
8200 Py_BEGIN_ALLOW_THREADS
8201 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8202 Py_END_ALLOW_THREADS
8203 if (n < 0) {
8204 Py_DECREF(buffer);
8205 return posix_error();
8206 }
8207 if (n != size)
8208 _PyBytes_Resize(&buffer, n);
8209 return buffer;
8210}
8211#endif
8212
8213PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008214"write(fd, data) -> byteswritten\n\n\
8215Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008216
8217static PyObject *
8218posix_write(PyObject *self, PyObject *args)
8219{
8220 Py_buffer pbuf;
8221 int fd;
8222 Py_ssize_t size, len;
8223
8224 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8225 return NULL;
8226 if (!_PyVerify_fd(fd)) {
8227 PyBuffer_Release(&pbuf);
8228 return posix_error();
8229 }
8230 len = pbuf.len;
8231 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008232#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008233 if (len > INT_MAX)
8234 len = INT_MAX;
8235 size = write(fd, pbuf.buf, (int)len);
8236#else
8237 size = write(fd, pbuf.buf, len);
8238#endif
8239 Py_END_ALLOW_THREADS
8240 PyBuffer_Release(&pbuf);
8241 if (size < 0)
8242 return posix_error();
8243 return PyLong_FromSsize_t(size);
8244}
8245
8246#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008247PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008248"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008249sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008250 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008251Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008252
8253static PyObject *
8254posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8255{
8256 int in, out;
8257 Py_ssize_t ret;
8258 off_t offset;
8259
8260#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8261#ifndef __APPLE__
8262 Py_ssize_t len;
8263#endif
8264 PyObject *headers = NULL, *trailers = NULL;
8265 Py_buffer *hbuf, *tbuf;
8266 off_t sbytes;
8267 struct sf_hdtr sf;
8268 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008269 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008270 static char *keywords[] = {"out", "in",
8271 "offset", "count",
8272 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008273
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008274 sf.headers = NULL;
8275 sf.trailers = NULL;
8276
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008277#ifdef __APPLE__
8278 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008279 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008280#else
8281 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008282 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008283#endif
8284 &headers, &trailers, &flags))
8285 return NULL;
8286 if (headers != NULL) {
8287 if (!PySequence_Check(headers)) {
8288 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008289 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008290 return NULL;
8291 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008292 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008293 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008294 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008295 (i = iov_setup(&(sf.headers), &hbuf,
8296 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008297 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008298#ifdef __APPLE__
8299 sbytes += i;
8300#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008301 }
8302 }
8303 if (trailers != NULL) {
8304 if (!PySequence_Check(trailers)) {
8305 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008306 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008307 return NULL;
8308 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008309 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008310 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008311 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008312 (i = iov_setup(&(sf.trailers), &tbuf,
8313 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008314 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008315#ifdef __APPLE__
8316 sbytes += i;
8317#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008318 }
8319 }
8320
8321 Py_BEGIN_ALLOW_THREADS
8322#ifdef __APPLE__
8323 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8324#else
8325 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8326#endif
8327 Py_END_ALLOW_THREADS
8328
8329 if (sf.headers != NULL)
8330 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8331 if (sf.trailers != NULL)
8332 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8333
8334 if (ret < 0) {
8335 if ((errno == EAGAIN) || (errno == EBUSY)) {
8336 if (sbytes != 0) {
8337 // some data has been sent
8338 goto done;
8339 }
8340 else {
8341 // no data has been sent; upper application is supposed
8342 // to retry on EAGAIN or EBUSY
8343 return posix_error();
8344 }
8345 }
8346 return posix_error();
8347 }
8348 goto done;
8349
8350done:
8351 #if !defined(HAVE_LARGEFILE_SUPPORT)
8352 return Py_BuildValue("l", sbytes);
8353 #else
8354 return Py_BuildValue("L", sbytes);
8355 #endif
8356
8357#else
8358 Py_ssize_t count;
8359 PyObject *offobj;
8360 static char *keywords[] = {"out", "in",
8361 "offset", "count", NULL};
8362 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8363 keywords, &out, &in, &offobj, &count))
8364 return NULL;
8365#ifdef linux
8366 if (offobj == Py_None) {
8367 Py_BEGIN_ALLOW_THREADS
8368 ret = sendfile(out, in, NULL, count);
8369 Py_END_ALLOW_THREADS
8370 if (ret < 0)
8371 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008372 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008373 }
8374#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008375 if (!_parse_off_t(offobj, &offset))
8376 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008377 Py_BEGIN_ALLOW_THREADS
8378 ret = sendfile(out, in, &offset, count);
8379 Py_END_ALLOW_THREADS
8380 if (ret < 0)
8381 return posix_error();
8382 return Py_BuildValue("n", ret);
8383#endif
8384}
8385#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008386
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008387PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008388"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008389Like stat(), but for an open file descriptor.\n\
8390Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008391
Barry Warsaw53699e91996-12-10 23:23:01 +00008392static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008393posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008394{
Victor Stinner8c62be82010-05-06 00:08:46 +00008395 int fd;
8396 STRUCT_STAT st;
8397 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008398 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008399 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008400 Py_BEGIN_ALLOW_THREADS
8401 res = FSTAT(fd, &st);
8402 Py_END_ALLOW_THREADS
8403 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008404#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008405 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008406#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008407 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008408#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 }
Tim Peters5aa91602002-01-30 05:46:57 +00008410
Victor Stinner4195b5c2012-02-08 23:03:19 +01008411 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008412}
8413
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008414PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008415"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008416Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008417connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008418
8419static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008420posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008421{
Victor Stinner8c62be82010-05-06 00:08:46 +00008422 int fd;
8423 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8424 return NULL;
8425 if (!_PyVerify_fd(fd))
8426 return PyBool_FromLong(0);
8427 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008428}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008429
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008430#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008431PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008432"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008433Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008434
Barry Warsaw53699e91996-12-10 23:23:01 +00008435static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008436posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008437{
Victor Stinner8c62be82010-05-06 00:08:46 +00008438 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008439#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008440 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008441 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008442 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008443#else
8444 int res;
8445#endif
8446
8447#ifdef MS_WINDOWS
8448 attr.nLength = sizeof(attr);
8449 attr.lpSecurityDescriptor = NULL;
8450 attr.bInheritHandle = FALSE;
8451
8452 Py_BEGIN_ALLOW_THREADS
8453 ok = CreatePipe(&read, &write, &attr, 0);
8454 if (ok) {
8455 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8456 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8457 if (fds[0] == -1 || fds[1] == -1) {
8458 CloseHandle(read);
8459 CloseHandle(write);
8460 ok = 0;
8461 }
8462 }
8463 Py_END_ALLOW_THREADS
8464
Victor Stinner8c62be82010-05-06 00:08:46 +00008465 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008466 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008467#else
8468
8469#ifdef HAVE_PIPE2
8470 Py_BEGIN_ALLOW_THREADS
8471 res = pipe2(fds, O_CLOEXEC);
8472 Py_END_ALLOW_THREADS
8473
8474 if (res != 0 && errno == ENOSYS)
8475 {
8476#endif
8477 Py_BEGIN_ALLOW_THREADS
8478 res = pipe(fds);
8479 Py_END_ALLOW_THREADS
8480
8481 if (res == 0) {
8482 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8483 close(fds[0]);
8484 close(fds[1]);
8485 return NULL;
8486 }
8487 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8488 close(fds[0]);
8489 close(fds[1]);
8490 return NULL;
8491 }
8492 }
8493#ifdef HAVE_PIPE2
8494 }
8495#endif
8496
8497 if (res != 0)
8498 return PyErr_SetFromErrno(PyExc_OSError);
8499#endif /* !MS_WINDOWS */
8500 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008501}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008502#endif /* HAVE_PIPE */
8503
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008504#ifdef HAVE_PIPE2
8505PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008506"pipe2(flags) -> (read_end, write_end)\n\n\
8507Create a pipe with flags set atomically.\n\
8508flags can be constructed by ORing together one or more of these values:\n\
8509O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008510");
8511
8512static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008513posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008514{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008515 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008516 int fds[2];
8517 int res;
8518
Serhiy Storchaka78980432013-01-15 01:12:17 +02008519 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008520 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008521 return NULL;
8522
8523 res = pipe2(fds, flags);
8524 if (res != 0)
8525 return posix_error();
8526 return Py_BuildValue("(ii)", fds[0], fds[1]);
8527}
8528#endif /* HAVE_PIPE2 */
8529
Ross Lagerwall7807c352011-03-17 20:20:30 +02008530#ifdef HAVE_WRITEV
8531PyDoc_STRVAR(posix_writev__doc__,
8532"writev(fd, buffers) -> byteswritten\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008533Write the contents of *buffers* to file descriptor *fd*. *buffers*\n\
8534must be a sequence of bytes-like objects.\n\n\
8535writev writes the contents of each object to the file descriptor\n\
8536and returns the total number of bytes written.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008537
8538static PyObject *
8539posix_writev(PyObject *self, PyObject *args)
8540{
8541 int fd, cnt;
8542 Py_ssize_t res;
8543 PyObject *seq;
8544 struct iovec *iov;
8545 Py_buffer *buf;
8546 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8547 return NULL;
8548 if (!PySequence_Check(seq)) {
8549 PyErr_SetString(PyExc_TypeError,
8550 "writev() arg 2 must be a sequence");
8551 return NULL;
8552 }
8553 cnt = PySequence_Size(seq);
8554
Victor Stinner57ddf782014-01-08 15:21:28 +01008555 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008556 return NULL;
8557 }
8558
8559 Py_BEGIN_ALLOW_THREADS
8560 res = writev(fd, iov, cnt);
8561 Py_END_ALLOW_THREADS
8562
8563 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008564 if (res < 0)
8565 return posix_error();
8566
Ross Lagerwall7807c352011-03-17 20:20:30 +02008567 return PyLong_FromSsize_t(res);
8568}
8569#endif
8570
8571#ifdef HAVE_PWRITE
8572PyDoc_STRVAR(posix_pwrite__doc__,
8573"pwrite(fd, string, offset) -> byteswritten\n\n\
8574Write string to a file descriptor, fd, from offset, leaving the file\n\
8575offset unchanged.");
8576
8577static PyObject *
8578posix_pwrite(PyObject *self, PyObject *args)
8579{
8580 Py_buffer pbuf;
8581 int fd;
8582 off_t offset;
8583 Py_ssize_t size;
8584
8585 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8586 return NULL;
8587
8588 if (!_PyVerify_fd(fd)) {
8589 PyBuffer_Release(&pbuf);
8590 return posix_error();
8591 }
8592 Py_BEGIN_ALLOW_THREADS
8593 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8594 Py_END_ALLOW_THREADS
8595 PyBuffer_Release(&pbuf);
8596 if (size < 0)
8597 return posix_error();
8598 return PyLong_FromSsize_t(size);
8599}
8600#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008601
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008602#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008603PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008604"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8605Create a FIFO (a POSIX named pipe).\n\
8606\n\
8607If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8608 and path should be relative; path will then be relative to that directory.\n\
8609dir_fd may not be implemented on your platform.\n\
8610 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008611
Barry Warsaw53699e91996-12-10 23:23:01 +00008612static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008613posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008614{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008615 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008616 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008617 int dir_fd = DEFAULT_DIR_FD;
8618 int result;
8619 PyObject *return_value = NULL;
8620 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8621
8622 memset(&path, 0, sizeof(path));
8623 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8624 path_converter, &path,
8625 &mode,
8626#ifdef HAVE_MKFIFOAT
8627 dir_fd_converter, &dir_fd
8628#else
8629 dir_fd_unavailable, &dir_fd
8630#endif
8631 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008632 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008633
Victor Stinner8c62be82010-05-06 00:08:46 +00008634 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008635#ifdef HAVE_MKFIFOAT
8636 if (dir_fd != DEFAULT_DIR_FD)
8637 result = mkfifoat(dir_fd, path.narrow, mode);
8638 else
8639#endif
8640 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008641 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008642
8643 if (result < 0) {
8644 return_value = posix_error();
8645 goto exit;
8646 }
8647
8648 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008649 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008650
8651exit:
8652 path_cleanup(&path);
8653 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008654}
8655#endif
8656
Neal Norwitz11690112002-07-30 01:08:28 +00008657#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008658PyDoc_STRVAR(posix_mknod__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008659"mknod(path, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008660Create a filesystem node (file, device special file or named pipe)\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008661named path. mode specifies both the permissions to use and the\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008662type of node to be created, being combined (bitwise OR) with one of\n\
8663S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008664device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008665os.makedev()), otherwise it is ignored.\n\
8666\n\
8667If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8668 and path should be relative; path will then be relative to that directory.\n\
8669dir_fd may not be implemented on your platform.\n\
8670 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008671
8672
8673static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008674posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008675{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008676 path_t path;
8677 int mode = 0666;
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008678 dev_t device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008679 int dir_fd = DEFAULT_DIR_FD;
8680 int result;
8681 PyObject *return_value = NULL;
8682 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8683
8684 memset(&path, 0, sizeof(path));
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008685 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|iO&$O&:mknod", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008686 path_converter, &path,
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008687 &mode, _Py_Dev_Converter, &device,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008688#ifdef HAVE_MKNODAT
8689 dir_fd_converter, &dir_fd
8690#else
8691 dir_fd_unavailable, &dir_fd
8692#endif
8693 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008695
Victor Stinner8c62be82010-05-06 00:08:46 +00008696 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008697#ifdef HAVE_MKNODAT
8698 if (dir_fd != DEFAULT_DIR_FD)
8699 result = mknodat(dir_fd, path.narrow, mode, device);
8700 else
8701#endif
8702 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008703 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008704
8705 if (result < 0) {
8706 return_value = posix_error();
8707 goto exit;
8708 }
8709
8710 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008711 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008712
Larry Hastings9cf065c2012-06-22 16:30:09 -07008713exit:
8714 path_cleanup(&path);
8715 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008716}
8717#endif
8718
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008719#ifdef HAVE_DEVICE_MACROS
8720PyDoc_STRVAR(posix_major__doc__,
8721"major(device) -> major number\n\
8722Extracts a device major number from a raw device number.");
8723
8724static PyObject *
8725posix_major(PyObject *self, PyObject *args)
8726{
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008727 dev_t device;
8728 if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00008729 return NULL;
8730 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008731}
8732
8733PyDoc_STRVAR(posix_minor__doc__,
8734"minor(device) -> minor number\n\
8735Extracts a device minor number from a raw device number.");
8736
8737static PyObject *
8738posix_minor(PyObject *self, PyObject *args)
8739{
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008740 dev_t device;
8741 if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00008742 return NULL;
8743 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008744}
8745
8746PyDoc_STRVAR(posix_makedev__doc__,
8747"makedev(major, minor) -> device number\n\
8748Composes a raw device number from the major and minor device numbers.");
8749
8750static PyObject *
8751posix_makedev(PyObject *self, PyObject *args)
8752{
Victor Stinner8c62be82010-05-06 00:08:46 +00008753 int major, minor;
8754 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8755 return NULL;
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008756 return _PyLong_FromDev(makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008757}
8758#endif /* device macros */
8759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008760
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008761#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008762PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008763"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008764Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008765
Barry Warsaw53699e91996-12-10 23:23:01 +00008766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008767posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008768{
Victor Stinner8c62be82010-05-06 00:08:46 +00008769 int fd;
8770 off_t length;
8771 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008772
Ross Lagerwall7807c352011-03-17 20:20:30 +02008773 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008774 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008775
Victor Stinner8c62be82010-05-06 00:08:46 +00008776 Py_BEGIN_ALLOW_THREADS
8777 res = ftruncate(fd, length);
8778 Py_END_ALLOW_THREADS
8779 if (res < 0)
8780 return posix_error();
8781 Py_INCREF(Py_None);
8782 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008783}
8784#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008785
Ross Lagerwall7807c352011-03-17 20:20:30 +02008786#ifdef HAVE_TRUNCATE
8787PyDoc_STRVAR(posix_truncate__doc__,
8788"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008789Truncate the file given by path to length bytes.\n\
8790On some platforms, path may also be specified as an open file descriptor.\n\
8791 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008792
8793static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008794posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008795{
Georg Brandl306336b2012-06-24 12:55:33 +02008796 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008797 off_t length;
8798 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008799 PyObject *result = NULL;
8800 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008801
Georg Brandl306336b2012-06-24 12:55:33 +02008802 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008803 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008804#ifdef HAVE_FTRUNCATE
8805 path.allow_fd = 1;
8806#endif
8807 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8808 path_converter, &path,
8809 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008810 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008811
8812 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008813#ifdef HAVE_FTRUNCATE
8814 if (path.fd != -1)
8815 res = ftruncate(path.fd, length);
8816 else
8817#endif
8818 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008819 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008820 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008821 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008822 else {
8823 Py_INCREF(Py_None);
8824 result = Py_None;
8825 }
8826 path_cleanup(&path);
8827 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008828}
8829#endif
8830
Victor Stinnerd6b17692014-09-30 12:20:05 +02008831/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8832 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8833 defined, which is the case in Python on AIX. AIX bug report:
8834 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8835#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8836# define POSIX_FADVISE_AIX_BUG
8837#endif
8838
8839#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008840PyDoc_STRVAR(posix_posix_fallocate__doc__,
8841"posix_fallocate(fd, offset, len)\n\n\
8842Ensures that enough disk space is allocated for the file specified by fd\n\
8843starting from offset and continuing for len bytes.");
8844
8845static PyObject *
8846posix_posix_fallocate(PyObject *self, PyObject *args)
8847{
8848 off_t len, offset;
8849 int res, fd;
8850
8851 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8852 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8853 return NULL;
8854
8855 Py_BEGIN_ALLOW_THREADS
8856 res = posix_fallocate(fd, offset, len);
8857 Py_END_ALLOW_THREADS
8858 if (res != 0) {
8859 errno = res;
8860 return posix_error();
8861 }
8862 Py_RETURN_NONE;
8863}
8864#endif
8865
Victor Stinnerd6b17692014-09-30 12:20:05 +02008866#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008867PyDoc_STRVAR(posix_posix_fadvise__doc__,
8868"posix_fadvise(fd, offset, len, advice)\n\n\
8869Announces an intention to access data in a specific pattern thus allowing\n\
8870the kernel to make optimizations.\n\
8871The advice applies to the region of the file specified by fd starting at\n\
8872offset and continuing for len bytes.\n\
8873advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8874POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8875POSIX_FADV_DONTNEED.");
8876
8877static PyObject *
8878posix_posix_fadvise(PyObject *self, PyObject *args)
8879{
8880 off_t len, offset;
8881 int res, fd, advice;
8882
8883 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8884 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8885 return NULL;
8886
8887 Py_BEGIN_ALLOW_THREADS
8888 res = posix_fadvise(fd, offset, len, advice);
8889 Py_END_ALLOW_THREADS
8890 if (res != 0) {
8891 errno = res;
8892 return posix_error();
8893 }
8894 Py_RETURN_NONE;
8895}
8896#endif
8897
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008898#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008899PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008900"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008901Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008902
Fred Drake762e2061999-08-26 17:23:54 +00008903/* Save putenv() parameters as values here, so we can collect them when they
8904 * get re-set with another call for the same key. */
8905static PyObject *posix_putenv_garbage;
8906
Tim Peters5aa91602002-01-30 05:46:57 +00008907static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008908posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008909{
Victor Stinner84ae1182010-05-06 22:05:07 +00008910 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008911#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008912 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008913 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008914
Victor Stinner8c62be82010-05-06 00:08:46 +00008915 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008916 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008917 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008918 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008919
Victor Stinner65170952011-11-22 22:16:17 +01008920 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008921 if (newstr == NULL) {
8922 PyErr_NoMemory();
8923 goto error;
8924 }
Victor Stinner65170952011-11-22 22:16:17 +01008925 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8926 PyErr_Format(PyExc_ValueError,
8927 "the environment variable is longer than %u characters",
8928 _MAX_ENV);
8929 goto error;
8930 }
8931
Victor Stinner8c62be82010-05-06 00:08:46 +00008932 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008933 if (newenv == NULL)
8934 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008936 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008937 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008938 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008939#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008940 PyObject *os1, *os2;
8941 char *s1, *s2;
8942 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008943
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008944 if (!PyArg_ParseTuple(args,
8945 "O&O&:putenv",
8946 PyUnicode_FSConverter, &os1,
8947 PyUnicode_FSConverter, &os2))
8948 return NULL;
8949 s1 = PyBytes_AsString(os1);
8950 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008951
Victor Stinner65170952011-11-22 22:16:17 +01008952 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008953 if (newstr == NULL) {
8954 PyErr_NoMemory();
8955 goto error;
8956 }
8957
Victor Stinner8c62be82010-05-06 00:08:46 +00008958 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008959 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008960 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008961 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008962 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008963#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008964
Victor Stinner8c62be82010-05-06 00:08:46 +00008965 /* Install the first arg and newstr in posix_putenv_garbage;
8966 * this will cause previous value to be collected. This has to
8967 * happen after the real putenv() call because the old value
8968 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008969 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008970 /* really not much we can do; just leak */
8971 PyErr_Clear();
8972 }
8973 else {
8974 Py_DECREF(newstr);
8975 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008976
Martin v. Löwis011e8422009-05-05 04:43:17 +00008977#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008978 Py_DECREF(os1);
8979 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008980#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008981 Py_RETURN_NONE;
8982
8983error:
8984#ifndef MS_WINDOWS
8985 Py_DECREF(os1);
8986 Py_DECREF(os2);
8987#endif
8988 Py_XDECREF(newstr);
8989 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008990}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008991#endif /* putenv */
8992
Guido van Rossumc524d952001-10-19 01:31:59 +00008993#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008994PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008995"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008996Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008997
8998static PyObject *
8999posix_unsetenv(PyObject *self, PyObject *args)
9000{
Victor Stinner65170952011-11-22 22:16:17 +01009001 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01009002#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009003 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009004#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009005
9006 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00009007
Victor Stinner65170952011-11-22 22:16:17 +01009008 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00009009 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00009010
Victor Stinner984890f2011-11-24 13:53:38 +01009011#ifdef HAVE_BROKEN_UNSETENV
9012 unsetenv(PyBytes_AS_STRING(name));
9013#else
Victor Stinner65170952011-11-22 22:16:17 +01009014 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06009015 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06009016 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01009017 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06009018 }
Victor Stinner984890f2011-11-24 13:53:38 +01009019#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009020
Victor Stinner8c62be82010-05-06 00:08:46 +00009021 /* Remove the key from posix_putenv_garbage;
9022 * this will cause it to be collected. This has to
9023 * happen after the real unsetenv() call because the
9024 * old value was still accessible until then.
9025 */
Victor Stinner65170952011-11-22 22:16:17 +01009026 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009027 /* really not much we can do; just leak */
9028 PyErr_Clear();
9029 }
Victor Stinner65170952011-11-22 22:16:17 +01009030 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00009031 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009032}
9033#endif /* unsetenv */
9034
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009035PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009036"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009037Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009038
Guido van Rossumf68d8e52001-04-14 17:55:09 +00009039static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009040posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00009041{
Victor Stinner8c62be82010-05-06 00:08:46 +00009042 int code;
9043 char *message;
9044 if (!PyArg_ParseTuple(args, "i:strerror", &code))
9045 return NULL;
9046 message = strerror(code);
9047 if (message == NULL) {
9048 PyErr_SetString(PyExc_ValueError,
9049 "strerror() argument out of range");
9050 return NULL;
9051 }
Victor Stinner1b579672011-12-17 05:47:23 +01009052 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009053}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009054
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009055
Guido van Rossumc9641791998-08-04 15:26:23 +00009056#ifdef HAVE_SYS_WAIT_H
9057
Fred Drake106c1a02002-04-23 15:58:02 +00009058#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009059PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009060"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009061Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00009062
9063static PyObject *
9064posix_WCOREDUMP(PyObject *self, PyObject *args)
9065{
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 WAIT_TYPE status;
9067 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009068
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
9070 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009071
Victor Stinner8c62be82010-05-06 00:08:46 +00009072 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009073}
9074#endif /* WCOREDUMP */
9075
9076#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009077PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009078"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00009079Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009080job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00009081
9082static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009083posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00009084{
Victor Stinner8c62be82010-05-06 00:08:46 +00009085 WAIT_TYPE status;
9086 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009087
Victor Stinner8c62be82010-05-06 00:08:46 +00009088 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
9089 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009090
Victor Stinner8c62be82010-05-06 00:08:46 +00009091 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009092}
9093#endif /* WIFCONTINUED */
9094
Guido van Rossumc9641791998-08-04 15:26:23 +00009095#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009096PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009097"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009098Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009099
9100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009101posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009102{
Victor Stinner8c62be82010-05-06 00:08:46 +00009103 WAIT_TYPE status;
9104 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009105
Victor Stinner8c62be82010-05-06 00:08:46 +00009106 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
9107 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009108
Victor Stinner8c62be82010-05-06 00:08:46 +00009109 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009110}
9111#endif /* WIFSTOPPED */
9112
9113#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009114PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009115"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009116Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009117
9118static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009119posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009120{
Victor Stinner8c62be82010-05-06 00:08:46 +00009121 WAIT_TYPE status;
9122 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009123
Victor Stinner8c62be82010-05-06 00:08:46 +00009124 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9125 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009126
Victor Stinner8c62be82010-05-06 00:08:46 +00009127 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009128}
9129#endif /* WIFSIGNALED */
9130
9131#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009132PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009133"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009134Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009135system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009136
9137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009138posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009139{
Victor Stinner8c62be82010-05-06 00:08:46 +00009140 WAIT_TYPE status;
9141 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009142
Victor Stinner8c62be82010-05-06 00:08:46 +00009143 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9144 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009145
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009147}
9148#endif /* WIFEXITED */
9149
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009150#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009151PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009152"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009153Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009154
9155static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009156posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009157{
Victor Stinner8c62be82010-05-06 00:08:46 +00009158 WAIT_TYPE status;
9159 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009160
Victor Stinner8c62be82010-05-06 00:08:46 +00009161 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9162 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009163
Victor Stinner8c62be82010-05-06 00:08:46 +00009164 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009165}
9166#endif /* WEXITSTATUS */
9167
9168#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009169PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009170"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009171Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009172value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009173
9174static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009175posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009176{
Victor Stinner8c62be82010-05-06 00:08:46 +00009177 WAIT_TYPE status;
9178 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009179
Victor Stinner8c62be82010-05-06 00:08:46 +00009180 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9181 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009182
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009184}
9185#endif /* WTERMSIG */
9186
9187#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009188PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009189"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009190Return the signal that stopped the process that provided\n\
9191the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009192
9193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009194posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009195{
Victor Stinner8c62be82010-05-06 00:08:46 +00009196 WAIT_TYPE status;
9197 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009198
Victor Stinner8c62be82010-05-06 00:08:46 +00009199 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9200 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009201
Victor Stinner8c62be82010-05-06 00:08:46 +00009202 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009203}
9204#endif /* WSTOPSIG */
9205
9206#endif /* HAVE_SYS_WAIT_H */
9207
9208
Thomas Wouters477c8d52006-05-27 19:21:47 +00009209#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009210#ifdef _SCO_DS
9211/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9212 needed definitions in sys/statvfs.h */
9213#define _SVID3
9214#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009215#include <sys/statvfs.h>
9216
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009217static PyObject*
9218_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009219 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9220 if (v == NULL)
9221 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009222
9223#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009224 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9225 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9226 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9227 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9228 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9229 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9230 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9231 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9232 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9233 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009234#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009235 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9236 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9237 PyStructSequence_SET_ITEM(v, 2,
9238 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9239 PyStructSequence_SET_ITEM(v, 3,
9240 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9241 PyStructSequence_SET_ITEM(v, 4,
9242 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9243 PyStructSequence_SET_ITEM(v, 5,
9244 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9245 PyStructSequence_SET_ITEM(v, 6,
9246 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9247 PyStructSequence_SET_ITEM(v, 7,
9248 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9249 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9250 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009251#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009252 if (PyErr_Occurred()) {
9253 Py_DECREF(v);
9254 return NULL;
9255 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009256
Victor Stinner8c62be82010-05-06 00:08:46 +00009257 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009258}
9259
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009260PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009261"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009262Perform an fstatvfs system call on the given fd.\n\
9263Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009264
9265static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009266posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009267{
Victor Stinner8c62be82010-05-06 00:08:46 +00009268 int fd, res;
9269 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009270
Victor Stinner8c62be82010-05-06 00:08:46 +00009271 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9272 return NULL;
9273 Py_BEGIN_ALLOW_THREADS
9274 res = fstatvfs(fd, &st);
9275 Py_END_ALLOW_THREADS
9276 if (res != 0)
9277 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009278
Victor Stinner8c62be82010-05-06 00:08:46 +00009279 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009280}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009281#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009282
9283
Thomas Wouters477c8d52006-05-27 19:21:47 +00009284#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009285#include <sys/statvfs.h>
9286
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009287PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009288"statvfs(path)\n\n\
9289Perform a statvfs system call on the given path.\n\
9290\n\
9291path may always be specified as a string.\n\
9292On some platforms, path may also be specified as an open file descriptor.\n\
9293 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009294
9295static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009296posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009297{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009298 static char *keywords[] = {"path", NULL};
9299 path_t path;
9300 int result;
9301 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009302 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009303
Larry Hastings9cf065c2012-06-22 16:30:09 -07009304 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009305 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009306#ifdef HAVE_FSTATVFS
9307 path.allow_fd = 1;
9308#endif
9309 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9310 path_converter, &path
9311 ))
9312 return NULL;
9313
9314 Py_BEGIN_ALLOW_THREADS
9315#ifdef HAVE_FSTATVFS
9316 if (path.fd != -1) {
9317#ifdef __APPLE__
9318 /* handle weak-linking on Mac OS X 10.3 */
9319 if (fstatvfs == NULL) {
9320 fd_specified("statvfs", path.fd);
9321 goto exit;
9322 }
9323#endif
9324 result = fstatvfs(path.fd, &st);
9325 }
9326 else
9327#endif
9328 result = statvfs(path.narrow, &st);
9329 Py_END_ALLOW_THREADS
9330
9331 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009332 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009333 goto exit;
9334 }
9335
9336 return_value = _pystatvfs_fromstructstatvfs(st);
9337
9338exit:
9339 path_cleanup(&path);
9340 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009341}
9342#endif /* HAVE_STATVFS */
9343
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009344#ifdef MS_WINDOWS
9345PyDoc_STRVAR(win32__getdiskusage__doc__,
9346"_getdiskusage(path) -> (total, free)\n\n\
9347Return disk usage statistics about the given path as (total, free) tuple.");
9348
9349static PyObject *
9350win32__getdiskusage(PyObject *self, PyObject *args)
9351{
9352 BOOL retval;
9353 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009354 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009355
Victor Stinner6139c1b2011-11-09 22:14:14 +01009356 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009357 return NULL;
9358
9359 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009360 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009361 Py_END_ALLOW_THREADS
9362 if (retval == 0)
9363 return PyErr_SetFromWindowsErr(0);
9364
9365 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9366}
9367#endif
9368
9369
Fred Drakec9680921999-12-13 16:37:25 +00009370/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9371 * It maps strings representing configuration variable names to
9372 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009373 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009374 * rarely-used constants. There are three separate tables that use
9375 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009376 *
9377 * This code is always included, even if none of the interfaces that
9378 * need it are included. The #if hackery needed to avoid it would be
9379 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009380 */
9381struct constdef {
9382 char *name;
9383 long value;
9384};
9385
Fred Drake12c6e2d1999-12-14 21:25:03 +00009386static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009387conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009388 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009389{
Christian Heimes217cfd12007-12-02 14:31:20 +00009390 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009391 *valuep = PyLong_AS_LONG(arg);
9392 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009393 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009394 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009395 /* look up the value in the table using a binary search */
9396 size_t lo = 0;
9397 size_t mid;
9398 size_t hi = tablesize;
9399 int cmp;
9400 const char *confname;
9401 if (!PyUnicode_Check(arg)) {
9402 PyErr_SetString(PyExc_TypeError,
9403 "configuration names must be strings or integers");
9404 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009405 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009406 confname = _PyUnicode_AsString(arg);
9407 if (confname == NULL)
9408 return 0;
9409 while (lo < hi) {
9410 mid = (lo + hi) / 2;
9411 cmp = strcmp(confname, table[mid].name);
9412 if (cmp < 0)
9413 hi = mid;
9414 else if (cmp > 0)
9415 lo = mid + 1;
9416 else {
9417 *valuep = table[mid].value;
9418 return 1;
9419 }
9420 }
9421 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9422 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009423 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009424}
9425
9426
9427#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9428static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009429#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009430 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009431#endif
9432#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009433 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009434#endif
Fred Drakec9680921999-12-13 16:37:25 +00009435#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009436 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009437#endif
9438#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009439 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009440#endif
9441#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009442 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009443#endif
9444#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009445 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009446#endif
9447#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009448 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009449#endif
9450#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009451 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009452#endif
9453#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009454 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009455#endif
9456#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009457 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009458#endif
9459#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009460 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009461#endif
9462#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009463 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009464#endif
9465#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009466 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009467#endif
9468#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009470#endif
9471#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009472 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009473#endif
9474#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009475 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009476#endif
9477#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009478 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009479#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009480#ifdef _PC_ACL_ENABLED
9481 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9482#endif
9483#ifdef _PC_MIN_HOLE_SIZE
9484 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9485#endif
9486#ifdef _PC_ALLOC_SIZE_MIN
9487 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9488#endif
9489#ifdef _PC_REC_INCR_XFER_SIZE
9490 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9491#endif
9492#ifdef _PC_REC_MAX_XFER_SIZE
9493 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9494#endif
9495#ifdef _PC_REC_MIN_XFER_SIZE
9496 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9497#endif
9498#ifdef _PC_REC_XFER_ALIGN
9499 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9500#endif
9501#ifdef _PC_SYMLINK_MAX
9502 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9503#endif
9504#ifdef _PC_XATTR_ENABLED
9505 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9506#endif
9507#ifdef _PC_XATTR_EXISTS
9508 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9509#endif
9510#ifdef _PC_TIMESTAMP_RESOLUTION
9511 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9512#endif
Fred Drakec9680921999-12-13 16:37:25 +00009513};
9514
Fred Drakec9680921999-12-13 16:37:25 +00009515static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009516conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009517{
9518 return conv_confname(arg, valuep, posix_constants_pathconf,
9519 sizeof(posix_constants_pathconf)
9520 / sizeof(struct constdef));
9521}
9522#endif
9523
9524#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009525PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009526"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009527Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009528If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009529
9530static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009531posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009532{
9533 PyObject *result = NULL;
9534 int name, fd;
9535
Fred Drake12c6e2d1999-12-14 21:25:03 +00009536 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9537 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009538 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009539
Stefan Krah0e803b32010-11-26 16:16:47 +00009540 errno = 0;
9541 limit = fpathconf(fd, name);
9542 if (limit == -1 && errno != 0)
9543 posix_error();
9544 else
9545 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009546 }
9547 return result;
9548}
9549#endif
9550
9551
9552#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009553PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009554"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009555Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009556If there is no limit, return -1.\n\
9557On some platforms, path may also be specified as an open file descriptor.\n\
9558 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009559
9560static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009561posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009562{
Georg Brandl306336b2012-06-24 12:55:33 +02009563 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009564 PyObject *result = NULL;
9565 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009566 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009567
Georg Brandl306336b2012-06-24 12:55:33 +02009568 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009569 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009570#ifdef HAVE_FPATHCONF
9571 path.allow_fd = 1;
9572#endif
9573 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9574 path_converter, &path,
9575 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009577
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009579#ifdef HAVE_FPATHCONF
9580 if (path.fd != -1)
9581 limit = fpathconf(path.fd, name);
9582 else
9583#endif
9584 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 if (limit == -1 && errno != 0) {
9586 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009587 /* could be a path or name problem */
9588 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009589 else
Victor Stinner292c8352012-10-30 02:17:38 +01009590 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 }
9592 else
9593 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009594 }
Georg Brandl306336b2012-06-24 12:55:33 +02009595 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009596 return result;
9597}
9598#endif
9599
9600#ifdef HAVE_CONFSTR
9601static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009602#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009604#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009605#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009607#endif
9608#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009610#endif
Fred Draked86ed291999-12-15 15:34:33 +00009611#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009613#endif
9614#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009616#endif
9617#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009619#endif
9620#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009622#endif
Fred Drakec9680921999-12-13 16:37:25 +00009623#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009625#endif
9626#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009628#endif
9629#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009630 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009631#endif
9632#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009633 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009634#endif
9635#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009636 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009637#endif
9638#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009640#endif
9641#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009643#endif
9644#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009646#endif
Fred Draked86ed291999-12-15 15:34:33 +00009647#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009649#endif
Fred Drakec9680921999-12-13 16:37:25 +00009650#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009652#endif
Fred Draked86ed291999-12-15 15:34:33 +00009653#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009655#endif
9656#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009658#endif
9659#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009661#endif
9662#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009664#endif
Fred Drakec9680921999-12-13 16:37:25 +00009665#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009666 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009667#endif
9668#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009670#endif
9671#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009673#endif
9674#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009676#endif
9677#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009679#endif
9680#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009682#endif
9683#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009685#endif
9686#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009688#endif
9689#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009691#endif
9692#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009694#endif
9695#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009697#endif
9698#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009700#endif
9701#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009703#endif
9704#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009706#endif
9707#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009709#endif
9710#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009712#endif
Fred Draked86ed291999-12-15 15:34:33 +00009713#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009715#endif
9716#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009718#endif
9719#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009721#endif
9722#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009724#endif
9725#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009727#endif
9728#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009730#endif
9731#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009733#endif
9734#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009736#endif
9737#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009739#endif
9740#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009742#endif
9743#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009745#endif
9746#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009748#endif
9749#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009751#endif
Fred Drakec9680921999-12-13 16:37:25 +00009752};
9753
9754static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009755conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009756{
9757 return conv_confname(arg, valuep, posix_constants_confstr,
9758 sizeof(posix_constants_confstr)
9759 / sizeof(struct constdef));
9760}
9761
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009762PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009763"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009764Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009765
9766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009767posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009768{
9769 PyObject *result = NULL;
9770 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009771 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009772 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009773
Victor Stinnercb043522010-09-10 23:49:04 +00009774 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9775 return NULL;
9776
9777 errno = 0;
9778 len = confstr(name, buffer, sizeof(buffer));
9779 if (len == 0) {
9780 if (errno) {
9781 posix_error();
9782 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009783 }
9784 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009785 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009786 }
9787 }
Victor Stinnercb043522010-09-10 23:49:04 +00009788
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009789 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009790 char *buf = PyMem_Malloc(len);
9791 if (buf == NULL)
9792 return PyErr_NoMemory();
9793 confstr(name, buf, len);
9794 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9795 PyMem_Free(buf);
9796 }
9797 else
9798 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009799 return result;
9800}
9801#endif
9802
9803
9804#ifdef HAVE_SYSCONF
9805static struct constdef posix_constants_sysconf[] = {
9806#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
Fred Draked86ed291999-12-15 15:34:33 +00009836#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009838#endif
9839#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009841#endif
Fred Drakec9680921999-12-13 16:37:25 +00009842#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
Fred Drakec9680921999-12-13 16:37:25 +00009845#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
Fred Draked86ed291999-12-15 15:34:33 +00009860#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009862#endif
Fred Drakec9680921999-12-13 16:37:25 +00009863#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
9872#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
Fred Draked86ed291999-12-15 15:34:33 +00009878#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009880#endif
Fred Drakec9680921999-12-13 16:37:25 +00009881#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
9884#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
9887#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
9890#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
9893#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
9908#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
Fred Draked86ed291999-12-15 15:34:33 +00009950#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009952#endif
Fred Drakec9680921999-12-13 16:37:25 +00009953#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
Fred Draked86ed291999-12-15 15:34:33 +00009962#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009964#endif
Fred Drakec9680921999-12-13 16:37:25 +00009965#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
Fred Draked86ed291999-12-15 15:34:33 +00009968#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009970#endif
9971#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009973#endif
Fred Drakec9680921999-12-13 16:37:25 +00009974#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
Fred Draked86ed291999-12-15 15:34:33 +00009986#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009988#endif
Fred Drakec9680921999-12-13 16:37:25 +00009989#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
Fred Draked86ed291999-12-15 15:34:33 +000010010#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010012#endif
Fred Drakec9680921999-12-13 16:37:25 +000010013#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
Fred Draked86ed291999-12-15 15:34:33 +000010019#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010021#endif
Fred Drakec9680921999-12-13 16:37:25 +000010022#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
Fred Draked86ed291999-12-15 15:34:33 +000010049#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010051#endif
10052#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010054#endif
Fred Drakec9680921999-12-13 16:37:25 +000010055#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
Fred Draked86ed291999-12-15 15:34:33 +000010160#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010162#endif
Fred Drakec9680921999-12-13 16:37:25 +000010163#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
10259#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
10262#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
10265#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
10268#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
10271#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010273#endif
10274#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
10277#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010279#endif
10280#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010282#endif
10283#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010285#endif
10286#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
10289#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010291#endif
10292#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010294#endif
10295#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298};
10299
10300static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010301conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010302{
10303 return conv_confname(arg, valuep, posix_constants_sysconf,
10304 sizeof(posix_constants_sysconf)
10305 / sizeof(struct constdef));
10306}
10307
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010308PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010309"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010310Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010311
10312static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010313posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010314{
10315 PyObject *result = NULL;
10316 int name;
10317
10318 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +020010319 long value;
Fred Drakec9680921999-12-13 16:37:25 +000010320
10321 errno = 0;
10322 value = sysconf(name);
10323 if (value == -1 && errno != 0)
10324 posix_error();
10325 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010326 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010327 }
10328 return result;
10329}
10330#endif
10331
10332
Fred Drakebec628d1999-12-15 18:31:10 +000010333/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010334 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010335 * the exported dictionaries that are used to publish information about the
10336 * names available on the host platform.
10337 *
10338 * Sorting the table at runtime ensures that the table is properly ordered
10339 * when used, even for platforms we're not able to test on. It also makes
10340 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010341 */
Fred Drakebec628d1999-12-15 18:31:10 +000010342
10343static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010344cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010345{
10346 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010348 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010350
10351 return strcmp(c1->name, c2->name);
10352}
10353
10354static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010355setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010357{
Fred Drakebec628d1999-12-15 18:31:10 +000010358 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010359 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010360
10361 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10362 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010363 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010365
Barry Warsaw3155db32000-04-13 15:20:40 +000010366 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 PyObject *o = PyLong_FromLong(table[i].value);
10368 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10369 Py_XDECREF(o);
10370 Py_DECREF(d);
10371 return -1;
10372 }
10373 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010374 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010375 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010376}
10377
Fred Drakebec628d1999-12-15 18:31:10 +000010378/* Return -1 on failure, 0 on success. */
10379static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010380setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010381{
10382#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010383 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010384 sizeof(posix_constants_pathconf)
10385 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010386 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010387 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010388#endif
10389#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010390 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010391 sizeof(posix_constants_confstr)
10392 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010393 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010394 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010395#endif
10396#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010397 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010398 sizeof(posix_constants_sysconf)
10399 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010400 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010401 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010402#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010403 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010404}
Fred Draked86ed291999-12-15 15:34:33 +000010405
10406
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010407PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010408"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010409Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010410in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010411
10412static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010413posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010414{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010415 abort();
10416 /*NOTREACHED*/
10417 Py_FatalError("abort() called from Python code didn't abort!");
10418 return NULL;
10419}
Fred Drakebec628d1999-12-15 18:31:10 +000010420
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010421#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010422PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010423"startfile(filepath [, operation]) - Start a file with its associated\n\
10424application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010425\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010426When \"operation\" is not specified or \"open\", this acts like\n\
10427double-clicking the file in Explorer, or giving the file name as an\n\
10428argument to the DOS \"start\" command: the file is opened with whatever\n\
10429application (if any) its extension is associated.\n\
10430When another \"operation\" is given, it specifies what should be done with\n\
10431the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010432\n\
10433startfile returns as soon as the associated application is launched.\n\
10434There is no option to wait for the application to close, and no way\n\
10435to retrieve the application's exit status.\n\
10436\n\
10437The filepath is relative to the current directory. If you want to use\n\
10438an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010439the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010440
10441static PyObject *
10442win32_startfile(PyObject *self, PyObject *args)
10443{
Victor Stinner8c62be82010-05-06 00:08:46 +000010444 PyObject *ofilepath;
10445 char *filepath;
10446 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010447 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010448 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010449
Victor Stinnereb5657a2011-09-30 01:44:27 +020010450 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 if (!PyArg_ParseTuple(args, "U|s:startfile",
10452 &unipath, &operation)) {
10453 PyErr_Clear();
10454 goto normal;
10455 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010456
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010458 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010459 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010460 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010461 PyErr_Clear();
10462 operation = NULL;
10463 goto normal;
10464 }
10465 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010466
Victor Stinnereb5657a2011-09-30 01:44:27 +020010467 wpath = PyUnicode_AsUnicode(unipath);
10468 if (wpath == NULL)
10469 goto normal;
10470 if (uoperation) {
10471 woperation = PyUnicode_AsUnicode(uoperation);
10472 if (woperation == NULL)
10473 goto normal;
10474 }
10475 else
10476 woperation = NULL;
10477
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010479 rc = ShellExecuteW((HWND)0, woperation, wpath,
10480 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 Py_END_ALLOW_THREADS
10482
Victor Stinnereb5657a2011-09-30 01:44:27 +020010483 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010485 win32_error_object("startfile", unipath);
10486 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 }
10488 Py_INCREF(Py_None);
10489 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010490
10491normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010492 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10493 PyUnicode_FSConverter, &ofilepath,
10494 &operation))
10495 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010496 if (win32_warn_bytes_api()) {
10497 Py_DECREF(ofilepath);
10498 return NULL;
10499 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010500 filepath = PyBytes_AsString(ofilepath);
10501 Py_BEGIN_ALLOW_THREADS
10502 rc = ShellExecute((HWND)0, operation, filepath,
10503 NULL, NULL, SW_SHOWNORMAL);
10504 Py_END_ALLOW_THREADS
10505 if (rc <= (HINSTANCE)32) {
10506 PyObject *errval = win32_error("startfile", filepath);
10507 Py_DECREF(ofilepath);
10508 return errval;
10509 }
10510 Py_DECREF(ofilepath);
10511 Py_INCREF(Py_None);
10512 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010513}
10514#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010515
Martin v. Löwis438b5342002-12-27 10:16:42 +000010516#ifdef HAVE_GETLOADAVG
10517PyDoc_STRVAR(posix_getloadavg__doc__,
10518"getloadavg() -> (float, float, float)\n\n\
10519Return the number of processes in the system run queue averaged over\n\
10520the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10521was unobtainable");
10522
10523static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010524posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010525{
10526 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010527 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010528 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10529 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010530 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010531 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010532}
10533#endif
10534
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010535PyDoc_STRVAR(device_encoding__doc__,
10536"device_encoding(fd) -> str\n\n\
10537Return a string describing the encoding of the device\n\
10538if the output is a terminal; else return None.");
10539
10540static PyObject *
10541device_encoding(PyObject *self, PyObject *args)
10542{
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010544
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10546 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010547
10548 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010549}
10550
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010551#ifdef HAVE_SETRESUID
10552PyDoc_STRVAR(posix_setresuid__doc__,
10553"setresuid(ruid, euid, suid)\n\n\
10554Set the current process's real, effective, and saved user ids.");
10555
10556static PyObject*
10557posix_setresuid (PyObject *self, PyObject *args)
10558{
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010560 uid_t ruid, euid, suid;
10561 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10562 _Py_Uid_Converter, &ruid,
10563 _Py_Uid_Converter, &euid,
10564 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 return NULL;
10566 if (setresuid(ruid, euid, suid) < 0)
10567 return posix_error();
10568 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010569}
10570#endif
10571
10572#ifdef HAVE_SETRESGID
10573PyDoc_STRVAR(posix_setresgid__doc__,
10574"setresgid(rgid, egid, sgid)\n\n\
10575Set the current process's real, effective, and saved group ids.");
10576
10577static PyObject*
10578posix_setresgid (PyObject *self, PyObject *args)
10579{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010580 gid_t rgid, egid, sgid;
10581 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10582 _Py_Gid_Converter, &rgid,
10583 _Py_Gid_Converter, &egid,
10584 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010585 return NULL;
10586 if (setresgid(rgid, egid, sgid) < 0)
10587 return posix_error();
10588 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010589}
10590#endif
10591
10592#ifdef HAVE_GETRESUID
10593PyDoc_STRVAR(posix_getresuid__doc__,
10594"getresuid() -> (ruid, euid, suid)\n\n\
10595Get tuple of the current process's real, effective, and saved user ids.");
10596
10597static PyObject*
10598posix_getresuid (PyObject *self, PyObject *noargs)
10599{
Victor Stinner8c62be82010-05-06 00:08:46 +000010600 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 if (getresuid(&ruid, &euid, &suid) < 0)
10602 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010603 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10604 _PyLong_FromUid(euid),
10605 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010606}
10607#endif
10608
10609#ifdef HAVE_GETRESGID
10610PyDoc_STRVAR(posix_getresgid__doc__,
10611"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010612Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010613
10614static PyObject*
10615posix_getresgid (PyObject *self, PyObject *noargs)
10616{
Victor Stinner8c62be82010-05-06 00:08:46 +000010617 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010618 if (getresgid(&rgid, &egid, &sgid) < 0)
10619 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010620 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10621 _PyLong_FromGid(egid),
10622 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010623}
10624#endif
10625
Benjamin Peterson9428d532011-09-14 11:45:52 -040010626#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010627
Benjamin Peterson799bd802011-08-31 22:15:17 -040010628PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010629"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10630Return the value of extended attribute attribute on path.\n\
10631\n\
10632path may be either a string or an open file descriptor.\n\
10633If follow_symlinks is False, and the last element of the path is a symbolic\n\
10634 link, getxattr will examine the symbolic link itself instead of the file\n\
10635 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010636
10637static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010638posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010639{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010640 path_t path;
10641 path_t attribute;
10642 int follow_symlinks = 1;
10643 PyObject *buffer = NULL;
10644 int i;
10645 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010646
Larry Hastings9cf065c2012-06-22 16:30:09 -070010647 memset(&path, 0, sizeof(path));
10648 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010649 path.function_name = "getxattr";
10650 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010651 path.allow_fd = 1;
10652 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10653 path_converter, &path,
10654 path_converter, &attribute,
10655 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010656 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010657
Larry Hastings9cf065c2012-06-22 16:30:09 -070010658 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10659 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010660
Larry Hastings9cf065c2012-06-22 16:30:09 -070010661 for (i = 0; ; i++) {
10662 void *ptr;
10663 ssize_t result;
10664 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10665 Py_ssize_t buffer_size = buffer_sizes[i];
10666 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010667 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010668 goto exit;
10669 }
10670 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10671 if (!buffer)
10672 goto exit;
10673 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010674
Larry Hastings9cf065c2012-06-22 16:30:09 -070010675 Py_BEGIN_ALLOW_THREADS;
10676 if (path.fd >= 0)
10677 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10678 else if (follow_symlinks)
10679 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10680 else
10681 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10682 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010683
Larry Hastings9cf065c2012-06-22 16:30:09 -070010684 if (result < 0) {
10685 Py_DECREF(buffer);
10686 buffer = NULL;
10687 if (errno == ERANGE)
10688 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010689 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010690 goto exit;
10691 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010692
Larry Hastings9cf065c2012-06-22 16:30:09 -070010693 if (result != buffer_size) {
10694 /* Can only shrink. */
10695 _PyBytes_Resize(&buffer, result);
10696 }
10697 break;
10698 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010699
Larry Hastings9cf065c2012-06-22 16:30:09 -070010700exit:
10701 path_cleanup(&path);
10702 path_cleanup(&attribute);
10703 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010704}
10705
10706PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010707"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10708Set extended attribute attribute on path to value.\n\
10709path may be either a string or an open file descriptor.\n\
10710If follow_symlinks is False, and the last element of the path is a symbolic\n\
10711 link, setxattr will modify the symbolic link itself instead of the file\n\
10712 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010713
10714static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010715posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010716{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010717 path_t path;
10718 path_t attribute;
10719 Py_buffer value;
10720 int flags = 0;
10721 int follow_symlinks = 1;
10722 int result;
10723 PyObject *return_value = NULL;
10724 static char *keywords[] = {"path", "attribute", "value",
10725 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010726
Larry Hastings9cf065c2012-06-22 16:30:09 -070010727 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010728 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010729 path.allow_fd = 1;
10730 memset(&attribute, 0, sizeof(attribute));
10731 memset(&value, 0, sizeof(value));
10732 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10733 keywords,
10734 path_converter, &path,
10735 path_converter, &attribute,
10736 &value, &flags,
10737 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010738 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010739
10740 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10741 goto exit;
10742
Benjamin Peterson799bd802011-08-31 22:15:17 -040010743 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010744 if (path.fd > -1)
10745 result = fsetxattr(path.fd, attribute.narrow,
10746 value.buf, value.len, flags);
10747 else if (follow_symlinks)
10748 result = setxattr(path.narrow, attribute.narrow,
10749 value.buf, value.len, flags);
10750 else
10751 result = lsetxattr(path.narrow, attribute.narrow,
10752 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010753 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010754
Larry Hastings9cf065c2012-06-22 16:30:09 -070010755 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010756 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010757 goto exit;
10758 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010759
Larry Hastings9cf065c2012-06-22 16:30:09 -070010760 return_value = Py_None;
10761 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010762
Larry Hastings9cf065c2012-06-22 16:30:09 -070010763exit:
10764 path_cleanup(&path);
10765 path_cleanup(&attribute);
10766 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010767
Larry Hastings9cf065c2012-06-22 16:30:09 -070010768 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010769}
10770
10771PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010772"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10773Remove extended attribute attribute on path.\n\
10774path may be either a string or an open file descriptor.\n\
10775If follow_symlinks is False, and the last element of the path is a symbolic\n\
10776 link, removexattr will modify the symbolic link itself instead of the file\n\
10777 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010778
10779static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010780posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010781{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010782 path_t path;
10783 path_t attribute;
10784 int follow_symlinks = 1;
10785 int result;
10786 PyObject *return_value = NULL;
10787 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010788
Larry Hastings9cf065c2012-06-22 16:30:09 -070010789 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010790 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010791 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010792 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010793 path.allow_fd = 1;
10794 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10795 keywords,
10796 path_converter, &path,
10797 path_converter, &attribute,
10798 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010799 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010800
10801 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10802 goto exit;
10803
Benjamin Peterson799bd802011-08-31 22:15:17 -040010804 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010805 if (path.fd > -1)
10806 result = fremovexattr(path.fd, attribute.narrow);
10807 else if (follow_symlinks)
10808 result = removexattr(path.narrow, attribute.narrow);
10809 else
10810 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010811 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010812
Larry Hastings9cf065c2012-06-22 16:30:09 -070010813 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010814 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010815 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010816 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010817
Larry Hastings9cf065c2012-06-22 16:30:09 -070010818 return_value = Py_None;
10819 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010820
Larry Hastings9cf065c2012-06-22 16:30:09 -070010821exit:
10822 path_cleanup(&path);
10823 path_cleanup(&attribute);
10824
10825 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010826}
10827
10828PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010829"listxattr(path='.', *, follow_symlinks=True)\n\n\
10830Return a list of extended attributes on path.\n\
10831\n\
10832path may be either None, a string, or an open file descriptor.\n\
10833if path is None, listxattr will examine the current directory.\n\
10834If follow_symlinks is False, and the last element of the path is a symbolic\n\
10835 link, listxattr will examine the symbolic link itself instead of the file\n\
10836 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010837
10838static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010839posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010840{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010841 path_t path;
10842 int follow_symlinks = 1;
10843 Py_ssize_t i;
10844 PyObject *result = NULL;
10845 char *buffer = NULL;
10846 char *name;
10847 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010848
Larry Hastings9cf065c2012-06-22 16:30:09 -070010849 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010850 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010851 path.allow_fd = 1;
10852 path.fd = -1;
10853 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10854 path_converter, &path,
10855 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010856 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010857
Larry Hastings9cf065c2012-06-22 16:30:09 -070010858 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10859 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010860
Larry Hastings9cf065c2012-06-22 16:30:09 -070010861 name = path.narrow ? path.narrow : ".";
10862 for (i = 0; ; i++) {
10863 char *start, *trace, *end;
10864 ssize_t length;
10865 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10866 Py_ssize_t buffer_size = buffer_sizes[i];
10867 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010868 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010869 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010870 break;
10871 }
10872 buffer = PyMem_MALLOC(buffer_size);
10873 if (!buffer) {
10874 PyErr_NoMemory();
10875 break;
10876 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010877
Larry Hastings9cf065c2012-06-22 16:30:09 -070010878 Py_BEGIN_ALLOW_THREADS;
10879 if (path.fd > -1)
10880 length = flistxattr(path.fd, buffer, buffer_size);
10881 else if (follow_symlinks)
10882 length = listxattr(name, buffer, buffer_size);
10883 else
10884 length = llistxattr(name, buffer, buffer_size);
10885 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010886
Larry Hastings9cf065c2012-06-22 16:30:09 -070010887 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010888 if (errno == ERANGE) {
10889 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010890 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010891 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010892 }
Victor Stinner292c8352012-10-30 02:17:38 +010010893 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010894 break;
10895 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010896
Larry Hastings9cf065c2012-06-22 16:30:09 -070010897 result = PyList_New(0);
10898 if (!result) {
10899 goto exit;
10900 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010901
Larry Hastings9cf065c2012-06-22 16:30:09 -070010902 end = buffer + length;
10903 for (trace = start = buffer; trace != end; trace++) {
10904 if (!*trace) {
10905 int error;
10906 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10907 trace - start);
10908 if (!attribute) {
10909 Py_DECREF(result);
10910 result = NULL;
10911 goto exit;
10912 }
10913 error = PyList_Append(result, attribute);
10914 Py_DECREF(attribute);
10915 if (error) {
10916 Py_DECREF(result);
10917 result = NULL;
10918 goto exit;
10919 }
10920 start = trace + 1;
10921 }
10922 }
10923 break;
10924 }
10925exit:
10926 path_cleanup(&path);
10927 if (buffer)
10928 PyMem_FREE(buffer);
10929 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010930}
10931
Benjamin Peterson9428d532011-09-14 11:45:52 -040010932#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010933
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010934
Georg Brandl2fb477c2012-02-21 00:33:36 +010010935PyDoc_STRVAR(posix_urandom__doc__,
10936"urandom(n) -> str\n\n\
10937Return n random bytes suitable for cryptographic use.");
10938
10939static PyObject *
10940posix_urandom(PyObject *self, PyObject *args)
10941{
10942 Py_ssize_t size;
10943 PyObject *result;
10944 int ret;
10945
10946 /* Read arguments */
10947 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10948 return NULL;
10949 if (size < 0)
10950 return PyErr_Format(PyExc_ValueError,
10951 "negative argument not allowed");
10952 result = PyBytes_FromStringAndSize(NULL, size);
10953 if (result == NULL)
10954 return NULL;
10955
10956 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10957 PyBytes_GET_SIZE(result));
10958 if (ret == -1) {
10959 Py_DECREF(result);
10960 return NULL;
10961 }
10962 return result;
10963}
10964
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010965/* Terminal size querying */
10966
10967static PyTypeObject TerminalSizeType;
10968
10969PyDoc_STRVAR(TerminalSize_docstring,
10970 "A tuple of (columns, lines) for holding terminal window size");
10971
10972static PyStructSequence_Field TerminalSize_fields[] = {
10973 {"columns", "width of the terminal window in characters"},
10974 {"lines", "height of the terminal window in characters"},
10975 {NULL, NULL}
10976};
10977
10978static PyStructSequence_Desc TerminalSize_desc = {
10979 "os.terminal_size",
10980 TerminalSize_docstring,
10981 TerminalSize_fields,
10982 2,
10983};
10984
10985#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10986PyDoc_STRVAR(termsize__doc__,
10987 "Return the size of the terminal window as (columns, lines).\n" \
10988 "\n" \
10989 "The optional argument fd (default standard output) specifies\n" \
10990 "which file descriptor should be queried.\n" \
10991 "\n" \
10992 "If the file descriptor is not connected to a terminal, an OSError\n" \
10993 "is thrown.\n" \
10994 "\n" \
10995 "This function will only be defined if an implementation is\n" \
10996 "available for this system.\n" \
10997 "\n" \
10998 "shutil.get_terminal_size is the high-level function which should \n" \
10999 "normally be used, os.get_terminal_size is the low-level implementation.");
11000
11001static PyObject*
11002get_terminal_size(PyObject *self, PyObject *args)
11003{
11004 int columns, lines;
11005 PyObject *termsize;
11006
11007 int fd = fileno(stdout);
11008 /* Under some conditions stdout may not be connected and
11009 * fileno(stdout) may point to an invalid file descriptor. For example
11010 * GUI apps don't have valid standard streams by default.
11011 *
11012 * If this happens, and the optional fd argument is not present,
11013 * the ioctl below will fail returning EBADF. This is what we want.
11014 */
11015
11016 if (!PyArg_ParseTuple(args, "|i", &fd))
11017 return NULL;
11018
11019#ifdef TERMSIZE_USE_IOCTL
11020 {
11021 struct winsize w;
11022 if (ioctl(fd, TIOCGWINSZ, &w))
11023 return PyErr_SetFromErrno(PyExc_OSError);
11024 columns = w.ws_col;
11025 lines = w.ws_row;
11026 }
11027#endif /* TERMSIZE_USE_IOCTL */
11028
11029#ifdef TERMSIZE_USE_CONIO
11030 {
11031 DWORD nhandle;
11032 HANDLE handle;
11033 CONSOLE_SCREEN_BUFFER_INFO csbi;
11034 switch (fd) {
11035 case 0: nhandle = STD_INPUT_HANDLE;
11036 break;
11037 case 1: nhandle = STD_OUTPUT_HANDLE;
11038 break;
11039 case 2: nhandle = STD_ERROR_HANDLE;
11040 break;
11041 default:
11042 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11043 }
11044 handle = GetStdHandle(nhandle);
11045 if (handle == NULL)
11046 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11047 if (handle == INVALID_HANDLE_VALUE)
11048 return PyErr_SetFromWindowsErr(0);
11049
11050 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11051 return PyErr_SetFromWindowsErr(0);
11052
11053 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11054 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11055 }
11056#endif /* TERMSIZE_USE_CONIO */
11057
11058 termsize = PyStructSequence_New(&TerminalSizeType);
11059 if (termsize == NULL)
11060 return NULL;
11061 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11062 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11063 if (PyErr_Occurred()) {
11064 Py_DECREF(termsize);
11065 return NULL;
11066 }
11067 return termsize;
11068}
11069#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11070
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011071PyDoc_STRVAR(posix_cpu_count__doc__,
11072"cpu_count() -> integer\n\n\
11073Return the number of CPUs in the system, or None if this value cannot be\n\
11074established.");
11075
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011076static PyObject *
11077posix_cpu_count(PyObject *self)
11078{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011079 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011080#ifdef MS_WINDOWS
11081 SYSTEM_INFO sysinfo;
11082 GetSystemInfo(&sysinfo);
11083 ncpu = sysinfo.dwNumberOfProcessors;
11084#elif defined(__hpux)
11085 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11086#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11087 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011088#elif defined(__DragonFly__) || \
11089 defined(__OpenBSD__) || \
11090 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011091 defined(__NetBSD__) || \
11092 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011093 int mib[2];
11094 size_t len = sizeof(ncpu);
11095 mib[0] = CTL_HW;
11096 mib[1] = HW_NCPU;
11097 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11098 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011099#endif
11100 if (ncpu >= 1)
11101 return PyLong_FromLong(ncpu);
11102 else
11103 Py_RETURN_NONE;
11104}
11105
Victor Stinnerdaf45552013-08-28 00:53:59 +020011106PyDoc_STRVAR(get_inheritable__doc__,
11107 "get_inheritable(fd) -> bool\n" \
11108 "\n" \
11109 "Get the close-on-exe flag of the specified file descriptor.");
11110
11111static PyObject*
11112posix_get_inheritable(PyObject *self, PyObject *args)
11113{
11114 int fd;
11115 int inheritable;
11116
11117 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd))
11118 return NULL;
11119
11120 if (!_PyVerify_fd(fd))
11121 return posix_error();
11122
11123 inheritable = _Py_get_inheritable(fd);
11124 if (inheritable < 0)
11125 return NULL;
11126 return PyBool_FromLong(inheritable);
11127}
11128
11129PyDoc_STRVAR(set_inheritable__doc__,
11130 "set_inheritable(fd, inheritable)\n" \
11131 "\n" \
11132 "Set the inheritable flag of the specified file descriptor.");
11133
11134static PyObject*
11135posix_set_inheritable(PyObject *self, PyObject *args)
11136{
11137 int fd, inheritable;
11138
11139 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable))
11140 return NULL;
11141
11142 if (!_PyVerify_fd(fd))
11143 return posix_error();
11144
11145 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
11146 return NULL;
11147 Py_RETURN_NONE;
11148}
11149
11150
11151#ifdef MS_WINDOWS
11152PyDoc_STRVAR(get_handle_inheritable__doc__,
11153 "get_handle_inheritable(fd) -> bool\n" \
11154 "\n" \
11155 "Get the close-on-exe flag of the specified file descriptor.");
11156
11157static PyObject*
11158posix_get_handle_inheritable(PyObject *self, PyObject *args)
11159{
11160 Py_intptr_t handle;
11161 DWORD flags;
11162
11163 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle))
11164 return NULL;
11165
11166 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11167 PyErr_SetFromWindowsErr(0);
11168 return NULL;
11169 }
11170
11171 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT);
11172}
11173
11174PyDoc_STRVAR(set_handle_inheritable__doc__,
11175 "set_handle_inheritable(fd, inheritable)\n" \
11176 "\n" \
11177 "Set the inheritable flag of the specified handle.");
11178
11179static PyObject*
11180posix_set_handle_inheritable(PyObject *self, PyObject *args)
11181{
11182 int inheritable = 1;
11183 Py_intptr_t handle;
11184 DWORD flags;
11185
11186 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable",
11187 &handle, &inheritable))
11188 return NULL;
11189
11190 if (inheritable)
11191 flags = HANDLE_FLAG_INHERIT;
11192 else
11193 flags = 0;
11194 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11195 PyErr_SetFromWindowsErr(0);
11196 return NULL;
11197 }
11198 Py_RETURN_NONE;
11199}
11200#endif /* MS_WINDOWS */
11201
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011202
Larry Hastings7726ac92014-01-31 22:03:12 -080011203/*[clinic input]
11204dump buffer
11205[clinic start generated code]*/
11206
11207#ifndef OS_TTYNAME_METHODDEF
11208 #define OS_TTYNAME_METHODDEF
11209#endif /* !defined(OS_TTYNAME_METHODDEF) */
11210/*[clinic end generated code: output=5d071bbc8f49ea12 input=524ce2e021e4eba6]*/
11211
Larry Hastings31826802013-10-19 00:09:25 -070011212
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011213static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070011214
11215 OS_STAT_METHODDEF
11216 OS_ACCESS_METHODDEF
11217 OS_TTYNAME_METHODDEF
11218
Larry Hastings9cf065c2012-06-22 16:30:09 -070011219 {"chdir", (PyCFunction)posix_chdir,
11220 METH_VARARGS | METH_KEYWORDS,
11221 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011222#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011223 {"chflags", (PyCFunction)posix_chflags,
11224 METH_VARARGS | METH_KEYWORDS,
11225 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011226#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011227 {"chmod", (PyCFunction)posix_chmod,
11228 METH_VARARGS | METH_KEYWORDS,
11229 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011230#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011231 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011232#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011233#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070011234 {"chown", (PyCFunction)posix_chown,
11235 METH_VARARGS | METH_KEYWORDS,
11236 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011237#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000011238#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011239 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011240#endif /* HAVE_LCHMOD */
11241#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011242 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011243#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000011244#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011245 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011246#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011247#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011248 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011249#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000011250#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000011252#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011253#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000011254 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011255#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 {"getcwd", (PyCFunction)posix_getcwd_unicode,
11257 METH_NOARGS, posix_getcwd__doc__},
11258 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
11259 METH_NOARGS, posix_getcwdb__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011260#if defined(HAVE_LINK) || defined(MS_WINDOWS)
11261 {"link", (PyCFunction)posix_link,
11262 METH_VARARGS | METH_KEYWORDS,
11263 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011264#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011265 {"listdir", (PyCFunction)posix_listdir,
11266 METH_VARARGS | METH_KEYWORDS,
11267 posix_listdir__doc__},
11268 {"lstat", (PyCFunction)posix_lstat,
11269 METH_VARARGS | METH_KEYWORDS,
11270 posix_lstat__doc__},
11271 {"mkdir", (PyCFunction)posix_mkdir,
11272 METH_VARARGS | METH_KEYWORDS,
11273 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011274#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011275 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011276#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011277#ifdef HAVE_GETPRIORITY
11278 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11279#endif /* HAVE_GETPRIORITY */
11280#ifdef HAVE_SETPRIORITY
11281 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11282#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011283#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011284 {"readlink", (PyCFunction)posix_readlink,
11285 METH_VARARGS | METH_KEYWORDS,
11286 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011287#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011288#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011289 {"readlink", (PyCFunction)win_readlink,
11290 METH_VARARGS | METH_KEYWORDS,
11291 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011292#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011293 {"rename", (PyCFunction)posix_rename,
11294 METH_VARARGS | METH_KEYWORDS,
11295 posix_rename__doc__},
11296 {"replace", (PyCFunction)posix_replace,
11297 METH_VARARGS | METH_KEYWORDS,
11298 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011299 {"rmdir", (PyCFunction)posix_rmdir,
11300 METH_VARARGS | METH_KEYWORDS,
11301 posix_rmdir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011302 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011303#if defined(HAVE_SYMLINK)
11304 {"symlink", (PyCFunction)posix_symlink,
11305 METH_VARARGS | METH_KEYWORDS,
11306 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011307#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011308#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011309 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011310#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011311 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011312#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011314#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011315 {"unlink", (PyCFunction)posix_unlink,
11316 METH_VARARGS | METH_KEYWORDS,
11317 posix_unlink__doc__},
11318 {"remove", (PyCFunction)posix_unlink,
11319 METH_VARARGS | METH_KEYWORDS,
11320 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011321 {"utime", (PyCFunction)posix_utime,
11322 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011323#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011324 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011325#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011326 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011327#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011328 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011329 {"execve", (PyCFunction)posix_execve,
11330 METH_VARARGS | METH_KEYWORDS,
11331 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011332#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011333#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011334 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11335 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000011336#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011337#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011338 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011339#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011340#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011341 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011342#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011343#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011344#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011345 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11346 {"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 +020011347#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011348#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011349 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011350#endif
11351#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011352 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011353#endif
11354#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011355 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011356#endif
11357#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011358 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011359#endif
11360#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011361 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011362#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011363 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011364#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011365 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11366 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11367#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011368#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011369#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011370 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011371#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011372#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011373 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011374#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011375#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011376 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011377#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011378#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011379 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011380#endif /* HAVE_GETEUID */
11381#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011382 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011383#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011384#ifdef HAVE_GETGROUPLIST
11385 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11386#endif
Fred Drakec9680921999-12-13 16:37:25 +000011387#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011388 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011389#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011391#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011392 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011393#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011394#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011395 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011396#endif /* HAVE_GETPPID */
11397#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011398 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011399#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011400#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011401 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011402#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011403#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011404 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011405#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011406#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011407 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011408#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011409#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011410 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011411#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011412#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011413 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11414 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011415#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011416#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011417 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011418#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011419#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011420 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011421#endif /* HAVE_SETEUID */
11422#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011424#endif /* HAVE_SETEGID */
11425#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011426 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011427#endif /* HAVE_SETREUID */
11428#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011429 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011430#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011431#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011432 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011433#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011434#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011435 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011436#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011437#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011438 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011439#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011440#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011442#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011443#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011445#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011446#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011447 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011448#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011449#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011450 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011451#endif /* HAVE_WAIT3 */
11452#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011453 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011454#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011455#if defined(HAVE_WAITID) && !defined(__APPLE__)
11456 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11457#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011458#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011459 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011460#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011461#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011462 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011463#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011464#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011466#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011467#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011468 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011469#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011470#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011471 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011472#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011473#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011474 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011475#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011476 {"open", (PyCFunction)posix_open,\
11477 METH_VARARGS | METH_KEYWORDS,
11478 posix_open__doc__},
Benjamin Peterson932bba32014-02-11 10:16:16 -050011479 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011480 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11481 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11482 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011483 {"dup2", (PyCFunction)posix_dup2,
11484 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011485#ifdef HAVE_LOCKF
11486 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11487#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011488 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11489 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011490#ifdef HAVE_READV
11491 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11492#endif
11493#ifdef HAVE_PREAD
11494 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11495#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011496 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011497#ifdef HAVE_WRITEV
11498 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11499#endif
11500#ifdef HAVE_PWRITE
11501 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11502#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011503#ifdef HAVE_SENDFILE
11504 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11505 posix_sendfile__doc__},
11506#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011507 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011508 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011509#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011510 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011511#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011512#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011513 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011514#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011515#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011516 {"mkfifo", (PyCFunction)posix_mkfifo,
11517 METH_VARARGS | METH_KEYWORDS,
11518 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011519#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011520#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011521 {"mknod", (PyCFunction)posix_mknod,
11522 METH_VARARGS | METH_KEYWORDS,
11523 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011524#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011525#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011526 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11527 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11528 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011529#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011530#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011531 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011532#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011533#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011534 {"truncate", (PyCFunction)posix_truncate,
11535 METH_VARARGS | METH_KEYWORDS,
11536 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011537#endif
Victor Stinnerd6b17692014-09-30 12:20:05 +020011538#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011539 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11540#endif
Victor Stinnerd6b17692014-09-30 12:20:05 +020011541#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011542 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11543#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011544#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011545 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011546#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011547#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011549#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011550 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011551#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011553#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011554#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011556#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011557#ifdef HAVE_SYNC
11558 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11559#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011560#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011561 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011562#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011563#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011564#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011565 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011566#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011567#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011568 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011569#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011570#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011571 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011572#endif /* WIFSTOPPED */
11573#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011574 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011575#endif /* WIFSIGNALED */
11576#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011577 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011578#endif /* WIFEXITED */
11579#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011580 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011581#endif /* WEXITSTATUS */
11582#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011583 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011584#endif /* WTERMSIG */
11585#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011586 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011587#endif /* WSTOPSIG */
11588#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011589#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011590 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011591#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011592#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011593 {"statvfs", (PyCFunction)posix_statvfs,
11594 METH_VARARGS | METH_KEYWORDS,
11595 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011596#endif
Fred Drakec9680921999-12-13 16:37:25 +000011597#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011598 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011599#endif
11600#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011601 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011602#endif
11603#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011604 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011605#endif
11606#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011607 {"pathconf", (PyCFunction)posix_pathconf,
11608 METH_VARARGS | METH_KEYWORDS,
11609 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011610#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011611 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011612#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011613 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011614 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011615 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011616 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011617 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011618#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011619#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011620 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011621#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011622 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011623#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011624 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011625#endif
11626#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011627 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011628#endif
11629#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011630 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011631#endif
11632#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011633 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011634#endif
11635
Benjamin Peterson9428d532011-09-14 11:45:52 -040011636#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011637 {"setxattr", (PyCFunction)posix_setxattr,
11638 METH_VARARGS | METH_KEYWORDS,
11639 posix_setxattr__doc__},
11640 {"getxattr", (PyCFunction)posix_getxattr,
11641 METH_VARARGS | METH_KEYWORDS,
11642 posix_getxattr__doc__},
11643 {"removexattr", (PyCFunction)posix_removexattr,
11644 METH_VARARGS | METH_KEYWORDS,
11645 posix_removexattr__doc__},
11646 {"listxattr", (PyCFunction)posix_listxattr,
11647 METH_VARARGS | METH_KEYWORDS,
11648 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011649#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011650#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11651 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11652#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011653 {"cpu_count", (PyCFunction)posix_cpu_count,
11654 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011655 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__},
11656 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__},
11657#ifdef MS_WINDOWS
11658 {"get_handle_inheritable", posix_get_handle_inheritable,
11659 METH_VARARGS, get_handle_inheritable__doc__},
11660 {"set_handle_inheritable", posix_set_handle_inheritable,
11661 METH_VARARGS, set_handle_inheritable__doc__},
11662#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011663 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011664};
11665
11666
Brian Curtin52173d42010-12-02 18:29:18 +000011667#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011668static int
Brian Curtin52173d42010-12-02 18:29:18 +000011669enable_symlink()
11670{
11671 HANDLE tok;
11672 TOKEN_PRIVILEGES tok_priv;
11673 LUID luid;
11674 int meth_idx = 0;
11675
11676 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011677 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011678
11679 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011680 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011681
11682 tok_priv.PrivilegeCount = 1;
11683 tok_priv.Privileges[0].Luid = luid;
11684 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11685
11686 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11687 sizeof(TOKEN_PRIVILEGES),
11688 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011689 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011690
Brian Curtin3b4499c2010-12-28 14:31:47 +000011691 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11692 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011693}
11694#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11695
Barry Warsaw4a342091996-12-19 23:50:02 +000011696static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011697all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011698{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011699#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011700 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011701#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011702#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011703 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011704#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011705#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011706 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011707#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011708#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011709 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011710#endif
Fred Drakec9680921999-12-13 16:37:25 +000011711#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011712 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011713#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011714#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011715 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011716#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011717#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011718 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011719#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011720#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011721 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011722#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011723#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011724 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011725#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011726#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011727 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011728#endif
11729#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011730 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011731#endif
11732#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011733 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011734#endif
11735#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011736 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011737#endif
11738#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011739 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011740#endif
11741#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011742 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011743#endif
11744#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011745 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011746#endif
11747#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011748 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011749#endif
11750#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011751 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011752#endif
11753#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011754 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011755#endif
11756#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011757 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011758#endif
11759#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011760 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011761#endif
11762#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011763 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011764#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011765#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011766 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011767#endif
11768#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011769 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011770#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011771#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011772 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011773#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011774#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011775 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011776#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011777#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011778 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011779#endif
11780#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011781 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011782#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011783#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011784 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011785#endif
11786#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011787 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011788#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011789#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011790 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011791#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011792#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011793 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011794#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011795#ifdef O_TMPFILE
11796 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11797#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011798#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011799 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011800#endif
11801#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011802 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011803#endif
11804#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011805 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011806#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011807#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011808 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011809#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011810#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011811 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011812#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011813
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011814
Jesus Cea94363612012-06-22 18:32:07 +020011815#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011816 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011817#endif
11818#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011819 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011820#endif
11821
Tim Peters5aa91602002-01-30 05:46:57 +000011822/* MS Windows */
11823#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011824 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011825 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011826#endif
11827#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011828 /* Optimize for short life (keep in memory). */
11829 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011830 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011831#endif
11832#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011833 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011834 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011835#endif
11836#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011837 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011838 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011839#endif
11840#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011841 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011842 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011843#endif
11844
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011845/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011846#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011847 /* Send a SIGIO signal whenever input or output
11848 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011849 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011850#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011851#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011852 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011853 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011854#endif
11855#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011856 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011857 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011858#endif
11859#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011860 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011861 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011862#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011863#ifdef O_NOLINKS
11864 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011865 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011866#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011867#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011868 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011869 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011870#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011871
Victor Stinner8c62be82010-05-06 00:08:46 +000011872 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011873#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011874 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011875#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011876#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011877 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011878#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011879#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011880 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011881#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011882#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011883 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011884#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011885#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011886 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011887#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011888#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011889 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011890#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011891#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011892 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011893#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011894#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011895 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011896#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011897#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011898 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011899#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011900#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011901 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011902#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011903#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011904 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011905#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011906#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011907 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011908#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011909#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011910 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011911#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011912#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011913 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011914#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011915#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011916 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011917#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011918#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011919 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011920#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011921#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011922 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011923#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011924
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011925 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011926#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011927 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011928#endif /* ST_RDONLY */
11929#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011930 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011931#endif /* ST_NOSUID */
11932
doko@ubuntu.comca616a22013-12-08 15:23:07 +010011933 /* GNU extensions */
11934#ifdef ST_NODEV
11935 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
11936#endif /* ST_NODEV */
11937#ifdef ST_NOEXEC
11938 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
11939#endif /* ST_NOEXEC */
11940#ifdef ST_SYNCHRONOUS
11941 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
11942#endif /* ST_SYNCHRONOUS */
11943#ifdef ST_MANDLOCK
11944 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
11945#endif /* ST_MANDLOCK */
11946#ifdef ST_WRITE
11947 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
11948#endif /* ST_WRITE */
11949#ifdef ST_APPEND
11950 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
11951#endif /* ST_APPEND */
11952#ifdef ST_NOATIME
11953 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
11954#endif /* ST_NOATIME */
11955#ifdef ST_NODIRATIME
11956 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
11957#endif /* ST_NODIRATIME */
11958#ifdef ST_RELATIME
11959 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
11960#endif /* ST_RELATIME */
11961
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011962 /* FreeBSD sendfile() constants */
11963#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011964 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011965#endif
11966#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011967 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011968#endif
11969#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011970 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011971#endif
11972
Ross Lagerwall7807c352011-03-17 20:20:30 +020011973 /* constants for posix_fadvise */
11974#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011975 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011976#endif
11977#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011978 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011979#endif
11980#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011981 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011982#endif
11983#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011984 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011985#endif
11986#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011987 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011988#endif
11989#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011990 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011991#endif
11992
11993 /* constants for waitid */
11994#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011995 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11996 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
11997 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011998#endif
11999#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012000 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012001#endif
12002#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012003 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012004#endif
12005#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012006 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012007#endif
12008#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012009 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012010#endif
12011#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012012 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012013#endif
12014#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012015 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012016#endif
12017#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012018 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012019#endif
12020
12021 /* constants for lockf */
12022#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012023 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012024#endif
12025#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012026 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012027#endif
12028#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012029 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012030#endif
12031#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012032 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012033#endif
12034
Guido van Rossum246bc171999-02-01 23:54:31 +000012035#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012036 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12037 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12038 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12039 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12040 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012041#endif
12042
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012043#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012044 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12045 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12046 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012047#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012048 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012049#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012050#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012051 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012052#endif
12053#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012054 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012055#endif
12056#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012057 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012058#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012059#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012060 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012061#endif
12062#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012063 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012064#endif
12065#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012066 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012067#endif
12068#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012069 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012070#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012071#endif
12072
Benjamin Peterson9428d532011-09-14 11:45:52 -040012073#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012074 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12075 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12076 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012077#endif
12078
Victor Stinner8b905bd2011-10-25 13:34:04 +020012079#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012080 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012081#endif
12082#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012083 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012084#endif
12085#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012086 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012087#endif
12088#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012089 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012090#endif
12091#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012092 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012093#endif
12094#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012095 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012096#endif
12097#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012098 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012099#endif
12100
Victor Stinner8c62be82010-05-06 00:08:46 +000012101 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012102}
12103
12104
Tim Peters5aa91602002-01-30 05:46:57 +000012105#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000012106#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012107#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000012108
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000012109#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000012110#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012111#define MODNAME "posix"
12112#endif
12113
Martin v. Löwis1a214512008-06-11 05:26:20 +000012114static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012115 PyModuleDef_HEAD_INIT,
12116 MODNAME,
12117 posix__doc__,
12118 -1,
12119 posix_methods,
12120 NULL,
12121 NULL,
12122 NULL,
12123 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012124};
12125
12126
Larry Hastings9cf065c2012-06-22 16:30:09 -070012127static char *have_functions[] = {
12128
12129#ifdef HAVE_FACCESSAT
12130 "HAVE_FACCESSAT",
12131#endif
12132
12133#ifdef HAVE_FCHDIR
12134 "HAVE_FCHDIR",
12135#endif
12136
12137#ifdef HAVE_FCHMOD
12138 "HAVE_FCHMOD",
12139#endif
12140
12141#ifdef HAVE_FCHMODAT
12142 "HAVE_FCHMODAT",
12143#endif
12144
12145#ifdef HAVE_FCHOWN
12146 "HAVE_FCHOWN",
12147#endif
12148
Larry Hastings00964ed2013-08-12 13:49:30 -040012149#ifdef HAVE_FCHOWNAT
12150 "HAVE_FCHOWNAT",
12151#endif
12152
Larry Hastings9cf065c2012-06-22 16:30:09 -070012153#ifdef HAVE_FEXECVE
12154 "HAVE_FEXECVE",
12155#endif
12156
12157#ifdef HAVE_FDOPENDIR
12158 "HAVE_FDOPENDIR",
12159#endif
12160
Georg Brandl306336b2012-06-24 12:55:33 +020012161#ifdef HAVE_FPATHCONF
12162 "HAVE_FPATHCONF",
12163#endif
12164
Larry Hastings9cf065c2012-06-22 16:30:09 -070012165#ifdef HAVE_FSTATAT
12166 "HAVE_FSTATAT",
12167#endif
12168
12169#ifdef HAVE_FSTATVFS
12170 "HAVE_FSTATVFS",
12171#endif
12172
Georg Brandl306336b2012-06-24 12:55:33 +020012173#ifdef HAVE_FTRUNCATE
12174 "HAVE_FTRUNCATE",
12175#endif
12176
Larry Hastings9cf065c2012-06-22 16:30:09 -070012177#ifdef HAVE_FUTIMENS
12178 "HAVE_FUTIMENS",
12179#endif
12180
12181#ifdef HAVE_FUTIMES
12182 "HAVE_FUTIMES",
12183#endif
12184
12185#ifdef HAVE_FUTIMESAT
12186 "HAVE_FUTIMESAT",
12187#endif
12188
12189#ifdef HAVE_LINKAT
12190 "HAVE_LINKAT",
12191#endif
12192
12193#ifdef HAVE_LCHFLAGS
12194 "HAVE_LCHFLAGS",
12195#endif
12196
12197#ifdef HAVE_LCHMOD
12198 "HAVE_LCHMOD",
12199#endif
12200
12201#ifdef HAVE_LCHOWN
12202 "HAVE_LCHOWN",
12203#endif
12204
12205#ifdef HAVE_LSTAT
12206 "HAVE_LSTAT",
12207#endif
12208
12209#ifdef HAVE_LUTIMES
12210 "HAVE_LUTIMES",
12211#endif
12212
12213#ifdef HAVE_MKDIRAT
12214 "HAVE_MKDIRAT",
12215#endif
12216
12217#ifdef HAVE_MKFIFOAT
12218 "HAVE_MKFIFOAT",
12219#endif
12220
12221#ifdef HAVE_MKNODAT
12222 "HAVE_MKNODAT",
12223#endif
12224
12225#ifdef HAVE_OPENAT
12226 "HAVE_OPENAT",
12227#endif
12228
12229#ifdef HAVE_READLINKAT
12230 "HAVE_READLINKAT",
12231#endif
12232
12233#ifdef HAVE_RENAMEAT
12234 "HAVE_RENAMEAT",
12235#endif
12236
12237#ifdef HAVE_SYMLINKAT
12238 "HAVE_SYMLINKAT",
12239#endif
12240
12241#ifdef HAVE_UNLINKAT
12242 "HAVE_UNLINKAT",
12243#endif
12244
12245#ifdef HAVE_UTIMENSAT
12246 "HAVE_UTIMENSAT",
12247#endif
12248
12249#ifdef MS_WINDOWS
12250 "MS_WINDOWS",
12251#endif
12252
12253 NULL
12254};
12255
12256
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012257PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012258INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012259{
Victor Stinner8c62be82010-05-06 00:08:46 +000012260 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012261 PyObject *list;
12262 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012263
Brian Curtin52173d42010-12-02 18:29:18 +000012264#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012265 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012266#endif
12267
Victor Stinner8c62be82010-05-06 00:08:46 +000012268 m = PyModule_Create(&posixmodule);
12269 if (m == NULL)
12270 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012271
Victor Stinner8c62be82010-05-06 00:08:46 +000012272 /* Initialize environ dictionary */
12273 v = convertenviron();
12274 Py_XINCREF(v);
12275 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12276 return NULL;
12277 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012278
Victor Stinner8c62be82010-05-06 00:08:46 +000012279 if (all_ins(m))
12280 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012281
Victor Stinner8c62be82010-05-06 00:08:46 +000012282 if (setup_confname_tables(m))
12283 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012284
Victor Stinner8c62be82010-05-06 00:08:46 +000012285 Py_INCREF(PyExc_OSError);
12286 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012287
Guido van Rossumb3d39562000-01-31 18:41:26 +000012288#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012289 if (posix_putenv_garbage == NULL)
12290 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012291#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012292
Victor Stinner8c62be82010-05-06 00:08:46 +000012293 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012294#if defined(HAVE_WAITID) && !defined(__APPLE__)
12295 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012296 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12297 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012298#endif
12299
Christian Heimes25827622013-10-12 01:27:08 +020012300 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012301 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12302 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12303 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012304 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12305 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012306 structseq_new = StatResultType.tp_new;
12307 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012308
Christian Heimes25827622013-10-12 01:27:08 +020012309 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012310 if (PyStructSequence_InitType2(&StatVFSResultType,
12311 &statvfs_result_desc) < 0)
12312 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012313#ifdef NEED_TICKS_PER_SECOND
12314# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012315 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012316# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012317 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012318# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012319 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012320# endif
12321#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012322
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012323#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012324 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012325 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12326 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012327 SchedParamType.tp_new = sched_param_new;
12328#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012329
12330 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012331 if (PyStructSequence_InitType2(&TerminalSizeType,
12332 &TerminalSize_desc) < 0)
12333 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012334 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012335#if defined(HAVE_WAITID) && !defined(__APPLE__)
12336 Py_INCREF((PyObject*) &WaitidResultType);
12337 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12338#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012339 Py_INCREF((PyObject*) &StatResultType);
12340 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12341 Py_INCREF((PyObject*) &StatVFSResultType);
12342 PyModule_AddObject(m, "statvfs_result",
12343 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012344
12345#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012346 Py_INCREF(&SchedParamType);
12347 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012348#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012349
Larry Hastings605a62d2012-06-24 04:33:36 -070012350 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012351 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12352 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012353 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12354
12355 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012356 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12357 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012358 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12359
Thomas Wouters477c8d52006-05-27 19:21:47 +000012360#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012361 /*
12362 * Step 2 of weak-linking support on Mac OS X.
12363 *
12364 * The code below removes functions that are not available on the
12365 * currently active platform.
12366 *
12367 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012368 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012369 * OSX 10.4.
12370 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012371#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012372 if (fstatvfs == NULL) {
12373 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12374 return NULL;
12375 }
12376 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012377#endif /* HAVE_FSTATVFS */
12378
12379#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012380 if (statvfs == NULL) {
12381 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12382 return NULL;
12383 }
12384 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012385#endif /* HAVE_STATVFS */
12386
12387# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012388 if (lchown == NULL) {
12389 if (PyObject_DelAttrString(m, "lchown") == -1) {
12390 return NULL;
12391 }
12392 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012393#endif /* HAVE_LCHOWN */
12394
12395
12396#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012397
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012398 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012399 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12400
Larry Hastings6fe20b32012-04-19 15:07:49 -070012401 billion = PyLong_FromLong(1000000000);
12402 if (!billion)
12403 return NULL;
12404
Larry Hastings9cf065c2012-06-22 16:30:09 -070012405 /* suppress "function not used" warnings */
12406 {
12407 int ignored;
12408 fd_specified("", -1);
12409 follow_symlinks_specified("", 1);
12410 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12411 dir_fd_converter(Py_None, &ignored);
12412 dir_fd_unavailable(Py_None, &ignored);
12413 }
12414
12415 /*
12416 * provide list of locally available functions
12417 * so os.py can populate support_* lists
12418 */
12419 list = PyList_New(0);
12420 if (!list)
12421 return NULL;
12422 for (trace = have_functions; *trace; trace++) {
12423 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12424 if (!unicode)
12425 return NULL;
12426 if (PyList_Append(list, unicode))
12427 return NULL;
12428 Py_DECREF(unicode);
12429 }
12430 PyModule_AddObject(m, "_have_functions", list);
12431
12432 initialized = 1;
12433
Victor Stinner8c62be82010-05-06 00:08:46 +000012434 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000012435}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012436
12437#ifdef __cplusplus
12438}
12439#endif