blob: e5384379415433856d95ebd13e6cea5848d18e01 [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 Stinner8c62be82010-05-06 00:08:46 +00003421 char buf[1026];
3422 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003423
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003424#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003425 if (!use_bytes) {
3426 wchar_t wbuf[1026];
3427 wchar_t *wbuf2 = wbuf;
3428 PyObject *resobj;
3429 DWORD len;
3430 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003431 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003432 /* If the buffer is large enough, len does not include the
3433 terminating \0. If the buffer is too small, len includes
3434 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003435 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003436 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003437 if (wbuf2)
3438 len = GetCurrentDirectoryW(len, wbuf2);
3439 }
3440 Py_END_ALLOW_THREADS
3441 if (!wbuf2) {
3442 PyErr_NoMemory();
3443 return NULL;
3444 }
3445 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003446 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003447 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003448 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003449 }
3450 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003451 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003452 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003453 return resobj;
3454 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003455
3456 if (win32_warn_bytes_api())
3457 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003458#endif
3459
Victor Stinner8c62be82010-05-06 00:08:46 +00003460 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003461 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003462 Py_END_ALLOW_THREADS
3463 if (res == NULL)
3464 return posix_error();
3465 if (use_bytes)
3466 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003467 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003468}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003469
3470PyDoc_STRVAR(posix_getcwd__doc__,
3471"getcwd() -> path\n\n\
3472Return a unicode string representing the current working directory.");
3473
3474static PyObject *
3475posix_getcwd_unicode(PyObject *self)
3476{
3477 return posix_getcwd(0);
3478}
3479
3480PyDoc_STRVAR(posix_getcwdb__doc__,
3481"getcwdb() -> path\n\n\
3482Return a bytes string representing the current working directory.");
3483
3484static PyObject *
3485posix_getcwd_bytes(PyObject *self)
3486{
3487 return posix_getcwd(1);
3488}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003489
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3491#define HAVE_LINK 1
3492#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003493
Guido van Rossumb6775db1994-08-01 11:34:53 +00003494#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003495PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3497Create a hard link to a file.\n\
3498\n\
3499If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3500 descriptor open to a directory, and the respective path string (src or dst)\n\
3501 should be relative; the path will then be relative to that directory.\n\
3502If follow_symlinks is False, and the last element of src is a symbolic\n\
3503 link, link will create a link to the symbolic link itself instead of the\n\
3504 file the link points to.\n\
3505src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3506 platform. If they are unavailable, using them will raise a\n\
3507 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003508
Barry Warsaw53699e91996-12-10 23:23:01 +00003509static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003511{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003512 path_t src, dst;
3513 int src_dir_fd = DEFAULT_DIR_FD;
3514 int dst_dir_fd = DEFAULT_DIR_FD;
3515 int follow_symlinks = 1;
3516 PyObject *return_value = NULL;
3517 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3518 "follow_symlinks", NULL};
3519#ifdef MS_WINDOWS
3520 BOOL result;
3521#else
3522 int result;
3523#endif
3524
3525 memset(&src, 0, sizeof(src));
3526 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003527 src.function_name = "link";
3528 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003529 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3530 path_converter, &src,
3531 path_converter, &dst,
3532 dir_fd_converter, &src_dir_fd,
3533 dir_fd_converter, &dst_dir_fd,
3534 &follow_symlinks))
3535 return NULL;
3536
3537#ifndef HAVE_LINKAT
3538 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3539 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3540 goto exit;
3541 }
3542#endif
3543
3544 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3545 PyErr_SetString(PyExc_NotImplementedError,
3546 "link: src and dst must be the same type");
3547 goto exit;
3548 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003549
Brian Curtin1b9df392010-11-24 20:24:31 +00003550#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003551 Py_BEGIN_ALLOW_THREADS
3552 if (src.wide)
3553 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3554 else
3555 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3556 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003557
Larry Hastings9cf065c2012-06-22 16:30:09 -07003558 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08003559 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003561 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562#else
3563 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003564#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003565 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3566 (dst_dir_fd != DEFAULT_DIR_FD) ||
3567 (!follow_symlinks))
3568 result = linkat(src_dir_fd, src.narrow,
3569 dst_dir_fd, dst.narrow,
3570 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3571 else
3572#endif
3573 result = link(src.narrow, dst.narrow);
3574 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003575
Larry Hastings9cf065c2012-06-22 16:30:09 -07003576 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08003577 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003579 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580#endif
3581
3582 return_value = Py_None;
3583 Py_INCREF(Py_None);
3584
3585exit:
3586 path_cleanup(&src);
3587 path_cleanup(&dst);
3588 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003589}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003590#endif
3591
Brian Curtin1b9df392010-11-24 20:24:31 +00003592
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003593
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003594PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003595"listdir(path='.') -> list_of_filenames\n\n\
3596Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003597The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598entries '.' and '..' even if they are present in the directory.\n\
3599\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003600path can be specified as either str or bytes. If path is bytes,\n\
3601 the filenames returned will also be bytes; in all other circumstances\n\
3602 the filenames returned will be str.\n\
3603On some platforms, path may also be specified as an open file descriptor;\n\
3604 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003605 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003606
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003607#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003608static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003609_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003610{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003611 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003612 PyObject *v;
3613 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3614 BOOL result;
3615 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003616 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003617 char *bufptr = namebuf;
3618 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003619 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003620 PyObject *po = NULL;
3621 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003622
Gregory P. Smith40a21602013-03-20 20:52:50 -07003623 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003624 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003626
Gregory P. Smith40a21602013-03-20 20:52:50 -07003627 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003628 po_wchars = L".";
3629 len = 1;
3630 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003631 po_wchars = path->wide;
3632 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003633 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003635 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003636 if (!wnamebuf) {
3637 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003638 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003639 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003640 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003641 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003642 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003643 if (wch != SEP && wch != ALTSEP && wch != L':')
3644 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 wcscpy(wnamebuf + len, L"*.*");
3646 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003647 if ((list = PyList_New(0)) == NULL) {
3648 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003649 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003650 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003652 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003653 if (hFindFile == INVALID_HANDLE_VALUE) {
3654 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003655 if (error == ERROR_FILE_NOT_FOUND)
3656 goto exit;
3657 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003658 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003659 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003660 }
3661 do {
3662 /* Skip over . and .. */
3663 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3664 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003665 v = PyUnicode_FromWideChar(wFileData.cFileName,
3666 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003667 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003668 Py_DECREF(list);
3669 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003670 break;
3671 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003672 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003673 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003674 Py_DECREF(list);
3675 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003676 break;
3677 }
3678 Py_DECREF(v);
3679 }
3680 Py_BEGIN_ALLOW_THREADS
3681 result = FindNextFileW(hFindFile, &wFileData);
3682 Py_END_ALLOW_THREADS
3683 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3684 it got to the end of the directory. */
3685 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003686 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003687 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003688 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003689 }
3690 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003691
Larry Hastings9cf065c2012-06-22 16:30:09 -07003692 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003693 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003694 strcpy(namebuf, path->narrow);
3695 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 if (len > 0) {
3697 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003698 if (ch != '\\' && ch != '/' && ch != ':')
3699 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 strcpy(namebuf + len, "*.*");
3701 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003702
Larry Hastings9cf065c2012-06-22 16:30:09 -07003703 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003704 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003705
Antoine Pitroub73caab2010-08-09 23:39:31 +00003706 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003707 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003708 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 if (hFindFile == INVALID_HANDLE_VALUE) {
3710 int error = GetLastError();
3711 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003712 goto exit;
3713 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003714 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003715 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003716 }
3717 do {
3718 /* Skip over . and .. */
3719 if (strcmp(FileData.cFileName, ".") != 0 &&
3720 strcmp(FileData.cFileName, "..") != 0) {
3721 v = PyBytes_FromString(FileData.cFileName);
3722 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003723 Py_DECREF(list);
3724 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003725 break;
3726 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003727 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003728 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003729 Py_DECREF(list);
3730 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003731 break;
3732 }
3733 Py_DECREF(v);
3734 }
3735 Py_BEGIN_ALLOW_THREADS
3736 result = FindNextFile(hFindFile, &FileData);
3737 Py_END_ALLOW_THREADS
3738 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3739 it got to the end of the directory. */
3740 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003741 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003742 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003743 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003744 }
3745 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003746
Larry Hastings9cf065c2012-06-22 16:30:09 -07003747exit:
3748 if (hFindFile != INVALID_HANDLE_VALUE) {
3749 if (FindClose(hFindFile) == FALSE) {
3750 if (list != NULL) {
3751 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003752 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003753 }
3754 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003755 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003756 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003757
Larry Hastings9cf065c2012-06-22 16:30:09 -07003758 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003759} /* end of _listdir_windows_no_opendir */
3760
3761#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3762
3763static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003764_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003765{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003766 PyObject *v;
3767 DIR *dirp = NULL;
3768 struct dirent *ep;
3769 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003770#ifdef HAVE_FDOPENDIR
3771 int fd = -1;
3772#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003773
Victor Stinner8c62be82010-05-06 00:08:46 +00003774 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003775#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003776 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003777 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003778 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003779 if (fd == -1)
3780 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003781
Larry Hastingsfdaea062012-06-25 04:42:23 -07003782 return_str = 1;
3783
Larry Hastings9cf065c2012-06-22 16:30:09 -07003784 Py_BEGIN_ALLOW_THREADS
3785 dirp = fdopendir(fd);
3786 Py_END_ALLOW_THREADS
3787 }
3788 else
3789#endif
3790 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003791 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003792 if (path->narrow) {
3793 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003794 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003795 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003796 }
3797 else {
3798 name = ".";
3799 return_str = 1;
3800 }
3801
Larry Hastings9cf065c2012-06-22 16:30:09 -07003802 Py_BEGIN_ALLOW_THREADS
3803 dirp = opendir(name);
3804 Py_END_ALLOW_THREADS
3805 }
3806
3807 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003808 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003809#ifdef HAVE_FDOPENDIR
3810 if (fd != -1) {
3811 Py_BEGIN_ALLOW_THREADS
3812 close(fd);
3813 Py_END_ALLOW_THREADS
3814 }
3815#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003816 goto exit;
3817 }
3818 if ((list = PyList_New(0)) == NULL) {
3819 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003820 }
3821 for (;;) {
3822 errno = 0;
3823 Py_BEGIN_ALLOW_THREADS
3824 ep = readdir(dirp);
3825 Py_END_ALLOW_THREADS
3826 if (ep == NULL) {
3827 if (errno == 0) {
3828 break;
3829 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003830 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003831 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003832 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003833 }
3834 }
3835 if (ep->d_name[0] == '.' &&
3836 (NAMLEN(ep) == 1 ||
3837 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3838 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003839 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003840 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3841 else
3842 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003843 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003844 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003845 break;
3846 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003847 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003848 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003849 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003850 break;
3851 }
3852 Py_DECREF(v);
3853 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003854
Larry Hastings9cf065c2012-06-22 16:30:09 -07003855exit:
3856 if (dirp != NULL) {
3857 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003858#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003859 if (fd > -1)
3860 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003861#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003862 closedir(dirp);
3863 Py_END_ALLOW_THREADS
3864 }
3865
Larry Hastings9cf065c2012-06-22 16:30:09 -07003866 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003867} /* end of _posix_listdir */
3868#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003869
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003870static PyObject *
3871posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3872{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003873 path_t path;
3874 PyObject *list = NULL;
3875 static char *keywords[] = {"path", NULL};
3876 PyObject *return_value;
3877
3878 memset(&path, 0, sizeof(path));
3879 path.function_name = "listdir";
3880 path.nullable = 1;
3881#ifdef HAVE_FDOPENDIR
3882 path.allow_fd = 1;
3883 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003884#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003885
3886 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3887 path_converter, &path)) {
3888 return NULL;
3889 }
3890
3891#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3892 return_value = _listdir_windows_no_opendir(&path, list);
3893#else
3894 return_value = _posix_listdir(&path, list);
3895#endif
3896 path_cleanup(&path);
3897 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003898}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003899
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003900#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003901/* A helper function for abspath on win32 */
3902static PyObject *
3903posix__getfullpathname(PyObject *self, PyObject *args)
3904{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003905 const char *path;
Victor Stinner75875072013-11-24 19:23:25 +01003906 char outbuf[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00003907 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003908 PyObject *po;
3909
3910 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3911 {
3912 wchar_t *wpath;
Victor Stinner75875072013-11-24 19:23:25 +01003913 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003914 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003915 DWORD result;
3916 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003917
3918 wpath = PyUnicode_AsUnicode(po);
3919 if (wpath == NULL)
3920 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003921 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003922 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003923 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003924 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003925 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003926 if (!woutbufp)
3927 return PyErr_NoMemory();
3928 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3929 }
3930 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003931 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003932 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003933 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003934 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003935 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003936 return v;
3937 }
3938 /* Drop the argument parsing error as narrow strings
3939 are also valid. */
3940 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003941
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003942 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3943 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003944 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003945 if (win32_warn_bytes_api())
3946 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003947 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003948 outbuf, &temp)) {
3949 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003950 return NULL;
3951 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3953 return PyUnicode_Decode(outbuf, strlen(outbuf),
3954 Py_FileSystemDefaultEncoding, NULL);
3955 }
3956 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003957} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003958
Brian Curtind25aef52011-06-13 15:16:04 -05003959
Brian Curtinf5e76d02010-11-24 13:14:05 +00003960
Brian Curtind40e6f72010-07-08 21:39:08 +00003961/* A helper function for samepath on windows */
3962static PyObject *
3963posix__getfinalpathname(PyObject *self, PyObject *args)
3964{
3965 HANDLE hFile;
3966 int buf_size;
3967 wchar_t *target_path;
3968 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003969 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003970 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003971
Victor Stinnereb5657a2011-09-30 01:44:27 +02003972 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003973 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003974 path = PyUnicode_AsUnicode(po);
3975 if (path == NULL)
3976 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003977
3978 if(!check_GetFinalPathNameByHandle()) {
3979 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3980 NotImplementedError. */
3981 return PyErr_Format(PyExc_NotImplementedError,
3982 "GetFinalPathNameByHandle not available on this platform");
3983 }
3984
3985 hFile = CreateFileW(
3986 path,
3987 0, /* desired access */
3988 0, /* share mode */
3989 NULL, /* security attributes */
3990 OPEN_EXISTING,
3991 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3992 FILE_FLAG_BACKUP_SEMANTICS,
3993 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003994
Victor Stinnereb5657a2011-09-30 01:44:27 +02003995 if(hFile == INVALID_HANDLE_VALUE)
3996 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003997
3998 /* We have a good handle to the target, use it to determine the
3999 target path name. */
4000 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
4001
4002 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02004003 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00004004
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004005 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00004006 if(!target_path)
4007 return PyErr_NoMemory();
4008
4009 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
4010 buf_size, VOLUME_NAME_DOS);
4011 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02004012 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00004013
4014 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02004015 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00004016
4017 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004018 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02004019 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00004020 return result;
4021
4022} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00004023
Brian Curtin95d028f2011-06-09 09:10:38 -05004024PyDoc_STRVAR(posix__isdir__doc__,
4025"Return true if the pathname refers to an existing directory.");
4026
Brian Curtin9c669cc2011-06-08 18:17:18 -05004027static PyObject *
4028posix__isdir(PyObject *self, PyObject *args)
4029{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004030 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004031 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004032 DWORD attributes;
4033
4034 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02004035 wchar_t *wpath = PyUnicode_AsUnicode(po);
4036 if (wpath == NULL)
4037 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004038
4039 attributes = GetFileAttributesW(wpath);
4040 if (attributes == INVALID_FILE_ATTRIBUTES)
4041 Py_RETURN_FALSE;
4042 goto check;
4043 }
4044 /* Drop the argument parsing error as narrow strings
4045 are also valid. */
4046 PyErr_Clear();
4047
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004048 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05004049 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01004050 if (win32_warn_bytes_api())
4051 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05004052 attributes = GetFileAttributesA(path);
4053 if (attributes == INVALID_FILE_ATTRIBUTES)
4054 Py_RETURN_FALSE;
4055
4056check:
4057 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4058 Py_RETURN_TRUE;
4059 else
4060 Py_RETURN_FALSE;
4061}
Tim Golden6b528062013-08-01 12:44:00 +01004062
4063PyDoc_STRVAR(posix__getvolumepathname__doc__,
4064"Return volume mount point of the specified path.");
4065
4066/* A helper function for ismount on windows */
4067static PyObject *
4068posix__getvolumepathname(PyObject *self, PyObject *args)
4069{
4070 PyObject *po, *result;
4071 wchar_t *path, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004072 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004073 BOOL ret;
4074
4075 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po))
4076 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004077 path = PyUnicode_AsUnicodeAndSize(po, &buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004078 if (path == NULL)
4079 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004080 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01004081
4082 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01004083 buflen = Py_MAX(buflen, MAX_PATH);
4084
4085 if (buflen > DWORD_MAX) {
4086 PyErr_SetString(PyExc_OverflowError, "path too long");
4087 return NULL;
4088 }
4089
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004090 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004091 if (mountpath == NULL)
4092 return PyErr_NoMemory();
4093
4094 Py_BEGIN_ALLOW_THREADS
Christian Heimes85ba92a2013-11-18 10:30:42 +01004095 ret = GetVolumePathNameW(path, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004096 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004097 Py_END_ALLOW_THREADS
4098
4099 if (!ret) {
4100 result = win32_error_object("_getvolumepathname", po);
4101 goto exit;
4102 }
4103 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4104
4105exit:
4106 PyMem_Free(mountpath);
4107 return result;
4108}
4109/* end of posix__getvolumepathname */
4110
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004111#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004113PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004114"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4115Create a directory.\n\
4116\n\
4117If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4118 and path should be relative; path will then be relative to that directory.\n\
4119dir_fd may not be implemented on your platform.\n\
4120 If it is unavailable, using it will raise a NotImplementedError.\n\
4121\n\
4122The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004123
Barry Warsaw53699e91996-12-10 23:23:01 +00004124static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004125posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004126{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004127 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004128 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004129 int dir_fd = DEFAULT_DIR_FD;
4130 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
4131 PyObject *return_value = NULL;
4132 int result;
4133
4134 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004135 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004136 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4137 path_converter, &path, &mode,
4138#ifdef HAVE_MKDIRAT
4139 dir_fd_converter, &dir_fd
4140#else
4141 dir_fd_unavailable, &dir_fd
4142#endif
4143 ))
4144 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004145
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004146#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004147 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004148 if (path.wide)
4149 result = CreateDirectoryW(path.wide, NULL);
4150 else
4151 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004152 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004153
Larry Hastings9cf065c2012-06-22 16:30:09 -07004154 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004155 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004156 goto exit;
4157 }
4158#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004159 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004160#if HAVE_MKDIRAT
4161 if (dir_fd != DEFAULT_DIR_FD)
4162 result = mkdirat(dir_fd, path.narrow, mode);
4163 else
4164#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004165#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004166 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004167#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004168 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004169#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004170 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004171 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01004172 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004173 goto exit;
4174 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004175#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004176 return_value = Py_None;
4177 Py_INCREF(Py_None);
4178exit:
4179 path_cleanup(&path);
4180 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004181}
4182
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004183
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004184/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4185#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004186#include <sys/resource.h>
4187#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004188
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004189
4190#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004191PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004192"nice(inc) -> new_priority\n\n\
4193Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004194
Barry Warsaw53699e91996-12-10 23:23:01 +00004195static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004196posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004197{
Victor Stinner8c62be82010-05-06 00:08:46 +00004198 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004199
Victor Stinner8c62be82010-05-06 00:08:46 +00004200 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4201 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004202
Victor Stinner8c62be82010-05-06 00:08:46 +00004203 /* There are two flavours of 'nice': one that returns the new
4204 priority (as required by almost all standards out there) and the
4205 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4206 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004207
Victor Stinner8c62be82010-05-06 00:08:46 +00004208 If we are of the nice family that returns the new priority, we
4209 need to clear errno before the call, and check if errno is filled
4210 before calling posix_error() on a returnvalue of -1, because the
4211 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004212
Victor Stinner8c62be82010-05-06 00:08:46 +00004213 errno = 0;
4214 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004215#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004216 if (value == 0)
4217 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004218#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004219 if (value == -1 && errno != 0)
4220 /* either nice() or getpriority() returned an error */
4221 return posix_error();
4222 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004223}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004224#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004225
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004226
4227#ifdef HAVE_GETPRIORITY
4228PyDoc_STRVAR(posix_getpriority__doc__,
4229"getpriority(which, who) -> current_priority\n\n\
4230Get program scheduling priority.");
4231
4232static PyObject *
4233posix_getpriority(PyObject *self, PyObject *args)
4234{
4235 int which, who, retval;
4236
4237 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4238 return NULL;
4239 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004240 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004241 if (errno != 0)
4242 return posix_error();
4243 return PyLong_FromLong((long)retval);
4244}
4245#endif /* HAVE_GETPRIORITY */
4246
4247
4248#ifdef HAVE_SETPRIORITY
4249PyDoc_STRVAR(posix_setpriority__doc__,
4250"setpriority(which, who, prio) -> None\n\n\
4251Set program scheduling priority.");
4252
4253static PyObject *
4254posix_setpriority(PyObject *self, PyObject *args)
4255{
4256 int which, who, prio, retval;
4257
4258 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4259 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004260 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004261 if (retval == -1)
4262 return posix_error();
4263 Py_RETURN_NONE;
4264}
4265#endif /* HAVE_SETPRIORITY */
4266
4267
Barry Warsaw53699e91996-12-10 23:23:01 +00004268static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004269internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004270{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004271 char *function_name = is_replace ? "replace" : "rename";
4272 path_t src;
4273 path_t dst;
4274 int src_dir_fd = DEFAULT_DIR_FD;
4275 int dst_dir_fd = DEFAULT_DIR_FD;
4276 int dir_fd_specified;
4277 PyObject *return_value = NULL;
4278 char format[24];
4279 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4280
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004281#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004282 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004283 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004284#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004285 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004286#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004287
4288 memset(&src, 0, sizeof(src));
4289 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01004290 src.function_name = function_name;
4291 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004292 strcpy(format, "O&O&|$O&O&:");
4293 strcat(format, function_name);
4294 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4295 path_converter, &src,
4296 path_converter, &dst,
4297 dir_fd_converter, &src_dir_fd,
4298 dir_fd_converter, &dst_dir_fd))
4299 return NULL;
4300
4301 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4302 (dst_dir_fd != DEFAULT_DIR_FD);
4303#ifndef HAVE_RENAMEAT
4304 if (dir_fd_specified) {
4305 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4306 goto exit;
4307 }
4308#endif
4309
4310 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4311 PyErr_Format(PyExc_ValueError,
4312 "%s: src and dst must be the same type", function_name);
4313 goto exit;
4314 }
4315
4316#ifdef MS_WINDOWS
4317 Py_BEGIN_ALLOW_THREADS
4318 if (src.wide)
4319 result = MoveFileExW(src.wide, dst.wide, flags);
4320 else
4321 result = MoveFileExA(src.narrow, dst.narrow, flags);
4322 Py_END_ALLOW_THREADS
4323
4324 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08004325 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004326 goto exit;
4327 }
4328
4329#else
4330 Py_BEGIN_ALLOW_THREADS
4331#ifdef HAVE_RENAMEAT
4332 if (dir_fd_specified)
4333 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4334 else
4335#endif
4336 result = rename(src.narrow, dst.narrow);
4337 Py_END_ALLOW_THREADS
4338
4339 if (result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08004340 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004341 goto exit;
4342 }
4343#endif
4344
4345 Py_INCREF(Py_None);
4346 return_value = Py_None;
4347exit:
4348 path_cleanup(&src);
4349 path_cleanup(&dst);
4350 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004351}
4352
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004353PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004354"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4355Rename a file or directory.\n\
4356\n\
4357If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4358 descriptor open to a directory, and the respective path string (src or dst)\n\
4359 should be relative; the path will then be relative to that directory.\n\
4360src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4361 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004362
4363static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004364posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004365{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004366 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004367}
4368
4369PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004370"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4371Rename a file or directory, overwriting the destination.\n\
4372\n\
4373If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4374 descriptor open to a directory, and the respective path string (src or dst)\n\
4375 should be relative; the path will then be relative to that directory.\n\
4376src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4377 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004378
4379static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004380posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004381{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004382 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004383}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004384
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004385PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004386"rmdir(path, *, dir_fd=None)\n\n\
4387Remove a directory.\n\
4388\n\
4389If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4390 and path should be relative; path will then be relative to that directory.\n\
4391dir_fd may not be implemented on your platform.\n\
4392 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004393
Barry Warsaw53699e91996-12-10 23:23:01 +00004394static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004395posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004396{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004397 path_t path;
4398 int dir_fd = DEFAULT_DIR_FD;
4399 static char *keywords[] = {"path", "dir_fd", NULL};
4400 int result;
4401 PyObject *return_value = NULL;
4402
4403 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004404 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004405 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4406 path_converter, &path,
4407#ifdef HAVE_UNLINKAT
4408 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004409#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004410 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004411#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004412 ))
4413 return NULL;
4414
4415 Py_BEGIN_ALLOW_THREADS
4416#ifdef MS_WINDOWS
4417 if (path.wide)
4418 result = RemoveDirectoryW(path.wide);
4419 else
4420 result = RemoveDirectoryA(path.narrow);
4421 result = !result; /* Windows, success=1, UNIX, success=0 */
4422#else
4423#ifdef HAVE_UNLINKAT
4424 if (dir_fd != DEFAULT_DIR_FD)
4425 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4426 else
4427#endif
4428 result = rmdir(path.narrow);
4429#endif
4430 Py_END_ALLOW_THREADS
4431
4432 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004433 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004434 goto exit;
4435 }
4436
4437 return_value = Py_None;
4438 Py_INCREF(Py_None);
4439
4440exit:
4441 path_cleanup(&path);
4442 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004443}
4444
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004445
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004446#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004447PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004448"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004449Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004450
Barry Warsaw53699e91996-12-10 23:23:01 +00004451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004452posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004453{
Victor Stinner8c62be82010-05-06 00:08:46 +00004454 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004455#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004456 wchar_t *command;
4457 if (!PyArg_ParseTuple(args, "u:system", &command))
4458 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004459
Victor Stinner8c62be82010-05-06 00:08:46 +00004460 Py_BEGIN_ALLOW_THREADS
4461 sts = _wsystem(command);
4462 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004463#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004464 PyObject *command_obj;
4465 char *command;
4466 if (!PyArg_ParseTuple(args, "O&:system",
4467 PyUnicode_FSConverter, &command_obj))
4468 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004469
Victor Stinner8c62be82010-05-06 00:08:46 +00004470 command = PyBytes_AsString(command_obj);
4471 Py_BEGIN_ALLOW_THREADS
4472 sts = system(command);
4473 Py_END_ALLOW_THREADS
4474 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004475#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004476 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004477}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004478#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004479
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004480
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004481PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004482"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004483Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004484
Barry Warsaw53699e91996-12-10 23:23:01 +00004485static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004486posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004487{
Victor Stinner8c62be82010-05-06 00:08:46 +00004488 int i;
4489 if (!PyArg_ParseTuple(args, "i:umask", &i))
4490 return NULL;
4491 i = (int)umask(i);
4492 if (i < 0)
4493 return posix_error();
4494 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004495}
4496
Brian Curtind40e6f72010-07-08 21:39:08 +00004497#ifdef MS_WINDOWS
4498
4499/* override the default DeleteFileW behavior so that directory
4500symlinks can be removed with this function, the same as with
4501Unix symlinks */
4502BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4503{
4504 WIN32_FILE_ATTRIBUTE_DATA info;
4505 WIN32_FIND_DATAW find_data;
4506 HANDLE find_data_handle;
4507 int is_directory = 0;
4508 int is_link = 0;
4509
4510 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4511 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004512
Brian Curtind40e6f72010-07-08 21:39:08 +00004513 /* Get WIN32_FIND_DATA structure for the path to determine if
4514 it is a symlink */
4515 if(is_directory &&
4516 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4517 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4518
4519 if(find_data_handle != INVALID_HANDLE_VALUE) {
4520 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4521 FindClose(find_data_handle);
4522 }
4523 }
4524 }
4525
4526 if (is_directory && is_link)
4527 return RemoveDirectoryW(lpFileName);
4528
4529 return DeleteFileW(lpFileName);
4530}
4531#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004532
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004533PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004534"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004535Remove a file (same as remove()).\n\
4536\n\
4537If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4538 and path should be relative; path will then be relative to that directory.\n\
4539dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004540 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004541
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004542PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004543"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004544Remove a file (same as unlink()).\n\
4545\n\
4546If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4547 and path should be relative; path will then be relative to that directory.\n\
4548dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004549 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004550
Barry Warsaw53699e91996-12-10 23:23:01 +00004551static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004552posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004553{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004554 path_t path;
4555 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004556 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004557 int result;
4558 PyObject *return_value = NULL;
4559
4560 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004561 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004562 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004563 path_converter, &path,
4564#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004565 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004566#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004567 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004568#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004569 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004570 return NULL;
4571
4572 Py_BEGIN_ALLOW_THREADS
4573#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004574 if (path.wide)
4575 result = Py_DeleteFileW(path.wide);
4576 else
4577 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004578 result = !result; /* Windows, success=1, UNIX, success=0 */
4579#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004580#ifdef HAVE_UNLINKAT
4581 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004582 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004583 else
4584#endif /* HAVE_UNLINKAT */
4585 result = unlink(path.narrow);
4586#endif
4587 Py_END_ALLOW_THREADS
4588
4589 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004590 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004591 goto exit;
4592 }
4593
4594 return_value = Py_None;
4595 Py_INCREF(Py_None);
4596
4597exit:
4598 path_cleanup(&path);
4599 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004600}
4601
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004602
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004603PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004604"uname() -> uname_result\n\n\
4605Return an object identifying the current operating system.\n\
4606The object behaves like a named tuple with the following fields:\n\
4607 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004608
Larry Hastings605a62d2012-06-24 04:33:36 -07004609static PyStructSequence_Field uname_result_fields[] = {
4610 {"sysname", "operating system name"},
4611 {"nodename", "name of machine on network (implementation-defined)"},
4612 {"release", "operating system release"},
4613 {"version", "operating system version"},
4614 {"machine", "hardware identifier"},
4615 {NULL}
4616};
4617
4618PyDoc_STRVAR(uname_result__doc__,
4619"uname_result: Result from os.uname().\n\n\
4620This object may be accessed either as a tuple of\n\
4621 (sysname, nodename, release, version, machine),\n\
4622or via the attributes sysname, nodename, release, version, and machine.\n\
4623\n\
4624See os.uname for more information.");
4625
4626static PyStructSequence_Desc uname_result_desc = {
4627 "uname_result", /* name */
4628 uname_result__doc__, /* doc */
4629 uname_result_fields,
4630 5
4631};
4632
4633static PyTypeObject UnameResultType;
4634
4635
4636#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004637static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004638posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004639{
Victor Stinner8c62be82010-05-06 00:08:46 +00004640 struct utsname u;
4641 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004642 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004643
Victor Stinner8c62be82010-05-06 00:08:46 +00004644 Py_BEGIN_ALLOW_THREADS
4645 res = uname(&u);
4646 Py_END_ALLOW_THREADS
4647 if (res < 0)
4648 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004649
4650 value = PyStructSequence_New(&UnameResultType);
4651 if (value == NULL)
4652 return NULL;
4653
4654#define SET(i, field) \
4655 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004656 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004657 if (!o) { \
4658 Py_DECREF(value); \
4659 return NULL; \
4660 } \
4661 PyStructSequence_SET_ITEM(value, i, o); \
4662 } \
4663
4664 SET(0, u.sysname);
4665 SET(1, u.nodename);
4666 SET(2, u.release);
4667 SET(3, u.version);
4668 SET(4, u.machine);
4669
4670#undef SET
4671
4672 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004673}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004674#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004675
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004676
Larry Hastings9cf065c2012-06-22 16:30:09 -07004677PyDoc_STRVAR(posix_utime__doc__,
4678"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4679Set the access and modified time of path.\n\
4680\n\
4681path may always be specified as a string.\n\
4682On some platforms, path may also be specified as an open file descriptor.\n\
4683 If this functionality is unavailable, using it raises an exception.\n\
4684\n\
4685If times is not None, it must be a tuple (atime, mtime);\n\
4686 atime and mtime should be expressed as float seconds since the epoch.\n\
4687If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4688 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4689 since the epoch.\n\
4690If both times and ns are None, utime uses the current time.\n\
4691Specifying tuples for both times and ns is an error.\n\
4692\n\
4693If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4694 and path should be relative; path will then be relative to that directory.\n\
4695If follow_symlinks is False, and the last element of the path is a symbolic\n\
4696 link, utime will modify the symbolic link itself instead of the file the\n\
4697 link points to.\n\
4698It is an error to use dir_fd or follow_symlinks when specifying path\n\
4699 as an open file descriptor.\n\
4700dir_fd and follow_symlinks may not be available on your platform.\n\
4701 If they are unavailable, using them will raise a NotImplementedError.");
4702
4703typedef struct {
4704 int now;
4705 time_t atime_s;
4706 long atime_ns;
4707 time_t mtime_s;
4708 long mtime_ns;
4709} utime_t;
4710
4711/*
Victor Stinner484df002014-10-09 13:52:31 +02004712 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004713 * they also intentionally leak the declaration of a pointer named "time"
4714 */
4715#define UTIME_TO_TIMESPEC \
4716 struct timespec ts[2]; \
4717 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004718 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004719 time = NULL; \
4720 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004721 ts[0].tv_sec = ut->atime_s; \
4722 ts[0].tv_nsec = ut->atime_ns; \
4723 ts[1].tv_sec = ut->mtime_s; \
4724 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004725 time = ts; \
4726 } \
4727
4728#define UTIME_TO_TIMEVAL \
4729 struct timeval tv[2]; \
4730 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004731 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732 time = NULL; \
4733 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004734 tv[0].tv_sec = ut->atime_s; \
4735 tv[0].tv_usec = ut->atime_ns / 1000; \
4736 tv[1].tv_sec = ut->mtime_s; \
4737 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004738 time = tv; \
4739 } \
4740
4741#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004742 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004743 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004744 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 time = NULL; \
4746 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004747 u.actime = ut->atime_s; \
4748 u.modtime = ut->mtime_s; \
4749 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004750 }
4751
4752#define UTIME_TO_TIME_T \
4753 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004754 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004755 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004756 time = NULL; \
4757 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004758 timet[0] = ut->atime_s; \
4759 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004760 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004761 } \
4762
4763
4764#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4765
4766#if UTIME_HAVE_DIR_FD
4767
4768static int
Victor Stinner484df002014-10-09 13:52:31 +02004769utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770{
4771#ifdef HAVE_UTIMENSAT
4772 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4773 UTIME_TO_TIMESPEC;
4774 return utimensat(dir_fd, path, time, flags);
4775#elif defined(HAVE_FUTIMESAT)
4776 UTIME_TO_TIMEVAL;
4777 /*
4778 * follow_symlinks will never be false here;
4779 * we only allow !follow_symlinks and dir_fd together
4780 * if we have utimensat()
4781 */
4782 assert(follow_symlinks);
4783 return futimesat(dir_fd, path, time);
4784#endif
4785}
4786
4787#endif
4788
4789#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4790
4791#if UTIME_HAVE_FD
4792
4793static int
Victor Stinner484df002014-10-09 13:52:31 +02004794utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004795{
4796#ifdef HAVE_FUTIMENS
4797 UTIME_TO_TIMESPEC;
4798 return futimens(fd, time);
4799#else
4800 UTIME_TO_TIMEVAL;
4801 return futimes(fd, time);
4802#endif
4803}
4804
4805#endif
4806
4807
4808#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4809 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4810
4811#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4812
4813static int
Victor Stinner484df002014-10-09 13:52:31 +02004814utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004815{
4816#ifdef HAVE_UTIMENSAT
4817 UTIME_TO_TIMESPEC;
4818 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4819#else
4820 UTIME_TO_TIMEVAL;
4821 return lutimes(path, time);
4822#endif
4823}
4824
4825#endif
4826
4827#ifndef MS_WINDOWS
4828
4829static int
Victor Stinner484df002014-10-09 13:52:31 +02004830utime_default(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, 0);
4835#elif defined(HAVE_UTIMES)
4836 UTIME_TO_TIMEVAL;
4837 return utimes(path, time);
4838#elif defined(HAVE_UTIME_H)
4839 UTIME_TO_UTIMBUF;
4840 return utime(path, time);
4841#else
4842 UTIME_TO_TIME_T;
4843 return utime(path, time);
4844#endif
4845}
4846
4847#endif
4848
Larry Hastings76ad59b2012-05-03 00:30:07 -07004849static int
4850split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4851{
4852 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004853 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004854 divmod = PyNumber_Divmod(py_long, billion);
4855 if (!divmod)
4856 goto exit;
4857 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4858 if ((*s == -1) && PyErr_Occurred())
4859 goto exit;
4860 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004861 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004862 goto exit;
4863
4864 result = 1;
4865exit:
4866 Py_XDECREF(divmod);
4867 return result;
4868}
4869
Larry Hastings9cf065c2012-06-22 16:30:09 -07004870static PyObject *
4871posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004872{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004873 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004874 PyObject *times = NULL;
4875 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004876 int dir_fd = DEFAULT_DIR_FD;
4877 int follow_symlinks = 1;
4878 char *keywords[] = {"path", "times", "ns", "dir_fd",
4879 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004880
Larry Hastings9cf065c2012-06-22 16:30:09 -07004881 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004882
Larry Hastings9cf065c2012-06-22 16:30:09 -07004883#ifdef MS_WINDOWS
4884 HANDLE hFile;
4885 FILETIME atime, mtime;
4886#else
4887 int result;
4888#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004889
Larry Hastings9cf065c2012-06-22 16:30:09 -07004890 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004891
Larry Hastings9cf065c2012-06-22 16:30:09 -07004892 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004893 path.function_name = "utime";
Christian Heimesb3c87242013-08-01 00:08:16 +02004894 memset(&utime, 0, sizeof(utime_t));
Larry Hastings9cf065c2012-06-22 16:30:09 -07004895#if UTIME_HAVE_FD
4896 path.allow_fd = 1;
4897#endif
4898 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4899 "O&|O$OO&p:utime", keywords,
4900 path_converter, &path,
4901 &times, &ns,
4902#if UTIME_HAVE_DIR_FD
4903 dir_fd_converter, &dir_fd,
4904#else
4905 dir_fd_unavailable, &dir_fd,
4906#endif
4907 &follow_symlinks
4908 ))
4909 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004910
Larry Hastings9cf065c2012-06-22 16:30:09 -07004911 if (times && (times != Py_None) && ns) {
4912 PyErr_SetString(PyExc_ValueError,
4913 "utime: you may specify either 'times'"
4914 " or 'ns' but not both");
4915 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004916 }
4917
4918 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004919 time_t a_sec, m_sec;
4920 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004921 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004922 PyErr_SetString(PyExc_TypeError,
4923 "utime: 'times' must be either"
4924 " a tuple of two ints or None");
4925 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004926 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004927 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004928 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004929 &a_sec, &a_nsec, _PyTime_ROUND_DOWN) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004930 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinner3c1b3792014-02-17 00:02:43 +01004931 &m_sec, &m_nsec, _PyTime_ROUND_DOWN) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004932 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004933 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004934 utime.atime_s = a_sec;
4935 utime.atime_ns = a_nsec;
4936 utime.mtime_s = m_sec;
4937 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004938 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004939 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004940 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004941 PyErr_SetString(PyExc_TypeError,
4942 "utime: 'ns' must be a tuple of two ints");
4943 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004944 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004945 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004946 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004947 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004948 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004949 &utime.mtime_s, &utime.mtime_ns)) {
4950 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004951 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004952 }
4953 else {
4954 /* times and ns are both None/unspecified. use "now". */
4955 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004956 }
4957
Larry Hastings9cf065c2012-06-22 16:30:09 -07004958#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4959 if (follow_symlinks_specified("utime", follow_symlinks))
4960 goto exit;
4961#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004962
Larry Hastings9cf065c2012-06-22 16:30:09 -07004963 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4964 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4965 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4966 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004967
Larry Hastings9cf065c2012-06-22 16:30:09 -07004968#if !defined(HAVE_UTIMENSAT)
4969 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004970 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004971 "utime: cannot use dir_fd and follow_symlinks "
4972 "together on this platform");
4973 goto exit;
4974 }
4975#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004976
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004977#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004978 Py_BEGIN_ALLOW_THREADS
4979 if (path.wide)
4980 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 NULL, OPEN_EXISTING,
4982 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004983 else
4984 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004985 NULL, OPEN_EXISTING,
4986 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004987 Py_END_ALLOW_THREADS
4988 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004989 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004990 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004991 }
4992
Larry Hastings9cf065c2012-06-22 16:30:09 -07004993 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004994 GetSystemTimeAsFileTime(&mtime);
4995 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004996 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004997 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004998 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4999 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005000 }
5001 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5002 /* Avoid putting the file name into the error here,
5003 as that may confuse the user into believing that
5004 something is wrong with the file, when it also
5005 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005006 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005007 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005008 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005009#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005010 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005011
Larry Hastings9cf065c2012-06-22 16:30:09 -07005012#if UTIME_HAVE_NOFOLLOW_SYMLINKS
5013 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
5014 result = utime_nofollow_symlinks(&utime, path.narrow);
5015 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005016#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005017
5018#if UTIME_HAVE_DIR_FD
5019 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
5020 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
5021 else
5022#endif
5023
5024#if UTIME_HAVE_FD
5025 if (path.fd != -1)
5026 result = utime_fd(&utime, path.fd);
5027 else
5028#endif
5029
5030 result = utime_default(&utime, path.narrow);
5031
5032 Py_END_ALLOW_THREADS
5033
5034 if (result < 0) {
5035 /* see previous comment about not putting filename in error here */
5036 return_value = posix_error();
5037 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00005038 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005039
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005040#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005041
5042 Py_INCREF(Py_None);
5043 return_value = Py_None;
5044
5045exit:
5046 path_cleanup(&path);
5047#ifdef MS_WINDOWS
5048 if (hFile != INVALID_HANDLE_VALUE)
5049 CloseHandle(hFile);
5050#endif
5051 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005052}
5053
Guido van Rossum3b066191991-06-04 19:40:25 +00005054/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005055
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005056PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005057"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005058Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005059
Barry Warsaw53699e91996-12-10 23:23:01 +00005060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005061posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005062{
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 int sts;
5064 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5065 return NULL;
5066 _exit(sts);
5067 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005068}
5069
Martin v. Löwis114619e2002-10-07 06:44:21 +00005070#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5071static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00005072free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005073{
Victor Stinner8c62be82010-05-06 00:08:46 +00005074 Py_ssize_t i;
5075 for (i = 0; i < count; i++)
5076 PyMem_Free(array[i]);
5077 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005078}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005079
Antoine Pitrou69f71142009-05-24 21:25:49 +00005080static
Martin v. Löwis011e8422009-05-05 04:43:17 +00005081int fsconvert_strdup(PyObject *o, char**out)
5082{
Victor Stinner8c62be82010-05-06 00:08:46 +00005083 PyObject *bytes;
5084 Py_ssize_t size;
5085 if (!PyUnicode_FSConverter(o, &bytes))
5086 return 0;
5087 size = PyBytes_GET_SIZE(bytes);
5088 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01005089 if (!*out) {
5090 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00005091 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01005092 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005093 memcpy(*out, PyBytes_AsString(bytes), size+1);
5094 Py_DECREF(bytes);
5095 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005096}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005097#endif
5098
Ross Lagerwall7807c352011-03-17 20:20:30 +02005099#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005100static char**
5101parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5102{
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 char **envlist;
5104 Py_ssize_t i, pos, envc;
5105 PyObject *keys=NULL, *vals=NULL;
5106 PyObject *key, *val, *key2, *val2;
5107 char *p, *k, *v;
5108 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005109
Victor Stinner8c62be82010-05-06 00:08:46 +00005110 i = PyMapping_Size(env);
5111 if (i < 0)
5112 return NULL;
5113 envlist = PyMem_NEW(char *, i + 1);
5114 if (envlist == NULL) {
5115 PyErr_NoMemory();
5116 return NULL;
5117 }
5118 envc = 0;
5119 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005120 if (!keys)
5121 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005122 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005123 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005124 goto error;
5125 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5126 PyErr_Format(PyExc_TypeError,
5127 "env.keys() or env.values() is not a list");
5128 goto error;
5129 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005130
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 for (pos = 0; pos < i; pos++) {
5132 key = PyList_GetItem(keys, pos);
5133 val = PyList_GetItem(vals, pos);
5134 if (!key || !val)
5135 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005136
Victor Stinner8c62be82010-05-06 00:08:46 +00005137 if (PyUnicode_FSConverter(key, &key2) == 0)
5138 goto error;
5139 if (PyUnicode_FSConverter(val, &val2) == 0) {
5140 Py_DECREF(key2);
5141 goto error;
5142 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005143
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 k = PyBytes_AsString(key2);
5145 v = PyBytes_AsString(val2);
5146 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005147
Victor Stinner8c62be82010-05-06 00:08:46 +00005148 p = PyMem_NEW(char, len);
5149 if (p == NULL) {
5150 PyErr_NoMemory();
5151 Py_DECREF(key2);
5152 Py_DECREF(val2);
5153 goto error;
5154 }
5155 PyOS_snprintf(p, len, "%s=%s", k, v);
5156 envlist[envc++] = p;
5157 Py_DECREF(key2);
5158 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005159 }
5160 Py_DECREF(vals);
5161 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005162
Victor Stinner8c62be82010-05-06 00:08:46 +00005163 envlist[envc] = 0;
5164 *envc_ptr = envc;
5165 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005166
5167error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 Py_XDECREF(keys);
5169 Py_XDECREF(vals);
5170 while (--envc >= 0)
5171 PyMem_DEL(envlist[envc]);
5172 PyMem_DEL(envlist);
5173 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005174}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005175
Ross Lagerwall7807c352011-03-17 20:20:30 +02005176static char**
5177parse_arglist(PyObject* argv, Py_ssize_t *argc)
5178{
5179 int i;
5180 char **argvlist = PyMem_NEW(char *, *argc+1);
5181 if (argvlist == NULL) {
5182 PyErr_NoMemory();
5183 return NULL;
5184 }
5185 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005186 PyObject* item = PySequence_ITEM(argv, i);
5187 if (item == NULL)
5188 goto fail;
5189 if (!fsconvert_strdup(item, &argvlist[i])) {
5190 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005191 goto fail;
5192 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005193 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005194 }
5195 argvlist[*argc] = NULL;
5196 return argvlist;
5197fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005198 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005199 free_string_array(argvlist, *argc);
5200 return NULL;
5201}
5202#endif
5203
5204#ifdef HAVE_EXECV
5205PyDoc_STRVAR(posix_execv__doc__,
5206"execv(path, args)\n\n\
5207Execute an executable path with arguments, replacing current process.\n\
5208\n\
5209 path: path of executable file\n\
5210 args: tuple or list of strings");
5211
5212static PyObject *
5213posix_execv(PyObject *self, PyObject *args)
5214{
5215 PyObject *opath;
5216 char *path;
5217 PyObject *argv;
5218 char **argvlist;
5219 Py_ssize_t argc;
5220
5221 /* execv has two arguments: (path, argv), where
5222 argv is a list or tuple of strings. */
5223
5224 if (!PyArg_ParseTuple(args, "O&O:execv",
5225 PyUnicode_FSConverter,
5226 &opath, &argv))
5227 return NULL;
5228 path = PyBytes_AsString(opath);
5229 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5230 PyErr_SetString(PyExc_TypeError,
5231 "execv() arg 2 must be a tuple or list");
5232 Py_DECREF(opath);
5233 return NULL;
5234 }
5235 argc = PySequence_Size(argv);
5236 if (argc < 1) {
5237 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5238 Py_DECREF(opath);
5239 return NULL;
5240 }
5241
5242 argvlist = parse_arglist(argv, &argc);
5243 if (argvlist == NULL) {
5244 Py_DECREF(opath);
5245 return NULL;
5246 }
5247
5248 execv(path, argvlist);
5249
5250 /* If we get here it's definitely an error */
5251
5252 free_string_array(argvlist, argc);
5253 Py_DECREF(opath);
5254 return posix_error();
5255}
5256
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005257PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005258"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005259Execute a path with arguments and environment, replacing current process.\n\
5260\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005261 path: path of executable file\n\
5262 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005263 env: dictionary of strings mapping to strings\n\
5264\n\
5265On some platforms, you may specify an open file descriptor for path;\n\
5266 execve will execute the program the file descriptor is open to.\n\
5267 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005268
Barry Warsaw53699e91996-12-10 23:23:01 +00005269static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005270posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005271{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005272 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005273 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005274 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005275 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005276 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005277 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005278
Victor Stinner8c62be82010-05-06 00:08:46 +00005279 /* execve has three arguments: (path, argv, env), where
5280 argv is a list or tuple of strings and env is a dictionary
5281 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005282
Larry Hastings9cf065c2012-06-22 16:30:09 -07005283 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01005284 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07005285#ifdef HAVE_FEXECVE
5286 path.allow_fd = 1;
5287#endif
5288 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5289 path_converter, &path,
5290 &argv, &env
5291 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005292 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005293
Ross Lagerwall7807c352011-03-17 20:20:30 +02005294 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005295 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005296 "execve: argv must be a tuple or list");
5297 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005298 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005299 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005300 if (!PyMapping_Check(env)) {
5301 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005302 "execve: environment must be a mapping object");
5303 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005304 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005305
Ross Lagerwall7807c352011-03-17 20:20:30 +02005306 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005307 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005308 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005309 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005310
Victor Stinner8c62be82010-05-06 00:08:46 +00005311 envlist = parse_envlist(env, &envc);
5312 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005313 goto fail;
5314
Larry Hastings9cf065c2012-06-22 16:30:09 -07005315#ifdef HAVE_FEXECVE
5316 if (path.fd > -1)
5317 fexecve(path.fd, argvlist, envlist);
5318 else
5319#endif
5320 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005321
5322 /* If we get here it's definitely an error */
5323
Victor Stinner292c8352012-10-30 02:17:38 +01005324 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005325
5326 while (--envc >= 0)
5327 PyMem_DEL(envlist[envc]);
5328 PyMem_DEL(envlist);
5329 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005330 if (argvlist)
5331 free_string_array(argvlist, argc);
5332 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005333 return NULL;
5334}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005335#endif /* HAVE_EXECV */
5336
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005337
Guido van Rossuma1065681999-01-25 23:20:23 +00005338#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005339PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005340"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005341Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005342\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005343 mode: mode of process creation\n\
5344 path: path of executable file\n\
5345 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005346
5347static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005348posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005349{
Victor Stinner8c62be82010-05-06 00:08:46 +00005350 PyObject *opath;
5351 char *path;
5352 PyObject *argv;
5353 char **argvlist;
5354 int mode, i;
5355 Py_ssize_t argc;
5356 Py_intptr_t spawnval;
5357 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005358
Victor Stinner8c62be82010-05-06 00:08:46 +00005359 /* spawnv has three arguments: (mode, path, argv), where
5360 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005361
Victor Stinner8c62be82010-05-06 00:08:46 +00005362 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5363 PyUnicode_FSConverter,
5364 &opath, &argv))
5365 return NULL;
5366 path = PyBytes_AsString(opath);
5367 if (PyList_Check(argv)) {
5368 argc = PyList_Size(argv);
5369 getitem = PyList_GetItem;
5370 }
5371 else if (PyTuple_Check(argv)) {
5372 argc = PyTuple_Size(argv);
5373 getitem = PyTuple_GetItem;
5374 }
5375 else {
5376 PyErr_SetString(PyExc_TypeError,
5377 "spawnv() arg 2 must be a tuple or list");
5378 Py_DECREF(opath);
5379 return NULL;
5380 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005381
Victor Stinner8c62be82010-05-06 00:08:46 +00005382 argvlist = PyMem_NEW(char *, argc+1);
5383 if (argvlist == NULL) {
5384 Py_DECREF(opath);
5385 return PyErr_NoMemory();
5386 }
5387 for (i = 0; i < argc; i++) {
5388 if (!fsconvert_strdup((*getitem)(argv, i),
5389 &argvlist[i])) {
5390 free_string_array(argvlist, i);
5391 PyErr_SetString(
5392 PyExc_TypeError,
5393 "spawnv() arg 2 must contain only strings");
5394 Py_DECREF(opath);
5395 return NULL;
5396 }
5397 }
5398 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005399
Victor Stinner8c62be82010-05-06 00:08:46 +00005400 if (mode == _OLD_P_OVERLAY)
5401 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005402
Victor Stinner8c62be82010-05-06 00:08:46 +00005403 Py_BEGIN_ALLOW_THREADS
5404 spawnval = _spawnv(mode, path, argvlist);
5405 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005406
Victor Stinner8c62be82010-05-06 00:08:46 +00005407 free_string_array(argvlist, argc);
5408 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005409
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 if (spawnval == -1)
5411 return posix_error();
5412 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005413 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005414}
5415
5416
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005417PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005418"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005419Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005420\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005421 mode: mode of process creation\n\
5422 path: path of executable file\n\
5423 args: tuple or list of arguments\n\
5424 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005425
5426static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005427posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005428{
Victor Stinner8c62be82010-05-06 00:08:46 +00005429 PyObject *opath;
5430 char *path;
5431 PyObject *argv, *env;
5432 char **argvlist;
5433 char **envlist;
5434 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005435 int mode;
5436 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005437 Py_intptr_t spawnval;
5438 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5439 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005440
Victor Stinner8c62be82010-05-06 00:08:46 +00005441 /* spawnve has four arguments: (mode, path, argv, env), where
5442 argv is a list or tuple of strings and env is a dictionary
5443 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005444
Victor Stinner8c62be82010-05-06 00:08:46 +00005445 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5446 PyUnicode_FSConverter,
5447 &opath, &argv, &env))
5448 return NULL;
5449 path = PyBytes_AsString(opath);
5450 if (PyList_Check(argv)) {
5451 argc = PyList_Size(argv);
5452 getitem = PyList_GetItem;
5453 }
5454 else if (PyTuple_Check(argv)) {
5455 argc = PyTuple_Size(argv);
5456 getitem = PyTuple_GetItem;
5457 }
5458 else {
5459 PyErr_SetString(PyExc_TypeError,
5460 "spawnve() arg 2 must be a tuple or list");
5461 goto fail_0;
5462 }
5463 if (!PyMapping_Check(env)) {
5464 PyErr_SetString(PyExc_TypeError,
5465 "spawnve() arg 3 must be a mapping object");
5466 goto fail_0;
5467 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005468
Victor Stinner8c62be82010-05-06 00:08:46 +00005469 argvlist = PyMem_NEW(char *, argc+1);
5470 if (argvlist == NULL) {
5471 PyErr_NoMemory();
5472 goto fail_0;
5473 }
5474 for (i = 0; i < argc; i++) {
5475 if (!fsconvert_strdup((*getitem)(argv, i),
5476 &argvlist[i]))
5477 {
5478 lastarg = i;
5479 goto fail_1;
5480 }
5481 }
5482 lastarg = argc;
5483 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005484
Victor Stinner8c62be82010-05-06 00:08:46 +00005485 envlist = parse_envlist(env, &envc);
5486 if (envlist == NULL)
5487 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005488
Victor Stinner8c62be82010-05-06 00:08:46 +00005489 if (mode == _OLD_P_OVERLAY)
5490 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005491
Victor Stinner8c62be82010-05-06 00:08:46 +00005492 Py_BEGIN_ALLOW_THREADS
5493 spawnval = _spawnve(mode, path, argvlist, envlist);
5494 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005495
Victor Stinner8c62be82010-05-06 00:08:46 +00005496 if (spawnval == -1)
5497 (void) posix_error();
5498 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005499 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005500
Victor Stinner8c62be82010-05-06 00:08:46 +00005501 while (--envc >= 0)
5502 PyMem_DEL(envlist[envc]);
5503 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005504 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005505 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005506 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005507 Py_DECREF(opath);
5508 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005509}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005510
Guido van Rossuma1065681999-01-25 23:20:23 +00005511#endif /* HAVE_SPAWNV */
5512
5513
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005514#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005515PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005516"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005517Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5518\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005519Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005520
5521static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005522posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005523{
Victor Stinner8c62be82010-05-06 00:08:46 +00005524 pid_t pid;
5525 int result = 0;
5526 _PyImport_AcquireLock();
5527 pid = fork1();
5528 if (pid == 0) {
5529 /* child: this clobbers and resets the import lock. */
5530 PyOS_AfterFork();
5531 } else {
5532 /* parent: release the import lock. */
5533 result = _PyImport_ReleaseLock();
5534 }
5535 if (pid == -1)
5536 return posix_error();
5537 if (result < 0) {
5538 /* Don't clobber the OSError if the fork failed. */
5539 PyErr_SetString(PyExc_RuntimeError,
5540 "not holding the import lock");
5541 return NULL;
5542 }
5543 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005544}
5545#endif
5546
5547
Guido van Rossumad0ee831995-03-01 10:34:45 +00005548#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005549PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005550"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005551Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005552Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005553
Barry Warsaw53699e91996-12-10 23:23:01 +00005554static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005555posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005556{
Victor Stinner8c62be82010-05-06 00:08:46 +00005557 pid_t pid;
5558 int result = 0;
5559 _PyImport_AcquireLock();
5560 pid = fork();
5561 if (pid == 0) {
5562 /* child: this clobbers and resets the import lock. */
5563 PyOS_AfterFork();
5564 } else {
5565 /* parent: release the import lock. */
5566 result = _PyImport_ReleaseLock();
5567 }
5568 if (pid == -1)
5569 return posix_error();
5570 if (result < 0) {
5571 /* Don't clobber the OSError if the fork failed. */
5572 PyErr_SetString(PyExc_RuntimeError,
5573 "not holding the import lock");
5574 return NULL;
5575 }
5576 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005577}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005578#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005579
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005580#ifdef HAVE_SCHED_H
5581
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005582#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5583
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005584PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5585"sched_get_priority_max(policy)\n\n\
5586Get the maximum scheduling priority for *policy*.");
5587
5588static PyObject *
5589posix_sched_get_priority_max(PyObject *self, PyObject *args)
5590{
5591 int policy, max;
5592
5593 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5594 return NULL;
5595 max = sched_get_priority_max(policy);
5596 if (max < 0)
5597 return posix_error();
5598 return PyLong_FromLong(max);
5599}
5600
5601PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5602"sched_get_priority_min(policy)\n\n\
5603Get the minimum scheduling priority for *policy*.");
5604
5605static PyObject *
5606posix_sched_get_priority_min(PyObject *self, PyObject *args)
5607{
5608 int policy, min;
5609
5610 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5611 return NULL;
5612 min = sched_get_priority_min(policy);
5613 if (min < 0)
5614 return posix_error();
5615 return PyLong_FromLong(min);
5616}
5617
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005618#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5619
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005620#ifdef HAVE_SCHED_SETSCHEDULER
5621
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005622PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5623"sched_getscheduler(pid)\n\n\
5624Get the scheduling policy for the process with a PID of *pid*.\n\
5625Passing a PID of 0 returns the scheduling policy for the calling process.");
5626
5627static PyObject *
5628posix_sched_getscheduler(PyObject *self, PyObject *args)
5629{
5630 pid_t pid;
5631 int policy;
5632
5633 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5634 return NULL;
5635 policy = sched_getscheduler(pid);
5636 if (policy < 0)
5637 return posix_error();
5638 return PyLong_FromLong(policy);
5639}
5640
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005641#endif
5642
5643#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5644
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005645static PyObject *
5646sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5647{
5648 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005649 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005650
5651 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5652 return NULL;
5653 res = PyStructSequence_New(type);
5654 if (!res)
5655 return NULL;
5656 Py_INCREF(priority);
5657 PyStructSequence_SET_ITEM(res, 0, priority);
5658 return res;
5659}
5660
5661PyDoc_STRVAR(sched_param__doc__,
5662"sched_param(sched_priority): A scheduling parameter.\n\n\
5663Current has only one field: sched_priority");
5664
5665static PyStructSequence_Field sched_param_fields[] = {
5666 {"sched_priority", "the scheduling priority"},
5667 {0}
5668};
5669
5670static PyStructSequence_Desc sched_param_desc = {
5671 "sched_param", /* name */
5672 sched_param__doc__, /* doc */
5673 sched_param_fields,
5674 1
5675};
5676
5677static int
5678convert_sched_param(PyObject *param, struct sched_param *res)
5679{
5680 long priority;
5681
5682 if (Py_TYPE(param) != &SchedParamType) {
5683 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5684 return 0;
5685 }
5686 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5687 if (priority == -1 && PyErr_Occurred())
5688 return 0;
5689 if (priority > INT_MAX || priority < INT_MIN) {
5690 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5691 return 0;
5692 }
5693 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5694 return 1;
5695}
5696
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005697#endif
5698
5699#ifdef HAVE_SCHED_SETSCHEDULER
5700
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005701PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5702"sched_setscheduler(pid, policy, param)\n\n\
5703Set the scheduling policy, *policy*, for *pid*.\n\
5704If *pid* is 0, the calling process is changed.\n\
5705*param* is an instance of sched_param.");
5706
5707static PyObject *
5708posix_sched_setscheduler(PyObject *self, PyObject *args)
5709{
5710 pid_t pid;
5711 int policy;
5712 struct sched_param param;
5713
5714 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5715 &pid, &policy, &convert_sched_param, &param))
5716 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005717
5718 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005719 ** sched_setscheduler() returns 0 in Linux, but the previous
5720 ** scheduling policy under Solaris/Illumos, and others.
5721 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005722 */
5723 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005724 return posix_error();
5725 Py_RETURN_NONE;
5726}
5727
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005728#endif
5729
5730#ifdef HAVE_SCHED_SETPARAM
5731
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005732PyDoc_STRVAR(posix_sched_getparam__doc__,
5733"sched_getparam(pid) -> sched_param\n\n\
5734Returns scheduling parameters for the process with *pid* as an instance of the\n\
5735sched_param class. A PID of 0 means the calling process.");
5736
5737static PyObject *
5738posix_sched_getparam(PyObject *self, PyObject *args)
5739{
5740 pid_t pid;
5741 struct sched_param param;
5742 PyObject *res, *priority;
5743
5744 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5745 return NULL;
5746 if (sched_getparam(pid, &param))
5747 return posix_error();
5748 res = PyStructSequence_New(&SchedParamType);
5749 if (!res)
5750 return NULL;
5751 priority = PyLong_FromLong(param.sched_priority);
5752 if (!priority) {
5753 Py_DECREF(res);
5754 return NULL;
5755 }
5756 PyStructSequence_SET_ITEM(res, 0, priority);
5757 return res;
5758}
5759
5760PyDoc_STRVAR(posix_sched_setparam__doc__,
5761"sched_setparam(pid, param)\n\n\
5762Set scheduling parameters for a process with PID *pid*.\n\
5763A PID of 0 means the calling process.");
5764
5765static PyObject *
5766posix_sched_setparam(PyObject *self, PyObject *args)
5767{
5768 pid_t pid;
5769 struct sched_param param;
5770
5771 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5772 &pid, &convert_sched_param, &param))
5773 return NULL;
5774 if (sched_setparam(pid, &param))
5775 return posix_error();
5776 Py_RETURN_NONE;
5777}
5778
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005779#endif
5780
5781#ifdef HAVE_SCHED_RR_GET_INTERVAL
5782
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005783PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5784"sched_rr_get_interval(pid) -> float\n\n\
5785Return the round-robin quantum for the process with PID *pid* in seconds.");
5786
5787static PyObject *
5788posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5789{
5790 pid_t pid;
5791 struct timespec interval;
5792
5793 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5794 return NULL;
5795 if (sched_rr_get_interval(pid, &interval))
5796 return posix_error();
5797 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5798}
5799
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005800#endif
5801
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005802PyDoc_STRVAR(posix_sched_yield__doc__,
5803"sched_yield()\n\n\
5804Voluntarily relinquish the CPU.");
5805
5806static PyObject *
5807posix_sched_yield(PyObject *self, PyObject *noargs)
5808{
5809 if (sched_yield())
5810 return posix_error();
5811 Py_RETURN_NONE;
5812}
5813
Benjamin Peterson2740af82011-08-02 17:41:34 -05005814#ifdef HAVE_SCHED_SETAFFINITY
5815
Antoine Pitrou84869872012-08-04 16:16:35 +02005816/* The minimum number of CPUs allocated in a cpu_set_t */
5817static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005818
5819PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5820"sched_setaffinity(pid, cpu_set)\n\n\
5821Set the affinity of the process with PID *pid* to *cpu_set*.");
5822
5823static PyObject *
5824posix_sched_setaffinity(PyObject *self, PyObject *args)
5825{
5826 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005827 int ncpus;
5828 size_t setsize;
5829 cpu_set_t *mask = NULL;
5830 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005831
Antoine Pitrou84869872012-08-04 16:16:35 +02005832 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5833 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005834 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005835
5836 iterator = PyObject_GetIter(iterable);
5837 if (iterator == NULL)
5838 return NULL;
5839
5840 ncpus = NCPUS_START;
5841 setsize = CPU_ALLOC_SIZE(ncpus);
5842 mask = CPU_ALLOC(ncpus);
5843 if (mask == NULL) {
5844 PyErr_NoMemory();
5845 goto error;
5846 }
5847 CPU_ZERO_S(setsize, mask);
5848
5849 while ((item = PyIter_Next(iterator))) {
5850 long cpu;
5851 if (!PyLong_Check(item)) {
5852 PyErr_Format(PyExc_TypeError,
5853 "expected an iterator of ints, "
5854 "but iterator yielded %R",
5855 Py_TYPE(item));
5856 Py_DECREF(item);
5857 goto error;
5858 }
5859 cpu = PyLong_AsLong(item);
5860 Py_DECREF(item);
5861 if (cpu < 0) {
5862 if (!PyErr_Occurred())
5863 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5864 goto error;
5865 }
5866 if (cpu > INT_MAX - 1) {
5867 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5868 goto error;
5869 }
5870 if (cpu >= ncpus) {
5871 /* Grow CPU mask to fit the CPU number */
5872 int newncpus = ncpus;
5873 cpu_set_t *newmask;
5874 size_t newsetsize;
5875 while (newncpus <= cpu) {
5876 if (newncpus > INT_MAX / 2)
5877 newncpus = cpu + 1;
5878 else
5879 newncpus = newncpus * 2;
5880 }
5881 newmask = CPU_ALLOC(newncpus);
5882 if (newmask == NULL) {
5883 PyErr_NoMemory();
5884 goto error;
5885 }
5886 newsetsize = CPU_ALLOC_SIZE(newncpus);
5887 CPU_ZERO_S(newsetsize, newmask);
5888 memcpy(newmask, mask, setsize);
5889 CPU_FREE(mask);
5890 setsize = newsetsize;
5891 mask = newmask;
5892 ncpus = newncpus;
5893 }
5894 CPU_SET_S(cpu, setsize, mask);
5895 }
5896 Py_CLEAR(iterator);
5897
5898 if (sched_setaffinity(pid, setsize, mask)) {
5899 posix_error();
5900 goto error;
5901 }
5902 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005903 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005904
5905error:
5906 if (mask)
5907 CPU_FREE(mask);
5908 Py_XDECREF(iterator);
5909 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005910}
5911
5912PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5913"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5914Return the affinity of the process with PID *pid*.\n\
5915The returned cpu_set will be of size *ncpus*.");
5916
5917static PyObject *
5918posix_sched_getaffinity(PyObject *self, PyObject *args)
5919{
5920 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005921 int cpu, ncpus, count;
5922 size_t setsize;
5923 cpu_set_t *mask = NULL;
5924 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005925
Antoine Pitrou84869872012-08-04 16:16:35 +02005926 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5927 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005928 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005929
5930 ncpus = NCPUS_START;
5931 while (1) {
5932 setsize = CPU_ALLOC_SIZE(ncpus);
5933 mask = CPU_ALLOC(ncpus);
5934 if (mask == NULL)
5935 return PyErr_NoMemory();
5936 if (sched_getaffinity(pid, setsize, mask) == 0)
5937 break;
5938 CPU_FREE(mask);
5939 if (errno != EINVAL)
5940 return posix_error();
5941 if (ncpus > INT_MAX / 2) {
5942 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5943 "a large enough CPU set");
5944 return NULL;
5945 }
5946 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005947 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005948
5949 res = PySet_New(NULL);
5950 if (res == NULL)
5951 goto error;
5952 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5953 if (CPU_ISSET_S(cpu, setsize, mask)) {
5954 PyObject *cpu_num = PyLong_FromLong(cpu);
5955 --count;
5956 if (cpu_num == NULL)
5957 goto error;
5958 if (PySet_Add(res, cpu_num)) {
5959 Py_DECREF(cpu_num);
5960 goto error;
5961 }
5962 Py_DECREF(cpu_num);
5963 }
5964 }
5965 CPU_FREE(mask);
5966 return res;
5967
5968error:
5969 if (mask)
5970 CPU_FREE(mask);
5971 Py_XDECREF(res);
5972 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005973}
5974
Benjamin Peterson2740af82011-08-02 17:41:34 -05005975#endif /* HAVE_SCHED_SETAFFINITY */
5976
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005977#endif /* HAVE_SCHED_H */
5978
Neal Norwitzb59798b2003-03-21 01:43:31 +00005979/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005980/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5981#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005982#define DEV_PTY_FILE "/dev/ptc"
5983#define HAVE_DEV_PTMX
5984#else
5985#define DEV_PTY_FILE "/dev/ptmx"
5986#endif
5987
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005988#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005989#ifdef HAVE_PTY_H
5990#include <pty.h>
5991#else
5992#ifdef HAVE_LIBUTIL_H
5993#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005994#else
5995#ifdef HAVE_UTIL_H
5996#include <util.h>
5997#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005998#endif /* HAVE_LIBUTIL_H */
5999#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006000#ifdef HAVE_STROPTS_H
6001#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006002#endif
6003#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006004
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006005#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006006PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006007"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006008Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006009
6010static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006011posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006012{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006013 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006014#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006015 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006016#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006017#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006019#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006020 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006021#endif
6022#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006023
Thomas Wouters70c21a12000-07-14 14:28:33 +00006024#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006025 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006026 goto posix_error;
6027
6028 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6029 goto error;
6030 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6031 goto error;
6032
Neal Norwitzb59798b2003-03-21 01:43:31 +00006033#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006034 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6035 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006036 goto posix_error;
6037 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6038 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006039
Victor Stinnerdaf45552013-08-28 00:53:59 +02006040 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006041 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006042 goto posix_error;
6043
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006044#else
Victor Stinner000de532013-11-25 23:19:58 +01006045 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006046 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006047 goto posix_error;
6048
Victor Stinner8c62be82010-05-06 00:08:46 +00006049 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006050
Victor Stinner8c62be82010-05-06 00:08:46 +00006051 /* change permission of slave */
6052 if (grantpt(master_fd) < 0) {
6053 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006054 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006055 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006056
Victor Stinner8c62be82010-05-06 00:08:46 +00006057 /* unlock slave */
6058 if (unlockpt(master_fd) < 0) {
6059 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006060 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006061 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006062
Victor Stinner8c62be82010-05-06 00:08:46 +00006063 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006064
Victor Stinner8c62be82010-05-06 00:08:46 +00006065 slave_name = ptsname(master_fd); /* get name of slave */
6066 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006067 goto posix_error;
6068
6069 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinner8c62be82010-05-06 00:08:46 +00006070 if (slave_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006071 goto posix_error;
Victor Stinner000de532013-11-25 23:19:58 +01006072
6073 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6074 goto posix_error;
6075
Neal Norwitzb59798b2003-03-21 01:43:31 +00006076#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6078 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006079#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006080 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006081#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006082#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006083#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006084
Victor Stinner8c62be82010-05-06 00:08:46 +00006085 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006086
Victor Stinnerdaf45552013-08-28 00:53:59 +02006087posix_error:
6088 posix_error();
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006089#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006090error:
Victor Stinnerb9981ba2013-08-28 01:51:06 +02006091#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +02006092 if (master_fd != -1)
6093 close(master_fd);
6094 if (slave_fd != -1)
6095 close(slave_fd);
6096 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006097}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006098#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006099
6100#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006101PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006102"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006103Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6104Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006105To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006106
6107static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006108posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006109{
Victor Stinner8c62be82010-05-06 00:08:46 +00006110 int master_fd = -1, result = 0;
6111 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006112
Victor Stinner8c62be82010-05-06 00:08:46 +00006113 _PyImport_AcquireLock();
6114 pid = forkpty(&master_fd, NULL, NULL, NULL);
6115 if (pid == 0) {
6116 /* child: this clobbers and resets the import lock. */
6117 PyOS_AfterFork();
6118 } else {
6119 /* parent: release the import lock. */
6120 result = _PyImport_ReleaseLock();
6121 }
6122 if (pid == -1)
6123 return posix_error();
6124 if (result < 0) {
6125 /* Don't clobber the OSError if the fork failed. */
6126 PyErr_SetString(PyExc_RuntimeError,
6127 "not holding the import lock");
6128 return NULL;
6129 }
6130 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006131}
6132#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006133
Ross Lagerwall7807c352011-03-17 20:20:30 +02006134
Guido van Rossumad0ee831995-03-01 10:34:45 +00006135#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006136PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006137"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006138Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006139
Barry Warsaw53699e91996-12-10 23:23:01 +00006140static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006141posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006142{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006143 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006144}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006145#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006146
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006147
Guido van Rossumad0ee831995-03-01 10:34:45 +00006148#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006149PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006150"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006151Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006152
Barry Warsaw53699e91996-12-10 23:23:01 +00006153static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006154posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006155{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006156 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006157}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006158#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006160
Guido van Rossumad0ee831995-03-01 10:34:45 +00006161#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006162PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006163"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006164Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006165
Barry Warsaw53699e91996-12-10 23:23:01 +00006166static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006167posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006168{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006169 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006170}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006171#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006172
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006173
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006174PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006175"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006176Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006177
Barry Warsaw53699e91996-12-10 23:23:01 +00006178static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006179posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006180{
Victor Stinner8c62be82010-05-06 00:08:46 +00006181 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006182}
6183
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006184#ifdef HAVE_GETGROUPLIST
6185PyDoc_STRVAR(posix_getgrouplist__doc__,
6186"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6187Returns a list of groups to which a user belongs.\n\n\
6188 user: username to lookup\n\
6189 group: base group id of the user");
6190
6191static PyObject *
6192posix_getgrouplist(PyObject *self, PyObject *args)
6193{
6194#ifdef NGROUPS_MAX
6195#define MAX_GROUPS NGROUPS_MAX
6196#else
6197 /* defined to be 16 on Solaris7, so this should be a small number */
6198#define MAX_GROUPS 64
6199#endif
6200
6201 const char *user;
6202 int i, ngroups;
6203 PyObject *list;
6204#ifdef __APPLE__
6205 int *groups, basegid;
6206#else
6207 gid_t *groups, basegid;
6208#endif
6209 ngroups = MAX_GROUPS;
6210
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006211#ifdef __APPLE__
6212 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006213 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006214#else
6215 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6216 _Py_Gid_Converter, &basegid))
6217 return NULL;
6218#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006219
6220#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006221 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006222#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006223 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006224#endif
6225 if (groups == NULL)
6226 return PyErr_NoMemory();
6227
6228 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6229 PyMem_Del(groups);
6230 return posix_error();
6231 }
6232
6233 list = PyList_New(ngroups);
6234 if (list == NULL) {
6235 PyMem_Del(groups);
6236 return NULL;
6237 }
6238
6239 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006240#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006241 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006242#else
6243 PyObject *o = _PyLong_FromGid(groups[i]);
6244#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006245 if (o == NULL) {
6246 Py_DECREF(list);
6247 PyMem_Del(groups);
6248 return NULL;
6249 }
6250 PyList_SET_ITEM(list, i, o);
6251 }
6252
6253 PyMem_Del(groups);
6254
6255 return list;
6256}
6257#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006258
Fred Drakec9680921999-12-13 16:37:25 +00006259#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006260PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006261"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006262Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006263
6264static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006265posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006266{
6267 PyObject *result = NULL;
6268
Fred Drakec9680921999-12-13 16:37:25 +00006269#ifdef NGROUPS_MAX
6270#define MAX_GROUPS NGROUPS_MAX
6271#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006272 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006273#define MAX_GROUPS 64
6274#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006276
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006277 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006278 * This is a helper variable to store the intermediate result when
6279 * that happens.
6280 *
6281 * To keep the code readable the OSX behaviour is unconditional,
6282 * according to the POSIX spec this should be safe on all unix-y
6283 * systems.
6284 */
6285 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006286 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006287
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006288#ifdef __APPLE__
6289 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6290 * there are more groups than can fit in grouplist. Therefore, on OS X
6291 * always first call getgroups with length 0 to get the actual number
6292 * of groups.
6293 */
6294 n = getgroups(0, NULL);
6295 if (n < 0) {
6296 return posix_error();
6297 } else if (n <= MAX_GROUPS) {
6298 /* groups will fit in existing array */
6299 alt_grouplist = grouplist;
6300 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006301 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006302 if (alt_grouplist == NULL) {
6303 errno = EINVAL;
6304 return posix_error();
6305 }
6306 }
6307
6308 n = getgroups(n, alt_grouplist);
6309 if (n == -1) {
6310 if (alt_grouplist != grouplist) {
6311 PyMem_Free(alt_grouplist);
6312 }
6313 return posix_error();
6314 }
6315#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006316 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006317 if (n < 0) {
6318 if (errno == EINVAL) {
6319 n = getgroups(0, NULL);
6320 if (n == -1) {
6321 return posix_error();
6322 }
6323 if (n == 0) {
6324 /* Avoid malloc(0) */
6325 alt_grouplist = grouplist;
6326 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006327 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006328 if (alt_grouplist == NULL) {
6329 errno = EINVAL;
6330 return posix_error();
6331 }
6332 n = getgroups(n, alt_grouplist);
6333 if (n == -1) {
6334 PyMem_Free(alt_grouplist);
6335 return posix_error();
6336 }
6337 }
6338 } else {
6339 return posix_error();
6340 }
6341 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006342#endif
6343
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006344 result = PyList_New(n);
6345 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006346 int i;
6347 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006348 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006349 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006350 Py_DECREF(result);
6351 result = NULL;
6352 break;
Fred Drakec9680921999-12-13 16:37:25 +00006353 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006354 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006355 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006356 }
6357
6358 if (alt_grouplist != grouplist) {
6359 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006360 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006361
Fred Drakec9680921999-12-13 16:37:25 +00006362 return result;
6363}
6364#endif
6365
Antoine Pitroub7572f02009-12-02 20:46:48 +00006366#ifdef HAVE_INITGROUPS
6367PyDoc_STRVAR(posix_initgroups__doc__,
6368"initgroups(username, gid) -> None\n\n\
6369Call the system initgroups() to initialize the group access list with all of\n\
6370the groups of which the specified username is a member, plus the specified\n\
6371group id.");
6372
6373static PyObject *
6374posix_initgroups(PyObject *self, PyObject *args)
6375{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006376 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006377 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006378 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006379#ifdef __APPLE__
6380 int gid;
6381#else
6382 gid_t gid;
6383#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006384
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006385#ifdef __APPLE__
6386 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6387 PyUnicode_FSConverter, &oname,
6388 &gid))
6389#else
6390 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6391 PyUnicode_FSConverter, &oname,
6392 _Py_Gid_Converter, &gid))
6393#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006394 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006395 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006396
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006397 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006398 Py_DECREF(oname);
6399 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006401
Victor Stinner8c62be82010-05-06 00:08:46 +00006402 Py_INCREF(Py_None);
6403 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006404}
6405#endif
6406
Martin v. Löwis606edc12002-06-13 21:09:11 +00006407#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006408PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006409"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006410Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006411
6412static PyObject *
6413posix_getpgid(PyObject *self, PyObject *args)
6414{
Victor Stinner8c62be82010-05-06 00:08:46 +00006415 pid_t pid, pgid;
6416 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6417 return NULL;
6418 pgid = getpgid(pid);
6419 if (pgid < 0)
6420 return posix_error();
6421 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006422}
6423#endif /* HAVE_GETPGID */
6424
6425
Guido van Rossumb6775db1994-08-01 11:34:53 +00006426#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006427PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006428"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006429Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006430
Barry Warsaw53699e91996-12-10 23:23:01 +00006431static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006432posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006433{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006434#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006435 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006436#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006437 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006438#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006439}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006440#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006441
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006442
Guido van Rossumb6775db1994-08-01 11:34:53 +00006443#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006444PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006445"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006446Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006447
Barry Warsaw53699e91996-12-10 23:23:01 +00006448static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006449posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006450{
Guido van Rossum64933891994-10-20 21:56:42 +00006451#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006453#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006454 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006455#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006456 return posix_error();
6457 Py_INCREF(Py_None);
6458 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006459}
6460
Guido van Rossumb6775db1994-08-01 11:34:53 +00006461#endif /* HAVE_SETPGRP */
6462
Guido van Rossumad0ee831995-03-01 10:34:45 +00006463#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006464
6465#ifdef MS_WINDOWS
6466#include <tlhelp32.h>
6467
6468static PyObject*
6469win32_getppid()
6470{
6471 HANDLE snapshot;
6472 pid_t mypid;
6473 PyObject* result = NULL;
6474 BOOL have_record;
6475 PROCESSENTRY32 pe;
6476
6477 mypid = getpid(); /* This function never fails */
6478
6479 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6480 if (snapshot == INVALID_HANDLE_VALUE)
6481 return PyErr_SetFromWindowsErr(GetLastError());
6482
6483 pe.dwSize = sizeof(pe);
6484 have_record = Process32First(snapshot, &pe);
6485 while (have_record) {
6486 if (mypid == (pid_t)pe.th32ProcessID) {
6487 /* We could cache the ulong value in a static variable. */
6488 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6489 break;
6490 }
6491
6492 have_record = Process32Next(snapshot, &pe);
6493 }
6494
6495 /* If our loop exits and our pid was not found (result will be NULL)
6496 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6497 * error anyway, so let's raise it. */
6498 if (!result)
6499 result = PyErr_SetFromWindowsErr(GetLastError());
6500
6501 CloseHandle(snapshot);
6502
6503 return result;
6504}
6505#endif /*MS_WINDOWS*/
6506
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006507PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006508"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006509Return the parent's process id. If the parent process has already exited,\n\
6510Windows machines will still return its id; others systems will return the id\n\
6511of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006512
Barry Warsaw53699e91996-12-10 23:23:01 +00006513static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006514posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006515{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006516#ifdef MS_WINDOWS
6517 return win32_getppid();
6518#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006519 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006520#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006521}
6522#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006523
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006524
Fred Drake12c6e2d1999-12-14 21:25:03 +00006525#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006526PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006527"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006528Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006529
6530static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006531posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006532{
Victor Stinner8c62be82010-05-06 00:08:46 +00006533 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006534#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006535 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006536 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006537
6538 if (GetUserNameW(user_name, &num_chars)) {
6539 /* num_chars is the number of unicode chars plus null terminator */
6540 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006541 }
6542 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006543 result = PyErr_SetFromWindowsErr(GetLastError());
6544#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006545 char *name;
6546 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006547
Victor Stinner8c62be82010-05-06 00:08:46 +00006548 errno = 0;
6549 name = getlogin();
6550 if (name == NULL) {
6551 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006552 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006553 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006554 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006555 }
6556 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006557 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006558 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006559#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006560 return result;
6561}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006562#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006563
Guido van Rossumad0ee831995-03-01 10:34:45 +00006564#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006565PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006566"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006567Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006568
Barry Warsaw53699e91996-12-10 23:23:01 +00006569static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006570posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006571{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006572 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006573}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006574#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006575
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006576
Guido van Rossumad0ee831995-03-01 10:34:45 +00006577#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006578PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006579"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006580Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006581
Barry Warsaw53699e91996-12-10 23:23:01 +00006582static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006583posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006584{
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 pid_t pid;
6586 int sig;
6587 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6588 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006589 if (kill(pid, sig) == -1)
6590 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006591 Py_INCREF(Py_None);
6592 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006593}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006594#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006595
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006596#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006597PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006598"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006599Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006600
6601static PyObject *
6602posix_killpg(PyObject *self, PyObject *args)
6603{
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 int sig;
6605 pid_t pgid;
6606 /* XXX some man pages make the `pgid` parameter an int, others
6607 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6608 take the same type. Moreover, pid_t is always at least as wide as
6609 int (else compilation of this module fails), which is safe. */
6610 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6611 return NULL;
6612 if (killpg(pgid, sig) == -1)
6613 return posix_error();
6614 Py_INCREF(Py_None);
6615 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006616}
6617#endif
6618
Brian Curtineb24d742010-04-12 17:16:38 +00006619#ifdef MS_WINDOWS
6620PyDoc_STRVAR(win32_kill__doc__,
6621"kill(pid, sig)\n\n\
6622Kill a process with a signal.");
6623
6624static PyObject *
6625win32_kill(PyObject *self, PyObject *args)
6626{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006627 PyObject *result;
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006628 pid_t pid;
6629 DWORD sig, err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006630 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006631
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006632 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig))
Victor Stinner8c62be82010-05-06 00:08:46 +00006633 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006634
Victor Stinner8c62be82010-05-06 00:08:46 +00006635 /* Console processes which share a common console can be sent CTRL+C or
6636 CTRL+BREAK events, provided they handle said events. */
6637 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006638 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006639 err = GetLastError();
6640 PyErr_SetFromWindowsErr(err);
6641 }
6642 else
6643 Py_RETURN_NONE;
6644 }
Brian Curtineb24d742010-04-12 17:16:38 +00006645
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6647 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006648 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 if (handle == NULL) {
6650 err = GetLastError();
6651 return PyErr_SetFromWindowsErr(err);
6652 }
Brian Curtineb24d742010-04-12 17:16:38 +00006653
Victor Stinner8c62be82010-05-06 00:08:46 +00006654 if (TerminateProcess(handle, sig) == 0) {
6655 err = GetLastError();
6656 result = PyErr_SetFromWindowsErr(err);
6657 } else {
6658 Py_INCREF(Py_None);
6659 result = Py_None;
6660 }
Brian Curtineb24d742010-04-12 17:16:38 +00006661
Victor Stinner8c62be82010-05-06 00:08:46 +00006662 CloseHandle(handle);
6663 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006664}
6665#endif /* MS_WINDOWS */
6666
Guido van Rossumc0125471996-06-28 18:55:32 +00006667#ifdef HAVE_PLOCK
6668
6669#ifdef HAVE_SYS_LOCK_H
6670#include <sys/lock.h>
6671#endif
6672
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006673PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006674"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006675Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006676
Barry Warsaw53699e91996-12-10 23:23:01 +00006677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006678posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006679{
Victor Stinner8c62be82010-05-06 00:08:46 +00006680 int op;
6681 if (!PyArg_ParseTuple(args, "i:plock", &op))
6682 return NULL;
6683 if (plock(op) == -1)
6684 return posix_error();
6685 Py_INCREF(Py_None);
6686 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006687}
6688#endif
6689
Guido van Rossumb6775db1994-08-01 11:34:53 +00006690#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006691PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006692"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006693Set the current process's user id.");
6694
Barry Warsaw53699e91996-12-10 23:23:01 +00006695static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006696posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006697{
Victor Stinner8c62be82010-05-06 00:08:46 +00006698 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006699 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006701 if (setuid(uid) < 0)
6702 return posix_error();
6703 Py_INCREF(Py_None);
6704 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006705}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006706#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006707
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006708
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006709#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006710PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006711"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006712Set the current process's effective user id.");
6713
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006714static PyObject *
6715posix_seteuid (PyObject *self, PyObject *args)
6716{
Victor Stinner8c62be82010-05-06 00:08:46 +00006717 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006718 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006720 if (seteuid(euid) < 0) {
6721 return posix_error();
6722 } else {
6723 Py_INCREF(Py_None);
6724 return Py_None;
6725 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006726}
6727#endif /* HAVE_SETEUID */
6728
6729#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006730PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006731"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006732Set the current process's effective group id.");
6733
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006734static PyObject *
6735posix_setegid (PyObject *self, PyObject *args)
6736{
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006738 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006739 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 if (setegid(egid) < 0) {
6741 return posix_error();
6742 } else {
6743 Py_INCREF(Py_None);
6744 return Py_None;
6745 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006746}
6747#endif /* HAVE_SETEGID */
6748
6749#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006750PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006751"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006752Set the current process's real and effective user ids.");
6753
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006754static PyObject *
6755posix_setreuid (PyObject *self, PyObject *args)
6756{
Victor Stinner8c62be82010-05-06 00:08:46 +00006757 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006758 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6759 _Py_Uid_Converter, &ruid,
6760 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 if (setreuid(ruid, euid) < 0) {
6763 return posix_error();
6764 } else {
6765 Py_INCREF(Py_None);
6766 return Py_None;
6767 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006768}
6769#endif /* HAVE_SETREUID */
6770
6771#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006772PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006773"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006774Set the current process's real and effective group ids.");
6775
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006776static PyObject *
6777posix_setregid (PyObject *self, PyObject *args)
6778{
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006780 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6781 _Py_Gid_Converter, &rgid,
6782 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006783 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 if (setregid(rgid, egid) < 0) {
6785 return posix_error();
6786 } else {
6787 Py_INCREF(Py_None);
6788 return Py_None;
6789 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006790}
6791#endif /* HAVE_SETREGID */
6792
Guido van Rossumb6775db1994-08-01 11:34:53 +00006793#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006794PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006795"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006796Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006797
Barry Warsaw53699e91996-12-10 23:23:01 +00006798static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006799posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006800{
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006802 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 if (setgid(gid) < 0)
6805 return posix_error();
6806 Py_INCREF(Py_None);
6807 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006808}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006809#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006810
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006811#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006813"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006814Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006815
6816static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006817posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006818{
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 int i, len;
6820 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006821
Victor Stinner8c62be82010-05-06 00:08:46 +00006822 if (!PySequence_Check(groups)) {
6823 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6824 return NULL;
6825 }
6826 len = PySequence_Size(groups);
6827 if (len > MAX_GROUPS) {
6828 PyErr_SetString(PyExc_ValueError, "too many groups");
6829 return NULL;
6830 }
6831 for(i = 0; i < len; i++) {
6832 PyObject *elem;
6833 elem = PySequence_GetItem(groups, i);
6834 if (!elem)
6835 return NULL;
6836 if (!PyLong_Check(elem)) {
6837 PyErr_SetString(PyExc_TypeError,
6838 "groups must be integers");
6839 Py_DECREF(elem);
6840 return NULL;
6841 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006842 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006843 Py_DECREF(elem);
6844 return NULL;
6845 }
6846 }
6847 Py_DECREF(elem);
6848 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006849
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 if (setgroups(len, grouplist) < 0)
6851 return posix_error();
6852 Py_INCREF(Py_None);
6853 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006854}
6855#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006856
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006857#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6858static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006859wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006860{
Victor Stinner8c62be82010-05-06 00:08:46 +00006861 PyObject *result;
6862 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006863 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006864
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 if (pid == -1)
6866 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006867
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 if (struct_rusage == NULL) {
6869 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6870 if (m == NULL)
6871 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006872 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 Py_DECREF(m);
6874 if (struct_rusage == NULL)
6875 return NULL;
6876 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006877
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6879 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6880 if (!result)
6881 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006882
6883#ifndef doubletime
6884#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6885#endif
6886
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006888 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006890 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006891#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6893 SET_INT(result, 2, ru->ru_maxrss);
6894 SET_INT(result, 3, ru->ru_ixrss);
6895 SET_INT(result, 4, ru->ru_idrss);
6896 SET_INT(result, 5, ru->ru_isrss);
6897 SET_INT(result, 6, ru->ru_minflt);
6898 SET_INT(result, 7, ru->ru_majflt);
6899 SET_INT(result, 8, ru->ru_nswap);
6900 SET_INT(result, 9, ru->ru_inblock);
6901 SET_INT(result, 10, ru->ru_oublock);
6902 SET_INT(result, 11, ru->ru_msgsnd);
6903 SET_INT(result, 12, ru->ru_msgrcv);
6904 SET_INT(result, 13, ru->ru_nsignals);
6905 SET_INT(result, 14, ru->ru_nvcsw);
6906 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006907#undef SET_INT
6908
Victor Stinner8c62be82010-05-06 00:08:46 +00006909 if (PyErr_Occurred()) {
6910 Py_DECREF(result);
6911 return NULL;
6912 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006913
Victor Stinner8c62be82010-05-06 00:08:46 +00006914 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006915}
6916#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6917
6918#ifdef HAVE_WAIT3
6919PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006920"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006921Wait for completion of a child process.");
6922
6923static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006924posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006925{
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 pid_t pid;
6927 int options;
6928 struct rusage ru;
6929 WAIT_TYPE status;
6930 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006931
Victor Stinner4195b5c2012-02-08 23:03:19 +01006932 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006933 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006934
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 Py_BEGIN_ALLOW_THREADS
6936 pid = wait3(&status, options, &ru);
6937 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006938
Victor Stinner4195b5c2012-02-08 23:03:19 +01006939 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006940}
6941#endif /* HAVE_WAIT3 */
6942
6943#ifdef HAVE_WAIT4
6944PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006945"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006946Wait for completion of a given child process.");
6947
6948static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006949posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006950{
Victor Stinner8c62be82010-05-06 00:08:46 +00006951 pid_t pid;
6952 int options;
6953 struct rusage ru;
6954 WAIT_TYPE status;
6955 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006956
Victor Stinner4195b5c2012-02-08 23:03:19 +01006957 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006959
Victor Stinner8c62be82010-05-06 00:08:46 +00006960 Py_BEGIN_ALLOW_THREADS
6961 pid = wait4(pid, &status, options, &ru);
6962 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006963
Victor Stinner4195b5c2012-02-08 23:03:19 +01006964 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006965}
6966#endif /* HAVE_WAIT4 */
6967
Ross Lagerwall7807c352011-03-17 20:20:30 +02006968#if defined(HAVE_WAITID) && !defined(__APPLE__)
6969PyDoc_STRVAR(posix_waitid__doc__,
6970"waitid(idtype, id, options) -> waitid_result\n\n\
6971Wait for the completion of one or more child processes.\n\n\
6972idtype can be P_PID, P_PGID or P_ALL.\n\
6973id specifies the pid to wait on.\n\
6974options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6975or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6976Returns either waitid_result or None if WNOHANG is specified and there are\n\
6977no children in a waitable state.");
6978
6979static PyObject *
6980posix_waitid(PyObject *self, PyObject *args)
6981{
6982 PyObject *result;
6983 idtype_t idtype;
6984 id_t id;
6985 int options, res;
6986 siginfo_t si;
6987 si.si_pid = 0;
6988 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6989 return NULL;
6990 Py_BEGIN_ALLOW_THREADS
6991 res = waitid(idtype, id, &si, options);
6992 Py_END_ALLOW_THREADS
6993 if (res == -1)
6994 return posix_error();
6995
6996 if (si.si_pid == 0)
6997 Py_RETURN_NONE;
6998
6999 result = PyStructSequence_New(&WaitidResultType);
7000 if (!result)
7001 return NULL;
7002
7003 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007004 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007005 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7006 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7007 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7008 if (PyErr_Occurred()) {
7009 Py_DECREF(result);
7010 return NULL;
7011 }
7012
7013 return result;
7014}
7015#endif
7016
Guido van Rossumb6775db1994-08-01 11:34:53 +00007017#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007018PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007019"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007020Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007021
Barry Warsaw53699e91996-12-10 23:23:01 +00007022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007023posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007024{
Victor Stinner8c62be82010-05-06 00:08:46 +00007025 pid_t pid;
7026 int options;
7027 WAIT_TYPE status;
7028 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007029
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7031 return NULL;
7032 Py_BEGIN_ALLOW_THREADS
7033 pid = waitpid(pid, &status, options);
7034 Py_END_ALLOW_THREADS
7035 if (pid == -1)
7036 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007037
Victor Stinner8c62be82010-05-06 00:08:46 +00007038 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007039}
7040
Tim Petersab034fa2002-02-01 11:27:43 +00007041#elif defined(HAVE_CWAIT)
7042
7043/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007044PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007045"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007046"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007047
7048static PyObject *
7049posix_waitpid(PyObject *self, PyObject *args)
7050{
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 Py_intptr_t pid;
7052 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007053
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007054 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007055 return NULL;
7056 Py_BEGIN_ALLOW_THREADS
7057 pid = _cwait(&status, pid, options);
7058 Py_END_ALLOW_THREADS
7059 if (pid == -1)
7060 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007061
Victor Stinner8c62be82010-05-06 00:08:46 +00007062 /* shift the status left a byte so this is more like the POSIX waitpid */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007063 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007064}
7065#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007066
Guido van Rossumad0ee831995-03-01 10:34:45 +00007067#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007068PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007069"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007070Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007071
Barry Warsaw53699e91996-12-10 23:23:01 +00007072static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007073posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007074{
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 pid_t pid;
7076 WAIT_TYPE status;
7077 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007078
Victor Stinner8c62be82010-05-06 00:08:46 +00007079 Py_BEGIN_ALLOW_THREADS
7080 pid = wait(&status);
7081 Py_END_ALLOW_THREADS
7082 if (pid == -1)
7083 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007084
Victor Stinner8c62be82010-05-06 00:08:46 +00007085 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007086}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007087#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007088
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007089
Larry Hastings9cf065c2012-06-22 16:30:09 -07007090#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7091PyDoc_STRVAR(readlink__doc__,
7092"readlink(path, *, dir_fd=None) -> path\n\n\
7093Return a string representing the path to which the symbolic link points.\n\
7094\n\
7095If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7096 and path should be relative; path will then be relative to that directory.\n\
7097dir_fd may not be implemented on your platform.\n\
7098 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007099#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007100
Guido van Rossumb6775db1994-08-01 11:34:53 +00007101#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007102
Barry Warsaw53699e91996-12-10 23:23:01 +00007103static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007104posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007105{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007106 path_t path;
7107 int dir_fd = DEFAULT_DIR_FD;
7108 char buffer[MAXPATHLEN];
7109 ssize_t length;
7110 PyObject *return_value = NULL;
7111 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007112
Larry Hastings9cf065c2012-06-22 16:30:09 -07007113 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007114 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007115 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7116 path_converter, &path,
7117#ifdef HAVE_READLINKAT
7118 dir_fd_converter, &dir_fd
7119#else
7120 dir_fd_unavailable, &dir_fd
7121#endif
7122 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007123 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007124
Victor Stinner8c62be82010-05-06 00:08:46 +00007125 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126#ifdef HAVE_READLINKAT
7127 if (dir_fd != DEFAULT_DIR_FD)
7128 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007129 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007130#endif
7131 length = readlink(path.narrow, buffer, sizeof(buffer));
7132 Py_END_ALLOW_THREADS
7133
7134 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007135 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007136 goto exit;
7137 }
7138
7139 if (PyUnicode_Check(path.object))
7140 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7141 else
7142 return_value = PyBytes_FromStringAndSize(buffer, length);
7143exit:
7144 path_cleanup(&path);
7145 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007146}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007147
7148
Guido van Rossumb6775db1994-08-01 11:34:53 +00007149#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007150
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007151
Larry Hastings9cf065c2012-06-22 16:30:09 -07007152#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007153PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007154"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7155Create a symbolic link pointing to src named dst.\n\n\
7156target_is_directory is required on Windows if the target is to be\n\
7157 interpreted as a directory. (On Windows, symlink requires\n\
7158 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7159 target_is_directory is ignored on non-Windows platforms.\n\
7160\n\
7161If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7162 and path should be relative; path will then be relative to that directory.\n\
7163dir_fd may not be implemented on your platform.\n\
7164 If it is unavailable, using it will raise a NotImplementedError.");
7165
7166#if defined(MS_WINDOWS)
7167
7168/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7169static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7170static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007171
Larry Hastings9cf065c2012-06-22 16:30:09 -07007172static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007173check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007174{
7175 HINSTANCE hKernel32;
7176 /* only recheck */
7177 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7178 return 1;
7179 hKernel32 = GetModuleHandleW(L"KERNEL32");
7180 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7181 "CreateSymbolicLinkW");
7182 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7183 "CreateSymbolicLinkA");
7184 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7185}
7186
Victor Stinner31b3b922013-06-05 01:49:17 +02007187/* Remove the last portion of the path */
7188static void
7189_dirnameW(WCHAR *path)
7190{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007191 WCHAR *ptr;
7192
7193 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007194 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007195 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007196 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007197 }
7198 *ptr = 0;
7199}
7200
Victor Stinner31b3b922013-06-05 01:49:17 +02007201/* Remove the last portion of the path */
7202static void
7203_dirnameA(char *path)
7204{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007205 char *ptr;
7206
7207 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007208 for(ptr = path + strlen(path); ptr != path; ptr--) {
7209 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007210 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007211 }
7212 *ptr = 0;
7213}
7214
Victor Stinner31b3b922013-06-05 01:49:17 +02007215/* Is this path absolute? */
7216static int
7217_is_absW(const WCHAR *path)
7218{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007219 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7220
7221}
7222
Victor Stinner31b3b922013-06-05 01:49:17 +02007223/* Is this path absolute? */
7224static int
7225_is_absA(const char *path)
7226{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007227 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7228
7229}
7230
Victor Stinner31b3b922013-06-05 01:49:17 +02007231/* join root and rest with a backslash */
7232static void
7233_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7234{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007235 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007236
Victor Stinner31b3b922013-06-05 01:49:17 +02007237 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007238 wcscpy(dest_path, rest);
7239 return;
7240 }
7241
7242 root_len = wcslen(root);
7243
7244 wcscpy(dest_path, root);
7245 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007246 dest_path[root_len] = L'\\';
7247 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007248 }
7249 wcscpy(dest_path+root_len, rest);
7250}
7251
Victor Stinner31b3b922013-06-05 01:49:17 +02007252/* join root and rest with a backslash */
7253static void
7254_joinA(char *dest_path, const char *root, const char *rest)
7255{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007256 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007257
Victor Stinner31b3b922013-06-05 01:49:17 +02007258 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007259 strcpy(dest_path, rest);
7260 return;
7261 }
7262
7263 root_len = strlen(root);
7264
7265 strcpy(dest_path, root);
7266 if(root_len) {
7267 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007268 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007269 }
7270 strcpy(dest_path+root_len, rest);
7271}
7272
Victor Stinner31b3b922013-06-05 01:49:17 +02007273/* Return True if the path at src relative to dest is a directory */
7274static int
7275_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007276{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007277 WIN32_FILE_ATTRIBUTE_DATA src_info;
7278 WCHAR dest_parent[MAX_PATH];
7279 WCHAR src_resolved[MAX_PATH] = L"";
7280
7281 /* dest_parent = os.path.dirname(dest) */
7282 wcscpy(dest_parent, dest);
7283 _dirnameW(dest_parent);
7284 /* src_resolved = os.path.join(dest_parent, src) */
7285 _joinW(src_resolved, dest_parent, src);
7286 return (
7287 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7288 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7289 );
7290}
7291
Victor Stinner31b3b922013-06-05 01:49:17 +02007292/* Return True if the path at src relative to dest is a directory */
7293static int
7294_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007295{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007296 WIN32_FILE_ATTRIBUTE_DATA src_info;
7297 char dest_parent[MAX_PATH];
7298 char src_resolved[MAX_PATH] = "";
7299
7300 /* dest_parent = os.path.dirname(dest) */
7301 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007302 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007303 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007304 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007305 return (
7306 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7307 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7308 );
7309}
7310
Larry Hastings9cf065c2012-06-22 16:30:09 -07007311#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007312
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007313static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007314posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007315{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007316 path_t src;
7317 path_t dst;
7318 int dir_fd = DEFAULT_DIR_FD;
7319 int target_is_directory = 0;
7320 static char *keywords[] = {"src", "dst", "target_is_directory",
7321 "dir_fd", NULL};
7322 PyObject *return_value;
7323#ifdef MS_WINDOWS
7324 DWORD result;
7325#else
7326 int result;
7327#endif
7328
7329 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01007330 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007331 src.argument_name = "src";
7332 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01007333 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007334 dst.argument_name = "dst";
7335
7336#ifdef MS_WINDOWS
7337 if (!check_CreateSymbolicLink()) {
7338 PyErr_SetString(PyExc_NotImplementedError,
7339 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007340 return NULL;
7341 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007342 if (!win32_can_symlink) {
7343 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007344 return NULL;
7345 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007346#endif
7347
7348 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7349 keywords,
7350 path_converter, &src,
7351 path_converter, &dst,
7352 &target_is_directory,
7353#ifdef HAVE_SYMLINKAT
7354 dir_fd_converter, &dir_fd
7355#else
7356 dir_fd_unavailable, &dir_fd
7357#endif
7358 ))
7359 return NULL;
7360
7361 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7362 PyErr_SetString(PyExc_ValueError,
7363 "symlink: src and dst must be the same type");
7364 return_value = NULL;
7365 goto exit;
7366 }
7367
7368#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007369
Larry Hastings9cf065c2012-06-22 16:30:09 -07007370 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007371 if (dst.wide) {
7372 /* if src is a directory, ensure target_is_directory==1 */
7373 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007374 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7375 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007376 }
7377 else {
7378 /* if src is a directory, ensure target_is_directory==1 */
7379 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007380 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7381 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007382 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007383 Py_END_ALLOW_THREADS
7384
7385 if (!result) {
Larry Hastingsb0827312014-02-09 22:05:19 -08007386 return_value = path_error2(&src, &dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007387 goto exit;
7388 }
7389
7390#else
7391
7392 Py_BEGIN_ALLOW_THREADS
7393#if HAVE_SYMLINKAT
7394 if (dir_fd != DEFAULT_DIR_FD)
7395 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7396 else
7397#endif
7398 result = symlink(src.narrow, dst.narrow);
7399 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#endif
7406
7407 return_value = Py_None;
7408 Py_INCREF(Py_None);
7409 goto exit; /* silence "unused label" warning */
7410exit:
7411 path_cleanup(&src);
7412 path_cleanup(&dst);
7413 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007414}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007415
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007416#endif /* HAVE_SYMLINK */
7417
Larry Hastings9cf065c2012-06-22 16:30:09 -07007418
Brian Curtind40e6f72010-07-08 21:39:08 +00007419#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7420
Brian Curtind40e6f72010-07-08 21:39:08 +00007421static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007422win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007423{
7424 wchar_t *path;
7425 DWORD n_bytes_returned;
7426 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007427 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007428 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007429 HANDLE reparse_point_handle;
7430
7431 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7432 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7433 wchar_t *print_name;
7434
Larry Hastings9cf065c2012-06-22 16:30:09 -07007435 static char *keywords[] = {"path", "dir_fd", NULL};
7436
7437 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7438 &po,
7439 dir_fd_unavailable, &dir_fd
7440 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007441 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007442
Victor Stinnereb5657a2011-09-30 01:44:27 +02007443 path = PyUnicode_AsUnicode(po);
7444 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007445 return NULL;
7446
7447 /* First get a handle to the reparse point */
7448 Py_BEGIN_ALLOW_THREADS
7449 reparse_point_handle = CreateFileW(
7450 path,
7451 0,
7452 0,
7453 0,
7454 OPEN_EXISTING,
7455 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7456 0);
7457 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007458
Brian Curtind40e6f72010-07-08 21:39:08 +00007459 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007460 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007461
Brian Curtind40e6f72010-07-08 21:39:08 +00007462 Py_BEGIN_ALLOW_THREADS
7463 /* New call DeviceIoControl to read the reparse point */
7464 io_result = DeviceIoControl(
7465 reparse_point_handle,
7466 FSCTL_GET_REPARSE_POINT,
7467 0, 0, /* in buffer */
7468 target_buffer, sizeof(target_buffer),
7469 &n_bytes_returned,
7470 0 /* we're not using OVERLAPPED_IO */
7471 );
7472 CloseHandle(reparse_point_handle);
7473 Py_END_ALLOW_THREADS
7474
7475 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007476 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007477
7478 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7479 {
7480 PyErr_SetString(PyExc_ValueError,
7481 "not a symbolic link");
7482 return NULL;
7483 }
Brian Curtin74e45612010-07-09 15:58:59 +00007484 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7485 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7486
7487 result = PyUnicode_FromWideChar(print_name,
7488 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007489 return result;
7490}
7491
7492#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7493
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007494
Larry Hastings605a62d2012-06-24 04:33:36 -07007495static PyStructSequence_Field times_result_fields[] = {
7496 {"user", "user time"},
7497 {"system", "system time"},
7498 {"children_user", "user time of children"},
7499 {"children_system", "system time of children"},
7500 {"elapsed", "elapsed time since an arbitrary point in the past"},
7501 {NULL}
7502};
7503
7504PyDoc_STRVAR(times_result__doc__,
7505"times_result: Result from os.times().\n\n\
7506This object may be accessed either as a tuple of\n\
7507 (user, system, children_user, children_system, elapsed),\n\
7508or via the attributes user, system, children_user, children_system,\n\
7509and elapsed.\n\
7510\n\
7511See os.times for more information.");
7512
7513static PyStructSequence_Desc times_result_desc = {
7514 "times_result", /* name */
7515 times_result__doc__, /* doc */
7516 times_result_fields,
7517 5
7518};
7519
7520static PyTypeObject TimesResultType;
7521
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007522#ifdef MS_WINDOWS
7523#define HAVE_TIMES /* mandatory, for the method table */
7524#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007525
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007526#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007527
7528static PyObject *
7529build_times_result(double user, double system,
7530 double children_user, double children_system,
7531 double elapsed)
7532{
7533 PyObject *value = PyStructSequence_New(&TimesResultType);
7534 if (value == NULL)
7535 return NULL;
7536
7537#define SET(i, field) \
7538 { \
7539 PyObject *o = PyFloat_FromDouble(field); \
7540 if (!o) { \
7541 Py_DECREF(value); \
7542 return NULL; \
7543 } \
7544 PyStructSequence_SET_ITEM(value, i, o); \
7545 } \
7546
7547 SET(0, user);
7548 SET(1, system);
7549 SET(2, children_user);
7550 SET(3, children_system);
7551 SET(4, elapsed);
7552
7553#undef SET
7554
7555 return value;
7556}
7557
7558PyDoc_STRVAR(posix_times__doc__,
7559"times() -> times_result\n\n\
7560Return an object containing floating point numbers indicating process\n\
7561times. The object behaves like a named tuple with these fields:\n\
7562 (utime, stime, cutime, cstime, elapsed_time)");
7563
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007564#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007565static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007566posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007567{
Victor Stinner8c62be82010-05-06 00:08:46 +00007568 FILETIME create, exit, kernel, user;
7569 HANDLE hProc;
7570 hProc = GetCurrentProcess();
7571 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7572 /* The fields of a FILETIME structure are the hi and lo part
7573 of a 64-bit value expressed in 100 nanosecond units.
7574 1e7 is one second in such units; 1e-7 the inverse.
7575 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7576 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007577 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007578 (double)(user.dwHighDateTime*429.4967296 +
7579 user.dwLowDateTime*1e-7),
7580 (double)(kernel.dwHighDateTime*429.4967296 +
7581 kernel.dwLowDateTime*1e-7),
7582 (double)0,
7583 (double)0,
7584 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007585}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02007586#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007587#define NEED_TICKS_PER_SECOND
7588static long ticks_per_second = -1;
7589static PyObject *
7590posix_times(PyObject *self, PyObject *noargs)
7591{
7592 struct tms t;
7593 clock_t c;
7594 errno = 0;
7595 c = times(&t);
7596 if (c == (clock_t) -1)
7597 return posix_error();
7598 return build_times_result(
7599 (double)t.tms_utime / ticks_per_second,
7600 (double)t.tms_stime / ticks_per_second,
7601 (double)t.tms_cutime / ticks_per_second,
7602 (double)t.tms_cstime / ticks_per_second,
7603 (double)c / ticks_per_second);
7604}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007605#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007606
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007607#endif /* HAVE_TIMES */
7608
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007609
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007610#ifdef HAVE_GETSID
7611PyDoc_STRVAR(posix_getsid__doc__,
7612"getsid(pid) -> sid\n\n\
7613Call the system call getsid().");
7614
7615static PyObject *
7616posix_getsid(PyObject *self, PyObject *args)
7617{
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 pid_t pid;
7619 int sid;
7620 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7621 return NULL;
7622 sid = getsid(pid);
7623 if (sid < 0)
7624 return posix_error();
7625 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007626}
7627#endif /* HAVE_GETSID */
7628
7629
Guido van Rossumb6775db1994-08-01 11:34:53 +00007630#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007631PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007632"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007633Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007634
Barry Warsaw53699e91996-12-10 23:23:01 +00007635static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007636posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007637{
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 if (setsid() < 0)
7639 return posix_error();
7640 Py_INCREF(Py_None);
7641 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007642}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007643#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007644
Guido van Rossumb6775db1994-08-01 11:34:53 +00007645#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007646PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007647"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007648Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007649
Barry Warsaw53699e91996-12-10 23:23:01 +00007650static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007651posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007652{
Victor Stinner8c62be82010-05-06 00:08:46 +00007653 pid_t pid;
7654 int pgrp;
7655 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7656 return NULL;
7657 if (setpgid(pid, pgrp) < 0)
7658 return posix_error();
7659 Py_INCREF(Py_None);
7660 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007661}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007662#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007664
Guido van Rossumb6775db1994-08-01 11:34:53 +00007665#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007666PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007667"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007668Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007669
Barry Warsaw53699e91996-12-10 23:23:01 +00007670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007671posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007672{
Victor Stinner8c62be82010-05-06 00:08:46 +00007673 int fd;
7674 pid_t pgid;
7675 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7676 return NULL;
7677 pgid = tcgetpgrp(fd);
7678 if (pgid < 0)
7679 return posix_error();
7680 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007681}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007682#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007683
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007684
Guido van Rossumb6775db1994-08-01 11:34:53 +00007685#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007686PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007687"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007688Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007689
Barry Warsaw53699e91996-12-10 23:23:01 +00007690static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007691posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007692{
Victor Stinner8c62be82010-05-06 00:08:46 +00007693 int fd;
7694 pid_t pgid;
7695 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7696 return NULL;
7697 if (tcsetpgrp(fd, pgid) < 0)
7698 return posix_error();
7699 Py_INCREF(Py_None);
7700 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007701}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007702#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007703
Guido van Rossum687dd131993-05-17 08:34:16 +00007704/* Functions acting on file descriptors */
7705
Victor Stinnerdaf45552013-08-28 00:53:59 +02007706#ifdef O_CLOEXEC
7707extern int _Py_open_cloexec_works;
7708#endif
7709
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007710PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007711"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7712Open a file for low level IO. Returns a file handle (integer).\n\
7713\n\
7714If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7715 and path should be relative; path will then be relative to that directory.\n\
7716dir_fd may not be implemented on your platform.\n\
7717 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007718
Barry Warsaw53699e91996-12-10 23:23:01 +00007719static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007720posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007721{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007722 path_t path;
7723 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007724 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007725 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007726 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007727 PyObject *return_value = NULL;
7728 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Victor Stinnerdaf45552013-08-28 00:53:59 +02007729#ifdef O_CLOEXEC
7730 int *atomic_flag_works = &_Py_open_cloexec_works;
7731#elif !defined(MS_WINDOWS)
7732 int *atomic_flag_works = NULL;
7733#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007734
Larry Hastings9cf065c2012-06-22 16:30:09 -07007735 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007736 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007737 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7738 path_converter, &path,
7739 &flags, &mode,
7740#ifdef HAVE_OPENAT
7741 dir_fd_converter, &dir_fd
7742#else
7743 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007744#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007745 ))
7746 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007747
Victor Stinnerdaf45552013-08-28 00:53:59 +02007748#ifdef MS_WINDOWS
7749 flags |= O_NOINHERIT;
7750#elif defined(O_CLOEXEC)
7751 flags |= O_CLOEXEC;
7752#endif
7753
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007755#ifdef MS_WINDOWS
7756 if (path.wide)
7757 fd = _wopen(path.wide, flags, mode);
7758 else
7759#endif
7760#ifdef HAVE_OPENAT
7761 if (dir_fd != DEFAULT_DIR_FD)
7762 fd = openat(dir_fd, path.narrow, flags, mode);
7763 else
7764#endif
7765 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007767
Larry Hastings9cf065c2012-06-22 16:30:09 -07007768 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007769 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007770 goto exit;
7771 }
7772
Victor Stinnerdaf45552013-08-28 00:53:59 +02007773#ifndef MS_WINDOWS
7774 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7775 close(fd);
7776 goto exit;
7777 }
7778#endif
7779
Larry Hastings9cf065c2012-06-22 16:30:09 -07007780 return_value = PyLong_FromLong((long)fd);
7781
7782exit:
7783 path_cleanup(&path);
7784 return return_value;
7785}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007786
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007787PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007788"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007789Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007790
Benjamin Peterson932bba32014-02-11 10:16:16 -05007791/*
7792The underscore at end of function name avoids a name clash with the libc
7793function posix_close.
7794*/
Barry Warsaw53699e91996-12-10 23:23:01 +00007795static PyObject *
Benjamin Peterson932bba32014-02-11 10:16:16 -05007796posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007797{
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 int fd, res;
7799 if (!PyArg_ParseTuple(args, "i:close", &fd))
7800 return NULL;
7801 if (!_PyVerify_fd(fd))
7802 return posix_error();
7803 Py_BEGIN_ALLOW_THREADS
7804 res = close(fd);
7805 Py_END_ALLOW_THREADS
7806 if (res < 0)
7807 return posix_error();
7808 Py_INCREF(Py_None);
7809 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007810}
7811
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007812
Victor Stinner8c62be82010-05-06 00:08:46 +00007813PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007814"closerange(fd_low, fd_high)\n\n\
7815Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7816
7817static PyObject *
7818posix_closerange(PyObject *self, PyObject *args)
7819{
Victor Stinner8c62be82010-05-06 00:08:46 +00007820 int fd_from, fd_to, i;
7821 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7822 return NULL;
7823 Py_BEGIN_ALLOW_THREADS
7824 for (i = fd_from; i < fd_to; i++)
7825 if (_PyVerify_fd(i))
7826 close(i);
7827 Py_END_ALLOW_THREADS
7828 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007829}
7830
7831
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007832PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007833"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007834Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007835
Barry Warsaw53699e91996-12-10 23:23:01 +00007836static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007837posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007838{
Victor Stinner8c62be82010-05-06 00:08:46 +00007839 int fd;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007840
Victor Stinner8c62be82010-05-06 00:08:46 +00007841 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7842 return NULL;
Tim Golden23005082013-10-25 11:22:37 +01007843
Victor Stinnerdaf45552013-08-28 00:53:59 +02007844 fd = _Py_dup(fd);
7845 if (fd == -1)
7846 return NULL;
7847
Victor Stinner8c62be82010-05-06 00:08:46 +00007848 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007849}
7850
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007851
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007852PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007853"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007854Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007855
Barry Warsaw53699e91996-12-10 23:23:01 +00007856static PyObject *
Victor Stinnerdaf45552013-08-28 00:53:59 +02007857posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007858{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007859 static char *keywords[] = {"fd", "fd2", "inheritable", NULL};
7860 int fd, fd2;
7861 int inheritable = 1;
7862 int res;
7863#if defined(HAVE_DUP3) && \
7864 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7865 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7866 int dup3_works = -1;
7867#endif
7868
7869 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords,
7870 &fd, &fd2, &inheritable))
Victor Stinner8c62be82010-05-06 00:08:46 +00007871 return NULL;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007872
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 if (!_PyVerify_fd_dup2(fd, fd2))
7874 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007875
7876#ifdef MS_WINDOWS
7877 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007878 res = dup2(fd, fd2);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007879 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007880 if (res < 0)
7881 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007882
7883 /* Character files like console cannot be make non-inheritable */
7884 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7885 close(fd2);
7886 return NULL;
7887 }
7888
7889#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7890 Py_BEGIN_ALLOW_THREADS
7891 if (!inheritable)
7892 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7893 else
7894 res = dup2(fd, fd2);
7895 Py_END_ALLOW_THREADS
7896 if (res < 0)
7897 return posix_error();
7898
7899#else
7900
7901#ifdef HAVE_DUP3
7902 if (!inheritable && dup3_works != 0) {
7903 Py_BEGIN_ALLOW_THREADS
7904 res = dup3(fd, fd2, O_CLOEXEC);
7905 Py_END_ALLOW_THREADS
7906 if (res < 0) {
7907 if (dup3_works == -1)
7908 dup3_works = (errno != ENOSYS);
7909 if (dup3_works)
7910 return posix_error();
7911 }
7912 }
7913
7914 if (inheritable || dup3_works == 0)
7915 {
7916#endif
7917 Py_BEGIN_ALLOW_THREADS
7918 res = dup2(fd, fd2);
7919 Py_END_ALLOW_THREADS
7920 if (res < 0)
7921 return posix_error();
7922
7923 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7924 close(fd2);
7925 return NULL;
7926 }
7927#ifdef HAVE_DUP3
7928 }
7929#endif
7930
7931#endif
7932
Victor Stinner8c62be82010-05-06 00:08:46 +00007933 Py_INCREF(Py_None);
7934 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007935}
7936
Ross Lagerwall7807c352011-03-17 20:20:30 +02007937#ifdef HAVE_LOCKF
7938PyDoc_STRVAR(posix_lockf__doc__,
7939"lockf(fd, cmd, len)\n\n\
7940Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7941fd is an open file descriptor.\n\
7942cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7943F_TEST.\n\
7944len specifies the section of the file to lock.");
7945
7946static PyObject *
7947posix_lockf(PyObject *self, PyObject *args)
7948{
7949 int fd, cmd, res;
7950 off_t len;
7951 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7952 &fd, &cmd, _parse_off_t, &len))
7953 return NULL;
7954
7955 Py_BEGIN_ALLOW_THREADS
7956 res = lockf(fd, cmd, len);
7957 Py_END_ALLOW_THREADS
7958
7959 if (res < 0)
7960 return posix_error();
7961
7962 Py_RETURN_NONE;
7963}
7964#endif
7965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007966
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007967PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007968"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007969Set the current position of a file descriptor.\n\
7970Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007971
Barry Warsaw53699e91996-12-10 23:23:01 +00007972static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007973posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007974{
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 int fd, how;
Victor Stinner14b9b112013-06-25 00:37:25 +02007976#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007977 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007978#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007979 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007980#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007981 PyObject *posobj;
7982 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007984#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7986 switch (how) {
7987 case 0: how = SEEK_SET; break;
7988 case 1: how = SEEK_CUR; break;
7989 case 2: how = SEEK_END; break;
7990 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007991#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007992
Ross Lagerwall8e749672011-03-17 21:54:07 +02007993#if !defined(HAVE_LARGEFILE_SUPPORT)
7994 pos = PyLong_AsLong(posobj);
7995#else
7996 pos = PyLong_AsLongLong(posobj);
7997#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007998 if (PyErr_Occurred())
7999 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008000
Victor Stinner8c62be82010-05-06 00:08:46 +00008001 if (!_PyVerify_fd(fd))
8002 return posix_error();
8003 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008004#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008005 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00008006#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00008008#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008009 Py_END_ALLOW_THREADS
8010 if (res < 0)
8011 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008012
8013#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008015#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008016 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008017#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008018}
8019
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008020
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008021PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008022"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008023Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008024
Barry Warsaw53699e91996-12-10 23:23:01 +00008025static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008026posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008027{
Victor Stinner8c62be82010-05-06 00:08:46 +00008028 int fd, size;
8029 Py_ssize_t n;
8030 PyObject *buffer;
8031 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
8032 return NULL;
8033 if (size < 0) {
8034 errno = EINVAL;
8035 return posix_error();
8036 }
8037 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8038 if (buffer == NULL)
8039 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00008040 if (!_PyVerify_fd(fd)) {
8041 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00008042 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00008043 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008044 Py_BEGIN_ALLOW_THREADS
8045 n = read(fd, PyBytes_AS_STRING(buffer), size);
8046 Py_END_ALLOW_THREADS
8047 if (n < 0) {
8048 Py_DECREF(buffer);
8049 return posix_error();
8050 }
8051 if (n != size)
8052 _PyBytes_Resize(&buffer, n);
8053 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008054}
8055
Ross Lagerwall7807c352011-03-17 20:20:30 +02008056#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8057 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008058static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008059iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8060{
8061 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008062 Py_ssize_t blen, total = 0;
8063
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008064 *iov = PyMem_New(struct iovec, cnt);
8065 if (*iov == NULL) {
8066 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008067 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008068 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008069
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008070 *buf = PyMem_New(Py_buffer, cnt);
8071 if (*buf == NULL) {
8072 PyMem_Del(*iov);
8073 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008074 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008075 }
8076
8077 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008078 PyObject *item = PySequence_GetItem(seq, i);
8079 if (item == NULL)
8080 goto fail;
8081 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8082 Py_DECREF(item);
8083 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008084 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008085 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008086 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008087 blen = (*buf)[i].len;
8088 (*iov)[i].iov_len = blen;
8089 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008090 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008091 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008092
8093fail:
8094 PyMem_Del(*iov);
8095 for (j = 0; j < i; j++) {
8096 PyBuffer_Release(&(*buf)[j]);
8097 }
8098 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008099 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008100}
8101
8102static void
8103iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8104{
8105 int i;
8106 PyMem_Del(iov);
8107 for (i = 0; i < cnt; i++) {
8108 PyBuffer_Release(&buf[i]);
8109 }
8110 PyMem_Del(buf);
8111}
8112#endif
8113
Ross Lagerwall7807c352011-03-17 20:20:30 +02008114#ifdef HAVE_READV
8115PyDoc_STRVAR(posix_readv__doc__,
8116"readv(fd, buffers) -> bytesread\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008117Read from a file descriptor fd into a number of mutable, bytes-like\n\
8118objects (\"buffers\"). readv will transfer data into each buffer\n\
8119until it is full and then move on to the next buffer in the sequence\n\
8120to hold the rest of the data.\n\n\
8121readv returns the total number of bytes read (which may be less than\n\
8122the total capacity of all the buffers.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008123
8124static PyObject *
8125posix_readv(PyObject *self, PyObject *args)
8126{
8127 int fd, cnt;
8128 Py_ssize_t n;
8129 PyObject *seq;
8130 struct iovec *iov;
8131 Py_buffer *buf;
8132
8133 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8134 return NULL;
8135 if (!PySequence_Check(seq)) {
8136 PyErr_SetString(PyExc_TypeError,
8137 "readv() arg 2 must be a sequence");
8138 return NULL;
8139 }
8140 cnt = PySequence_Size(seq);
8141
Victor Stinner57ddf782014-01-08 15:21:28 +01008142 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE) < 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008143 return NULL;
8144
8145 Py_BEGIN_ALLOW_THREADS
8146 n = readv(fd, iov, cnt);
8147 Py_END_ALLOW_THREADS
8148
8149 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008150 if (n < 0)
8151 return posix_error();
8152
Ross Lagerwall7807c352011-03-17 20:20:30 +02008153 return PyLong_FromSsize_t(n);
8154}
8155#endif
8156
8157#ifdef HAVE_PREAD
8158PyDoc_STRVAR(posix_pread__doc__,
8159"pread(fd, buffersize, offset) -> string\n\n\
8160Read from a file descriptor, fd, at a position of offset. It will read up\n\
8161to buffersize number of bytes. The file offset remains unchanged.");
8162
8163static PyObject *
8164posix_pread(PyObject *self, PyObject *args)
8165{
8166 int fd, size;
8167 off_t offset;
8168 Py_ssize_t n;
8169 PyObject *buffer;
8170 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8171 return NULL;
8172
8173 if (size < 0) {
8174 errno = EINVAL;
8175 return posix_error();
8176 }
8177 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8178 if (buffer == NULL)
8179 return NULL;
8180 if (!_PyVerify_fd(fd)) {
8181 Py_DECREF(buffer);
8182 return posix_error();
8183 }
8184 Py_BEGIN_ALLOW_THREADS
8185 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8186 Py_END_ALLOW_THREADS
8187 if (n < 0) {
8188 Py_DECREF(buffer);
8189 return posix_error();
8190 }
8191 if (n != size)
8192 _PyBytes_Resize(&buffer, n);
8193 return buffer;
8194}
8195#endif
8196
8197PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008198"write(fd, data) -> byteswritten\n\n\
8199Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008200
8201static PyObject *
8202posix_write(PyObject *self, PyObject *args)
8203{
8204 Py_buffer pbuf;
8205 int fd;
8206 Py_ssize_t size, len;
8207
8208 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8209 return NULL;
8210 if (!_PyVerify_fd(fd)) {
8211 PyBuffer_Release(&pbuf);
8212 return posix_error();
8213 }
8214 len = pbuf.len;
8215 Py_BEGIN_ALLOW_THREADS
Victor Stinner14b9b112013-06-25 00:37:25 +02008216#ifdef MS_WINDOWS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008217 if (len > INT_MAX)
8218 len = INT_MAX;
8219 size = write(fd, pbuf.buf, (int)len);
8220#else
8221 size = write(fd, pbuf.buf, len);
8222#endif
8223 Py_END_ALLOW_THREADS
8224 PyBuffer_Release(&pbuf);
8225 if (size < 0)
8226 return posix_error();
8227 return PyLong_FromSsize_t(size);
8228}
8229
8230#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008231PyDoc_STRVAR(posix_sendfile__doc__,
8232"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8233sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8234 -> byteswritten\n\
8235Copy nbytes bytes from file descriptor in to file descriptor out.");
8236
8237static PyObject *
8238posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8239{
8240 int in, out;
8241 Py_ssize_t ret;
8242 off_t offset;
8243
8244#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8245#ifndef __APPLE__
8246 Py_ssize_t len;
8247#endif
8248 PyObject *headers = NULL, *trailers = NULL;
8249 Py_buffer *hbuf, *tbuf;
8250 off_t sbytes;
8251 struct sf_hdtr sf;
8252 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008253 static char *keywords[] = {"out", "in",
8254 "offset", "count",
8255 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008256
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008257 sf.headers = NULL;
8258 sf.trailers = NULL;
8259
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008260#ifdef __APPLE__
8261 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008262 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008263#else
8264 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008265 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008266#endif
8267 &headers, &trailers, &flags))
8268 return NULL;
8269 if (headers != NULL) {
8270 if (!PySequence_Check(headers)) {
8271 PyErr_SetString(PyExc_TypeError,
8272 "sendfile() headers must be a sequence or None");
8273 return NULL;
8274 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008275 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008276 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008277 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008278 (i = iov_setup(&(sf.headers), &hbuf,
8279 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008280 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008281#ifdef __APPLE__
8282 sbytes += i;
8283#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008284 }
8285 }
8286 if (trailers != NULL) {
8287 if (!PySequence_Check(trailers)) {
8288 PyErr_SetString(PyExc_TypeError,
8289 "sendfile() trailers must be a sequence or None");
8290 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.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008294 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008295 (i = iov_setup(&(sf.trailers), &tbuf,
8296 trailers, sf.trl_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
8304 Py_BEGIN_ALLOW_THREADS
8305#ifdef __APPLE__
8306 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8307#else
8308 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8309#endif
8310 Py_END_ALLOW_THREADS
8311
8312 if (sf.headers != NULL)
8313 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8314 if (sf.trailers != NULL)
8315 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8316
8317 if (ret < 0) {
8318 if ((errno == EAGAIN) || (errno == EBUSY)) {
8319 if (sbytes != 0) {
8320 // some data has been sent
8321 goto done;
8322 }
8323 else {
8324 // no data has been sent; upper application is supposed
8325 // to retry on EAGAIN or EBUSY
8326 return posix_error();
8327 }
8328 }
8329 return posix_error();
8330 }
8331 goto done;
8332
8333done:
8334 #if !defined(HAVE_LARGEFILE_SUPPORT)
8335 return Py_BuildValue("l", sbytes);
8336 #else
8337 return Py_BuildValue("L", sbytes);
8338 #endif
8339
8340#else
8341 Py_ssize_t count;
8342 PyObject *offobj;
8343 static char *keywords[] = {"out", "in",
8344 "offset", "count", NULL};
8345 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8346 keywords, &out, &in, &offobj, &count))
8347 return NULL;
8348#ifdef linux
8349 if (offobj == Py_None) {
8350 Py_BEGIN_ALLOW_THREADS
8351 ret = sendfile(out, in, NULL, count);
8352 Py_END_ALLOW_THREADS
8353 if (ret < 0)
8354 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008355 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008356 }
8357#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008358 if (!_parse_off_t(offobj, &offset))
8359 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008360 Py_BEGIN_ALLOW_THREADS
8361 ret = sendfile(out, in, &offset, count);
8362 Py_END_ALLOW_THREADS
8363 if (ret < 0)
8364 return posix_error();
8365 return Py_BuildValue("n", ret);
8366#endif
8367}
8368#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008369
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008370PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008371"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008372Like stat(), but for an open file descriptor.\n\
8373Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008374
Barry Warsaw53699e91996-12-10 23:23:01 +00008375static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008376posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008377{
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 int fd;
8379 STRUCT_STAT st;
8380 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008381 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008382 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008383 Py_BEGIN_ALLOW_THREADS
8384 res = FSTAT(fd, &st);
8385 Py_END_ALLOW_THREADS
8386 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008387#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008388 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008389#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008390 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008391#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008392 }
Tim Peters5aa91602002-01-30 05:46:57 +00008393
Victor Stinner4195b5c2012-02-08 23:03:19 +01008394 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008395}
8396
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008397PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008398"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008399Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008400connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008401
8402static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008403posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008404{
Victor Stinner8c62be82010-05-06 00:08:46 +00008405 int fd;
8406 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8407 return NULL;
8408 if (!_PyVerify_fd(fd))
8409 return PyBool_FromLong(0);
8410 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008411}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008412
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008413#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008414PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008415"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008416Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008417
Barry Warsaw53699e91996-12-10 23:23:01 +00008418static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008419posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008420{
Victor Stinner8c62be82010-05-06 00:08:46 +00008421 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008422#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008423 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008424 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008425 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008426#else
8427 int res;
8428#endif
8429
8430#ifdef MS_WINDOWS
8431 attr.nLength = sizeof(attr);
8432 attr.lpSecurityDescriptor = NULL;
8433 attr.bInheritHandle = FALSE;
8434
8435 Py_BEGIN_ALLOW_THREADS
8436 ok = CreatePipe(&read, &write, &attr, 0);
8437 if (ok) {
8438 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8439 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8440 if (fds[0] == -1 || fds[1] == -1) {
8441 CloseHandle(read);
8442 CloseHandle(write);
8443 ok = 0;
8444 }
8445 }
8446 Py_END_ALLOW_THREADS
8447
Victor Stinner8c62be82010-05-06 00:08:46 +00008448 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008449 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008450#else
8451
8452#ifdef HAVE_PIPE2
8453 Py_BEGIN_ALLOW_THREADS
8454 res = pipe2(fds, O_CLOEXEC);
8455 Py_END_ALLOW_THREADS
8456
8457 if (res != 0 && errno == ENOSYS)
8458 {
8459#endif
8460 Py_BEGIN_ALLOW_THREADS
8461 res = pipe(fds);
8462 Py_END_ALLOW_THREADS
8463
8464 if (res == 0) {
8465 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8466 close(fds[0]);
8467 close(fds[1]);
8468 return NULL;
8469 }
8470 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8471 close(fds[0]);
8472 close(fds[1]);
8473 return NULL;
8474 }
8475 }
8476#ifdef HAVE_PIPE2
8477 }
8478#endif
8479
8480 if (res != 0)
8481 return PyErr_SetFromErrno(PyExc_OSError);
8482#endif /* !MS_WINDOWS */
8483 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008484}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008485#endif /* HAVE_PIPE */
8486
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008487#ifdef HAVE_PIPE2
8488PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008489"pipe2(flags) -> (read_end, write_end)\n\n\
8490Create a pipe with flags set atomically.\n\
8491flags can be constructed by ORing together one or more of these values:\n\
8492O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008493");
8494
8495static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008496posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008497{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008498 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008499 int fds[2];
8500 int res;
8501
Serhiy Storchaka78980432013-01-15 01:12:17 +02008502 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008503 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008504 return NULL;
8505
8506 res = pipe2(fds, flags);
8507 if (res != 0)
8508 return posix_error();
8509 return Py_BuildValue("(ii)", fds[0], fds[1]);
8510}
8511#endif /* HAVE_PIPE2 */
8512
Ross Lagerwall7807c352011-03-17 20:20:30 +02008513#ifdef HAVE_WRITEV
8514PyDoc_STRVAR(posix_writev__doc__,
8515"writev(fd, buffers) -> byteswritten\n\n\
Benjamin Petersone83ed432014-01-18 22:54:59 -05008516Write the contents of *buffers* to file descriptor *fd*. *buffers*\n\
8517must be a sequence of bytes-like objects.\n\n\
8518writev writes the contents of each object to the file descriptor\n\
8519and returns the total number of bytes written.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008520
8521static PyObject *
8522posix_writev(PyObject *self, PyObject *args)
8523{
8524 int fd, cnt;
8525 Py_ssize_t res;
8526 PyObject *seq;
8527 struct iovec *iov;
8528 Py_buffer *buf;
8529 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8530 return NULL;
8531 if (!PySequence_Check(seq)) {
8532 PyErr_SetString(PyExc_TypeError,
8533 "writev() arg 2 must be a sequence");
8534 return NULL;
8535 }
8536 cnt = PySequence_Size(seq);
8537
Victor Stinner57ddf782014-01-08 15:21:28 +01008538 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008539 return NULL;
8540 }
8541
8542 Py_BEGIN_ALLOW_THREADS
8543 res = writev(fd, iov, cnt);
8544 Py_END_ALLOW_THREADS
8545
8546 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008547 if (res < 0)
8548 return posix_error();
8549
Ross Lagerwall7807c352011-03-17 20:20:30 +02008550 return PyLong_FromSsize_t(res);
8551}
8552#endif
8553
8554#ifdef HAVE_PWRITE
8555PyDoc_STRVAR(posix_pwrite__doc__,
8556"pwrite(fd, string, offset) -> byteswritten\n\n\
8557Write string to a file descriptor, fd, from offset, leaving the file\n\
8558offset unchanged.");
8559
8560static PyObject *
8561posix_pwrite(PyObject *self, PyObject *args)
8562{
8563 Py_buffer pbuf;
8564 int fd;
8565 off_t offset;
8566 Py_ssize_t size;
8567
8568 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8569 return NULL;
8570
8571 if (!_PyVerify_fd(fd)) {
8572 PyBuffer_Release(&pbuf);
8573 return posix_error();
8574 }
8575 Py_BEGIN_ALLOW_THREADS
8576 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8577 Py_END_ALLOW_THREADS
8578 PyBuffer_Release(&pbuf);
8579 if (size < 0)
8580 return posix_error();
8581 return PyLong_FromSsize_t(size);
8582}
8583#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008584
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008585#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008586PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008587"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8588Create a FIFO (a POSIX named pipe).\n\
8589\n\
8590If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8591 and path should be relative; path will then be relative to that directory.\n\
8592dir_fd may not be implemented on your platform.\n\
8593 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008594
Barry Warsaw53699e91996-12-10 23:23:01 +00008595static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008596posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008597{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008598 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008599 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008600 int dir_fd = DEFAULT_DIR_FD;
8601 int result;
8602 PyObject *return_value = NULL;
8603 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8604
8605 memset(&path, 0, sizeof(path));
8606 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8607 path_converter, &path,
8608 &mode,
8609#ifdef HAVE_MKFIFOAT
8610 dir_fd_converter, &dir_fd
8611#else
8612 dir_fd_unavailable, &dir_fd
8613#endif
8614 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008615 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008616
Victor Stinner8c62be82010-05-06 00:08:46 +00008617 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008618#ifdef HAVE_MKFIFOAT
8619 if (dir_fd != DEFAULT_DIR_FD)
8620 result = mkfifoat(dir_fd, path.narrow, mode);
8621 else
8622#endif
8623 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008624 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008625
8626 if (result < 0) {
8627 return_value = posix_error();
8628 goto exit;
8629 }
8630
8631 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008632 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008633
8634exit:
8635 path_cleanup(&path);
8636 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008637}
8638#endif
8639
Neal Norwitz11690112002-07-30 01:08:28 +00008640#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008641PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008642"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008643Create a filesystem node (file, device special file or named pipe)\n\
8644named filename. mode specifies both the permissions to use and the\n\
8645type of node to be created, being combined (bitwise OR) with one of\n\
8646S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008647device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008648os.makedev()), otherwise it is ignored.\n\
8649\n\
8650If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8651 and path should be relative; path will then be relative to that directory.\n\
8652dir_fd may not be implemented on your platform.\n\
8653 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008654
8655
8656static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008657posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008658{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008659 path_t path;
8660 int mode = 0666;
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008661 dev_t device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008662 int dir_fd = DEFAULT_DIR_FD;
8663 int result;
8664 PyObject *return_value = NULL;
8665 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8666
8667 memset(&path, 0, sizeof(path));
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008668 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|iO&$O&:mknod", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008669 path_converter, &path,
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008670 &mode, _Py_Dev_Converter, &device,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008671#ifdef HAVE_MKNODAT
8672 dir_fd_converter, &dir_fd
8673#else
8674 dir_fd_unavailable, &dir_fd
8675#endif
8676 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008677 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008678
Victor Stinner8c62be82010-05-06 00:08:46 +00008679 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008680#ifdef HAVE_MKNODAT
8681 if (dir_fd != DEFAULT_DIR_FD)
8682 result = mknodat(dir_fd, path.narrow, mode, device);
8683 else
8684#endif
8685 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008686 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008687
8688 if (result < 0) {
8689 return_value = posix_error();
8690 goto exit;
8691 }
8692
8693 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008695
Larry Hastings9cf065c2012-06-22 16:30:09 -07008696exit:
8697 path_cleanup(&path);
8698 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008699}
8700#endif
8701
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008702#ifdef HAVE_DEVICE_MACROS
8703PyDoc_STRVAR(posix_major__doc__,
8704"major(device) -> major number\n\
8705Extracts a device major number from a raw device number.");
8706
8707static PyObject *
8708posix_major(PyObject *self, PyObject *args)
8709{
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008710 dev_t device;
8711 if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00008712 return NULL;
8713 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008714}
8715
8716PyDoc_STRVAR(posix_minor__doc__,
8717"minor(device) -> minor number\n\
8718Extracts a device minor number from a raw device number.");
8719
8720static PyObject *
8721posix_minor(PyObject *self, PyObject *args)
8722{
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008723 dev_t device;
8724 if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00008725 return NULL;
8726 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008727}
8728
8729PyDoc_STRVAR(posix_makedev__doc__,
8730"makedev(major, minor) -> device number\n\
8731Composes a raw device number from the major and minor device numbers.");
8732
8733static PyObject *
8734posix_makedev(PyObject *self, PyObject *args)
8735{
Victor Stinner8c62be82010-05-06 00:08:46 +00008736 int major, minor;
8737 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8738 return NULL;
Serhiy Storchakab2653b32015-01-18 11:12:11 +02008739 return _PyLong_FromDev(makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008740}
8741#endif /* device macros */
8742
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008743
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008744#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008745PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008746"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008747Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008748
Barry Warsaw53699e91996-12-10 23:23:01 +00008749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008750posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008751{
Victor Stinner8c62be82010-05-06 00:08:46 +00008752 int fd;
8753 off_t length;
8754 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008755
Ross Lagerwall7807c352011-03-17 20:20:30 +02008756 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008757 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008758
Victor Stinner8c62be82010-05-06 00:08:46 +00008759 Py_BEGIN_ALLOW_THREADS
8760 res = ftruncate(fd, length);
8761 Py_END_ALLOW_THREADS
8762 if (res < 0)
8763 return posix_error();
8764 Py_INCREF(Py_None);
8765 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008766}
8767#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008768
Ross Lagerwall7807c352011-03-17 20:20:30 +02008769#ifdef HAVE_TRUNCATE
8770PyDoc_STRVAR(posix_truncate__doc__,
8771"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008772Truncate the file given by path to length bytes.\n\
8773On some platforms, path may also be specified as an open file descriptor.\n\
8774 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008775
8776static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008777posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008778{
Georg Brandl306336b2012-06-24 12:55:33 +02008779 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008780 off_t length;
8781 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008782 PyObject *result = NULL;
8783 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008784
Georg Brandl306336b2012-06-24 12:55:33 +02008785 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008786 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008787#ifdef HAVE_FTRUNCATE
8788 path.allow_fd = 1;
8789#endif
8790 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8791 path_converter, &path,
8792 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008793 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008794
8795 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008796#ifdef HAVE_FTRUNCATE
8797 if (path.fd != -1)
8798 res = ftruncate(path.fd, length);
8799 else
8800#endif
8801 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008802 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008803 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008804 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008805 else {
8806 Py_INCREF(Py_None);
8807 result = Py_None;
8808 }
8809 path_cleanup(&path);
8810 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008811}
8812#endif
8813
Victor Stinnerd6b17692014-09-30 12:20:05 +02008814/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8815 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8816 defined, which is the case in Python on AIX. AIX bug report:
8817 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8818#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8819# define POSIX_FADVISE_AIX_BUG
8820#endif
8821
8822#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008823PyDoc_STRVAR(posix_posix_fallocate__doc__,
8824"posix_fallocate(fd, offset, len)\n\n\
8825Ensures that enough disk space is allocated for the file specified by fd\n\
8826starting from offset and continuing for len bytes.");
8827
8828static PyObject *
8829posix_posix_fallocate(PyObject *self, PyObject *args)
8830{
8831 off_t len, offset;
8832 int res, fd;
8833
8834 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8835 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8836 return NULL;
8837
8838 Py_BEGIN_ALLOW_THREADS
8839 res = posix_fallocate(fd, offset, len);
8840 Py_END_ALLOW_THREADS
8841 if (res != 0) {
8842 errno = res;
8843 return posix_error();
8844 }
8845 Py_RETURN_NONE;
8846}
8847#endif
8848
Victor Stinnerd6b17692014-09-30 12:20:05 +02008849#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008850PyDoc_STRVAR(posix_posix_fadvise__doc__,
8851"posix_fadvise(fd, offset, len, advice)\n\n\
8852Announces an intention to access data in a specific pattern thus allowing\n\
8853the kernel to make optimizations.\n\
8854The advice applies to the region of the file specified by fd starting at\n\
8855offset and continuing for len bytes.\n\
8856advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8857POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8858POSIX_FADV_DONTNEED.");
8859
8860static PyObject *
8861posix_posix_fadvise(PyObject *self, PyObject *args)
8862{
8863 off_t len, offset;
8864 int res, fd, advice;
8865
8866 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8867 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8868 return NULL;
8869
8870 Py_BEGIN_ALLOW_THREADS
8871 res = posix_fadvise(fd, offset, len, advice);
8872 Py_END_ALLOW_THREADS
8873 if (res != 0) {
8874 errno = res;
8875 return posix_error();
8876 }
8877 Py_RETURN_NONE;
8878}
8879#endif
8880
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008881#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008882PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008883"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008884Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008885
Fred Drake762e2061999-08-26 17:23:54 +00008886/* Save putenv() parameters as values here, so we can collect them when they
8887 * get re-set with another call for the same key. */
8888static PyObject *posix_putenv_garbage;
8889
Tim Peters5aa91602002-01-30 05:46:57 +00008890static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008891posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008892{
Victor Stinner84ae1182010-05-06 22:05:07 +00008893 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008894#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008895 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008896 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008897
Victor Stinner8c62be82010-05-06 00:08:46 +00008898 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008899 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008900 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008901 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008902
Victor Stinner65170952011-11-22 22:16:17 +01008903 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008904 if (newstr == NULL) {
8905 PyErr_NoMemory();
8906 goto error;
8907 }
Victor Stinner65170952011-11-22 22:16:17 +01008908 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8909 PyErr_Format(PyExc_ValueError,
8910 "the environment variable is longer than %u characters",
8911 _MAX_ENV);
8912 goto error;
8913 }
8914
Victor Stinner8c62be82010-05-06 00:08:46 +00008915 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008916 if (newenv == NULL)
8917 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008918 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008919 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008920 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008921 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008922#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008923 PyObject *os1, *os2;
8924 char *s1, *s2;
8925 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008926
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008927 if (!PyArg_ParseTuple(args,
8928 "O&O&:putenv",
8929 PyUnicode_FSConverter, &os1,
8930 PyUnicode_FSConverter, &os2))
8931 return NULL;
8932 s1 = PyBytes_AsString(os1);
8933 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008934
Victor Stinner65170952011-11-22 22:16:17 +01008935 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008936 if (newstr == NULL) {
8937 PyErr_NoMemory();
8938 goto error;
8939 }
8940
Victor Stinner8c62be82010-05-06 00:08:46 +00008941 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008942 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008943 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008944 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008945 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008946#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008947
Victor Stinner8c62be82010-05-06 00:08:46 +00008948 /* Install the first arg and newstr in posix_putenv_garbage;
8949 * this will cause previous value to be collected. This has to
8950 * happen after the real putenv() call because the old value
8951 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008952 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008953 /* really not much we can do; just leak */
8954 PyErr_Clear();
8955 }
8956 else {
8957 Py_DECREF(newstr);
8958 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008959
Martin v. Löwis011e8422009-05-05 04:43:17 +00008960#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008961 Py_DECREF(os1);
8962 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008963#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008964 Py_RETURN_NONE;
8965
8966error:
8967#ifndef MS_WINDOWS
8968 Py_DECREF(os1);
8969 Py_DECREF(os2);
8970#endif
8971 Py_XDECREF(newstr);
8972 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008973}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008974#endif /* putenv */
8975
Guido van Rossumc524d952001-10-19 01:31:59 +00008976#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008977PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008978"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008979Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008980
8981static PyObject *
8982posix_unsetenv(PyObject *self, PyObject *args)
8983{
Victor Stinner65170952011-11-22 22:16:17 +01008984 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008985#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008986 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008987#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008988
8989 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008990
Victor Stinner65170952011-11-22 22:16:17 +01008991 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008992 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008993
Victor Stinner984890f2011-11-24 13:53:38 +01008994#ifdef HAVE_BROKEN_UNSETENV
8995 unsetenv(PyBytes_AS_STRING(name));
8996#else
Victor Stinner65170952011-11-22 22:16:17 +01008997 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008998 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008999 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01009000 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06009001 }
Victor Stinner984890f2011-11-24 13:53:38 +01009002#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009003
Victor Stinner8c62be82010-05-06 00:08:46 +00009004 /* Remove the key from posix_putenv_garbage;
9005 * this will cause it to be collected. This has to
9006 * happen after the real unsetenv() call because the
9007 * old value was still accessible until then.
9008 */
Victor Stinner65170952011-11-22 22:16:17 +01009009 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009010 /* really not much we can do; just leak */
9011 PyErr_Clear();
9012 }
Victor Stinner65170952011-11-22 22:16:17 +01009013 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00009014 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009015}
9016#endif /* unsetenv */
9017
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009018PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009019"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009020Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009021
Guido van Rossumf68d8e52001-04-14 17:55:09 +00009022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009023posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00009024{
Victor Stinner8c62be82010-05-06 00:08:46 +00009025 int code;
9026 char *message;
9027 if (!PyArg_ParseTuple(args, "i:strerror", &code))
9028 return NULL;
9029 message = strerror(code);
9030 if (message == NULL) {
9031 PyErr_SetString(PyExc_ValueError,
9032 "strerror() argument out of range");
9033 return NULL;
9034 }
Victor Stinner1b579672011-12-17 05:47:23 +01009035 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009036}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009037
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009038
Guido van Rossumc9641791998-08-04 15:26:23 +00009039#ifdef HAVE_SYS_WAIT_H
9040
Fred Drake106c1a02002-04-23 15:58:02 +00009041#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009042PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009043"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009044Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00009045
9046static PyObject *
9047posix_WCOREDUMP(PyObject *self, PyObject *args)
9048{
Victor Stinner8c62be82010-05-06 00:08:46 +00009049 WAIT_TYPE status;
9050 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009051
Victor Stinner8c62be82010-05-06 00:08:46 +00009052 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
9053 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009054
Victor Stinner8c62be82010-05-06 00:08:46 +00009055 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009056}
9057#endif /* WCOREDUMP */
9058
9059#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009060PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009061"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00009062Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009063job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00009064
9065static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009066posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00009067{
Victor Stinner8c62be82010-05-06 00:08:46 +00009068 WAIT_TYPE status;
9069 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009070
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
9072 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009073
Victor Stinner8c62be82010-05-06 00:08:46 +00009074 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009075}
9076#endif /* WIFCONTINUED */
9077
Guido van Rossumc9641791998-08-04 15:26:23 +00009078#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009079PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009080"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009081Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009082
9083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009084posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009085{
Victor Stinner8c62be82010-05-06 00:08:46 +00009086 WAIT_TYPE status;
9087 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009088
Victor Stinner8c62be82010-05-06 00:08:46 +00009089 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
9090 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009091
Victor Stinner8c62be82010-05-06 00:08:46 +00009092 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009093}
9094#endif /* WIFSTOPPED */
9095
9096#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009097PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009098"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009099Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009100
9101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009102posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009103{
Victor Stinner8c62be82010-05-06 00:08:46 +00009104 WAIT_TYPE status;
9105 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009106
Victor Stinner8c62be82010-05-06 00:08:46 +00009107 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9108 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009109
Victor Stinner8c62be82010-05-06 00:08:46 +00009110 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009111}
9112#endif /* WIFSIGNALED */
9113
9114#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009115PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009116"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009117Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009118system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009119
9120static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009121posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009122{
Victor Stinner8c62be82010-05-06 00:08:46 +00009123 WAIT_TYPE status;
9124 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009125
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9127 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009128
Victor Stinner8c62be82010-05-06 00:08:46 +00009129 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009130}
9131#endif /* WIFEXITED */
9132
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009133#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009134PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009135"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009136Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009137
9138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009139posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009140{
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 WAIT_TYPE status;
9142 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009143
Victor Stinner8c62be82010-05-06 00:08:46 +00009144 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9145 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009146
Victor Stinner8c62be82010-05-06 00:08:46 +00009147 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009148}
9149#endif /* WEXITSTATUS */
9150
9151#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009152PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009153"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009154Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009155value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009156
9157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009158posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009159{
Victor Stinner8c62be82010-05-06 00:08:46 +00009160 WAIT_TYPE status;
9161 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009162
Victor Stinner8c62be82010-05-06 00:08:46 +00009163 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9164 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009165
Victor Stinner8c62be82010-05-06 00:08:46 +00009166 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009167}
9168#endif /* WTERMSIG */
9169
9170#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009171PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009172"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009173Return the signal that stopped the process that provided\n\
9174the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009175
9176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009177posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009178{
Victor Stinner8c62be82010-05-06 00:08:46 +00009179 WAIT_TYPE status;
9180 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009181
Victor Stinner8c62be82010-05-06 00:08:46 +00009182 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9183 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009184
Victor Stinner8c62be82010-05-06 00:08:46 +00009185 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009186}
9187#endif /* WSTOPSIG */
9188
9189#endif /* HAVE_SYS_WAIT_H */
9190
9191
Thomas Wouters477c8d52006-05-27 19:21:47 +00009192#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009193#ifdef _SCO_DS
9194/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9195 needed definitions in sys/statvfs.h */
9196#define _SVID3
9197#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009198#include <sys/statvfs.h>
9199
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009200static PyObject*
9201_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009202 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9203 if (v == NULL)
9204 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009205
9206#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009207 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9208 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9209 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9210 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9211 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9212 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9213 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9214 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9215 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9216 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009217#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009218 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9219 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9220 PyStructSequence_SET_ITEM(v, 2,
9221 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9222 PyStructSequence_SET_ITEM(v, 3,
9223 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9224 PyStructSequence_SET_ITEM(v, 4,
9225 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9226 PyStructSequence_SET_ITEM(v, 5,
9227 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9228 PyStructSequence_SET_ITEM(v, 6,
9229 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9230 PyStructSequence_SET_ITEM(v, 7,
9231 PyLong_FromLongLong((PY_LONG_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#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009235 if (PyErr_Occurred()) {
9236 Py_DECREF(v);
9237 return NULL;
9238 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009239
Victor Stinner8c62be82010-05-06 00:08:46 +00009240 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009241}
9242
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009243PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009244"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009245Perform an fstatvfs system call on the given fd.\n\
9246Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009247
9248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009249posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009250{
Victor Stinner8c62be82010-05-06 00:08:46 +00009251 int fd, res;
9252 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009253
Victor Stinner8c62be82010-05-06 00:08:46 +00009254 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9255 return NULL;
9256 Py_BEGIN_ALLOW_THREADS
9257 res = fstatvfs(fd, &st);
9258 Py_END_ALLOW_THREADS
9259 if (res != 0)
9260 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009261
Victor Stinner8c62be82010-05-06 00:08:46 +00009262 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009263}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009264#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009265
9266
Thomas Wouters477c8d52006-05-27 19:21:47 +00009267#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009268#include <sys/statvfs.h>
9269
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009270PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009271"statvfs(path)\n\n\
9272Perform a statvfs system call on the given path.\n\
9273\n\
9274path may always be specified as a string.\n\
9275On some platforms, path may also be specified as an open file descriptor.\n\
9276 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009277
9278static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009279posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009280{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009281 static char *keywords[] = {"path", NULL};
9282 path_t path;
9283 int result;
9284 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009285 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009286
Larry Hastings9cf065c2012-06-22 16:30:09 -07009287 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009288 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009289#ifdef HAVE_FSTATVFS
9290 path.allow_fd = 1;
9291#endif
9292 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9293 path_converter, &path
9294 ))
9295 return NULL;
9296
9297 Py_BEGIN_ALLOW_THREADS
9298#ifdef HAVE_FSTATVFS
9299 if (path.fd != -1) {
9300#ifdef __APPLE__
9301 /* handle weak-linking on Mac OS X 10.3 */
9302 if (fstatvfs == NULL) {
9303 fd_specified("statvfs", path.fd);
9304 goto exit;
9305 }
9306#endif
9307 result = fstatvfs(path.fd, &st);
9308 }
9309 else
9310#endif
9311 result = statvfs(path.narrow, &st);
9312 Py_END_ALLOW_THREADS
9313
9314 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009315 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009316 goto exit;
9317 }
9318
9319 return_value = _pystatvfs_fromstructstatvfs(st);
9320
9321exit:
9322 path_cleanup(&path);
9323 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009324}
9325#endif /* HAVE_STATVFS */
9326
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009327#ifdef MS_WINDOWS
9328PyDoc_STRVAR(win32__getdiskusage__doc__,
9329"_getdiskusage(path) -> (total, free)\n\n\
9330Return disk usage statistics about the given path as (total, free) tuple.");
9331
9332static PyObject *
9333win32__getdiskusage(PyObject *self, PyObject *args)
9334{
9335 BOOL retval;
9336 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009337 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009338
Victor Stinner6139c1b2011-11-09 22:14:14 +01009339 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009340 return NULL;
9341
9342 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009343 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009344 Py_END_ALLOW_THREADS
9345 if (retval == 0)
9346 return PyErr_SetFromWindowsErr(0);
9347
9348 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9349}
9350#endif
9351
9352
Fred Drakec9680921999-12-13 16:37:25 +00009353/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9354 * It maps strings representing configuration variable names to
9355 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009356 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009357 * rarely-used constants. There are three separate tables that use
9358 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009359 *
9360 * This code is always included, even if none of the interfaces that
9361 * need it are included. The #if hackery needed to avoid it would be
9362 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009363 */
9364struct constdef {
9365 char *name;
9366 long value;
9367};
9368
Fred Drake12c6e2d1999-12-14 21:25:03 +00009369static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009370conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009371 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009372{
Christian Heimes217cfd12007-12-02 14:31:20 +00009373 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009374 *valuep = PyLong_AS_LONG(arg);
9375 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009376 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009377 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009378 /* look up the value in the table using a binary search */
9379 size_t lo = 0;
9380 size_t mid;
9381 size_t hi = tablesize;
9382 int cmp;
9383 const char *confname;
9384 if (!PyUnicode_Check(arg)) {
9385 PyErr_SetString(PyExc_TypeError,
9386 "configuration names must be strings or integers");
9387 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009389 confname = _PyUnicode_AsString(arg);
9390 if (confname == NULL)
9391 return 0;
9392 while (lo < hi) {
9393 mid = (lo + hi) / 2;
9394 cmp = strcmp(confname, table[mid].name);
9395 if (cmp < 0)
9396 hi = mid;
9397 else if (cmp > 0)
9398 lo = mid + 1;
9399 else {
9400 *valuep = table[mid].value;
9401 return 1;
9402 }
9403 }
9404 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9405 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009406 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009407}
9408
9409
9410#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9411static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009412#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009413 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009414#endif
9415#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009416 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009417#endif
Fred Drakec9680921999-12-13 16:37:25 +00009418#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009419 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009420#endif
9421#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009422 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009423#endif
9424#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009425 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009426#endif
9427#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009428 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009429#endif
9430#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009431 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009432#endif
9433#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009434 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009435#endif
9436#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009437 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009438#endif
9439#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009440 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009441#endif
9442#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009443 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009444#endif
9445#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009446 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009447#endif
9448#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009449 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009450#endif
9451#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009452 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009453#endif
9454#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009455 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009456#endif
9457#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009458 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009459#endif
9460#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009461 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009462#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009463#ifdef _PC_ACL_ENABLED
9464 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9465#endif
9466#ifdef _PC_MIN_HOLE_SIZE
9467 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9468#endif
9469#ifdef _PC_ALLOC_SIZE_MIN
9470 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9471#endif
9472#ifdef _PC_REC_INCR_XFER_SIZE
9473 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9474#endif
9475#ifdef _PC_REC_MAX_XFER_SIZE
9476 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9477#endif
9478#ifdef _PC_REC_MIN_XFER_SIZE
9479 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9480#endif
9481#ifdef _PC_REC_XFER_ALIGN
9482 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9483#endif
9484#ifdef _PC_SYMLINK_MAX
9485 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9486#endif
9487#ifdef _PC_XATTR_ENABLED
9488 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9489#endif
9490#ifdef _PC_XATTR_EXISTS
9491 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9492#endif
9493#ifdef _PC_TIMESTAMP_RESOLUTION
9494 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9495#endif
Fred Drakec9680921999-12-13 16:37:25 +00009496};
9497
Fred Drakec9680921999-12-13 16:37:25 +00009498static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009499conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009500{
9501 return conv_confname(arg, valuep, posix_constants_pathconf,
9502 sizeof(posix_constants_pathconf)
9503 / sizeof(struct constdef));
9504}
9505#endif
9506
9507#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009508PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009509"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009510Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009511If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009512
9513static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009514posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009515{
9516 PyObject *result = NULL;
9517 int name, fd;
9518
Fred Drake12c6e2d1999-12-14 21:25:03 +00009519 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9520 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009521 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009522
Stefan Krah0e803b32010-11-26 16:16:47 +00009523 errno = 0;
9524 limit = fpathconf(fd, name);
9525 if (limit == -1 && errno != 0)
9526 posix_error();
9527 else
9528 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009529 }
9530 return result;
9531}
9532#endif
9533
9534
9535#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009536PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009537"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009538Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009539If there is no limit, return -1.\n\
9540On some platforms, path may also be specified as an open file descriptor.\n\
9541 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009542
9543static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009544posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009545{
Georg Brandl306336b2012-06-24 12:55:33 +02009546 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009547 PyObject *result = NULL;
9548 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009549 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009550
Georg Brandl306336b2012-06-24 12:55:33 +02009551 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009552 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02009553#ifdef HAVE_FPATHCONF
9554 path.allow_fd = 1;
9555#endif
9556 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9557 path_converter, &path,
9558 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009560
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009562#ifdef HAVE_FPATHCONF
9563 if (path.fd != -1)
9564 limit = fpathconf(path.fd, name);
9565 else
9566#endif
9567 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 if (limit == -1 && errno != 0) {
9569 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009570 /* could be a path or name problem */
9571 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009572 else
Victor Stinner292c8352012-10-30 02:17:38 +01009573 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 }
9575 else
9576 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009577 }
Georg Brandl306336b2012-06-24 12:55:33 +02009578 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009579 return result;
9580}
9581#endif
9582
9583#ifdef HAVE_CONFSTR
9584static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009585#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009587#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009588#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009590#endif
9591#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009593#endif
Fred Draked86ed291999-12-15 15:34:33 +00009594#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009596#endif
9597#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009599#endif
9600#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009602#endif
9603#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009605#endif
Fred Drakec9680921999-12-13 16:37:25 +00009606#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009608#endif
9609#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
9624#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
9627#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
Fred Draked86ed291999-12-15 15:34:33 +00009630#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009632#endif
Fred Drakec9680921999-12-13 16:37:25 +00009633#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009635#endif
Fred Draked86ed291999-12-15 15:34:33 +00009636#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009638#endif
9639#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009641#endif
9642#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009644#endif
9645#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009647#endif
Fred Drakec9680921999-12-13 16:37:25 +00009648#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009650#endif
9651#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009653#endif
9654#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009656#endif
9657#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009659#endif
9660#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009662#endif
9663#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009665#endif
9666#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009668#endif
9669#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009671#endif
9672#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009674#endif
9675#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009677#endif
9678#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009679 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009680#endif
9681#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009682 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009683#endif
9684#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009686#endif
9687#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009688 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009689#endif
9690#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009692#endif
9693#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009694 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009695#endif
Fred Draked86ed291999-12-15 15:34:33 +00009696#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009698#endif
9699#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009701#endif
9702#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009704#endif
9705#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009707#endif
9708#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009710#endif
9711#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009713#endif
9714#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009716#endif
9717#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009719#endif
9720#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009722#endif
9723#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009725#endif
9726#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009728#endif
9729#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009731#endif
9732#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009734#endif
Fred Drakec9680921999-12-13 16:37:25 +00009735};
9736
9737static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009738conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009739{
9740 return conv_confname(arg, valuep, posix_constants_confstr,
9741 sizeof(posix_constants_confstr)
9742 / sizeof(struct constdef));
9743}
9744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009745PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009746"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009747Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009748
9749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009750posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009751{
9752 PyObject *result = NULL;
9753 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009754 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009755 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009756
Victor Stinnercb043522010-09-10 23:49:04 +00009757 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9758 return NULL;
9759
9760 errno = 0;
9761 len = confstr(name, buffer, sizeof(buffer));
9762 if (len == 0) {
9763 if (errno) {
9764 posix_error();
9765 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009766 }
9767 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009768 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009769 }
9770 }
Victor Stinnercb043522010-09-10 23:49:04 +00009771
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009772 if (len >= sizeof(buffer)) {
Victor Stinnercb043522010-09-10 23:49:04 +00009773 char *buf = PyMem_Malloc(len);
9774 if (buf == NULL)
9775 return PyErr_NoMemory();
9776 confstr(name, buf, len);
9777 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9778 PyMem_Free(buf);
9779 }
9780 else
9781 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009782 return result;
9783}
9784#endif
9785
9786
9787#ifdef HAVE_SYSCONF
9788static struct constdef posix_constants_sysconf[] = {
9789#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
Fred Draked86ed291999-12-15 15:34:33 +00009819#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009821#endif
9822#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009824#endif
Fred Drakec9680921999-12-13 16:37:25 +00009825#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
Fred Drakec9680921999-12-13 16:37:25 +00009828#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
9831#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009833#endif
9834#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
9837#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009839#endif
9840#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
Fred Draked86ed291999-12-15 15:34:33 +00009843#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009845#endif
Fred Drakec9680921999-12-13 16:37:25 +00009846#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
9849#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
9858#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009860#endif
Fred Draked86ed291999-12-15 15:34:33 +00009861#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009863#endif
Fred Drakec9680921999-12-13 16:37:25 +00009864#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009866#endif
9867#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
9873#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009875#endif
9876#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
9885#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
9888#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
9897#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
9900#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
9909#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
9912#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
Fred Draked86ed291999-12-15 15:34:33 +00009933#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009935#endif
Fred Drakec9680921999-12-13 16:37:25 +00009936#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
Fred Draked86ed291999-12-15 15:34:33 +00009945#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009947#endif
Fred Drakec9680921999-12-13 16:37:25 +00009948#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
Fred Draked86ed291999-12-15 15:34:33 +00009951#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009953#endif
9954#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009956#endif
Fred Drakec9680921999-12-13 16:37:25 +00009957#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
Fred Draked86ed291999-12-15 15:34:33 +00009969#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009971#endif
Fred Drakec9680921999-12-13 16:37:25 +00009972#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
Fred Draked86ed291999-12-15 15:34:33 +00009993#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009995#endif
Fred Drakec9680921999-12-13 16:37:25 +00009996#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
Fred Draked86ed291999-12-15 15:34:33 +000010002#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010004#endif
Fred Drakec9680921999-12-13 16:37:25 +000010005#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
Fred Draked86ed291999-12-15 15:34:33 +000010032#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010034#endif
10035#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010037#endif
Fred Drakec9680921999-12-13 16:37:25 +000010038#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
10041#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
10044#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
10047#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010049#endif
10050#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010052#endif
10053#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
10056#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
10062#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010064#endif
10065#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
10068#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010070#endif
10071#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010073#endif
10074#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010076#endif
10077#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
10080#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
10083#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010085#endif
10086#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010088#endif
10089#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010091#endif
10092#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
10095#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010097#endif
10098#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
10110#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010112#endif
10113#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010115#endif
10116#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
10119#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010121#endif
10122#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010124#endif
10125#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
10131#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
10140#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010142#endif
Fred Draked86ed291999-12-15 15:34:33 +000010143#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010145#endif
Fred Drakec9680921999-12-13 16:37:25 +000010146#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010148#endif
10149#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010151#endif
10152#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010154#endif
10155#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
10158#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
10170#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010172#endif
10173#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
10176#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010178#endif
10179#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010223#endif
10224#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010225 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010226#endif
10227#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010228 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010229#endif
10230#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010231 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010232#endif
10233#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010234 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010235#endif
10236#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010237 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010238#endif
10239#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010240 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010241#endif
10242#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010243 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010244#endif
10245#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010247#endif
10248#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010249 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010250#endif
10251#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010252 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010253#endif
10254#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010256#endif
10257#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010258 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010259#endif
10260#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010261 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010262#endif
10263#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010265#endif
10266#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010268#endif
10269#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010270 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010271#endif
10272#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010274#endif
10275#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010277#endif
10278#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010279 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010280#endif
10281};
10282
10283static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010284conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010285{
10286 return conv_confname(arg, valuep, posix_constants_sysconf,
10287 sizeof(posix_constants_sysconf)
10288 / sizeof(struct constdef));
10289}
10290
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010291PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010292"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010293Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010294
10295static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010296posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010297{
10298 PyObject *result = NULL;
10299 int name;
10300
10301 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner6fdd7b82013-05-16 22:26:29 +020010302 long value;
Fred Drakec9680921999-12-13 16:37:25 +000010303
10304 errno = 0;
10305 value = sysconf(name);
10306 if (value == -1 && errno != 0)
10307 posix_error();
10308 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010309 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010310 }
10311 return result;
10312}
10313#endif
10314
10315
Fred Drakebec628d1999-12-15 18:31:10 +000010316/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010317 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010318 * the exported dictionaries that are used to publish information about the
10319 * names available on the host platform.
10320 *
10321 * Sorting the table at runtime ensures that the table is properly ordered
10322 * when used, even for platforms we're not able to test on. It also makes
10323 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010324 */
Fred Drakebec628d1999-12-15 18:31:10 +000010325
10326static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010327cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010328{
10329 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010331 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010333
10334 return strcmp(c1->name, c2->name);
10335}
10336
10337static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010338setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010340{
Fred Drakebec628d1999-12-15 18:31:10 +000010341 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010342 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010343
10344 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10345 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010346 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010348
Barry Warsaw3155db32000-04-13 15:20:40 +000010349 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 PyObject *o = PyLong_FromLong(table[i].value);
10351 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10352 Py_XDECREF(o);
10353 Py_DECREF(d);
10354 return -1;
10355 }
10356 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010357 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010358 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010359}
10360
Fred Drakebec628d1999-12-15 18:31:10 +000010361/* Return -1 on failure, 0 on success. */
10362static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010363setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010364{
10365#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010366 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010367 sizeof(posix_constants_pathconf)
10368 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010369 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010370 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010371#endif
10372#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010373 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010374 sizeof(posix_constants_confstr)
10375 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010376 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010377 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010378#endif
10379#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010380 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010381 sizeof(posix_constants_sysconf)
10382 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010383 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010384 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010385#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010386 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010387}
Fred Draked86ed291999-12-15 15:34:33 +000010388
10389
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010390PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010391"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010392Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010393in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010394
10395static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010396posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010397{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010398 abort();
10399 /*NOTREACHED*/
10400 Py_FatalError("abort() called from Python code didn't abort!");
10401 return NULL;
10402}
Fred Drakebec628d1999-12-15 18:31:10 +000010403
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010404#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010405PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010406"startfile(filepath [, operation]) - Start a file with its associated\n\
10407application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010408\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010409When \"operation\" is not specified or \"open\", this acts like\n\
10410double-clicking the file in Explorer, or giving the file name as an\n\
10411argument to the DOS \"start\" command: the file is opened with whatever\n\
10412application (if any) its extension is associated.\n\
10413When another \"operation\" is given, it specifies what should be done with\n\
10414the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010415\n\
10416startfile returns as soon as the associated application is launched.\n\
10417There is no option to wait for the application to close, and no way\n\
10418to retrieve the application's exit status.\n\
10419\n\
10420The filepath is relative to the current directory. If you want to use\n\
10421an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010422the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010423
10424static PyObject *
10425win32_startfile(PyObject *self, PyObject *args)
10426{
Victor Stinner8c62be82010-05-06 00:08:46 +000010427 PyObject *ofilepath;
10428 char *filepath;
10429 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010430 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010432
Victor Stinnereb5657a2011-09-30 01:44:27 +020010433 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010434 if (!PyArg_ParseTuple(args, "U|s:startfile",
10435 &unipath, &operation)) {
10436 PyErr_Clear();
10437 goto normal;
10438 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010439
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010441 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010443 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010444 PyErr_Clear();
10445 operation = NULL;
10446 goto normal;
10447 }
10448 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010449
Victor Stinnereb5657a2011-09-30 01:44:27 +020010450 wpath = PyUnicode_AsUnicode(unipath);
10451 if (wpath == NULL)
10452 goto normal;
10453 if (uoperation) {
10454 woperation = PyUnicode_AsUnicode(uoperation);
10455 if (woperation == NULL)
10456 goto normal;
10457 }
10458 else
10459 woperation = NULL;
10460
Victor Stinner8c62be82010-05-06 00:08:46 +000010461 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010462 rc = ShellExecuteW((HWND)0, woperation, wpath,
10463 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 Py_END_ALLOW_THREADS
10465
Victor Stinnereb5657a2011-09-30 01:44:27 +020010466 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010468 win32_error_object("startfile", unipath);
10469 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 }
10471 Py_INCREF(Py_None);
10472 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010473
10474normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010475 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10476 PyUnicode_FSConverter, &ofilepath,
10477 &operation))
10478 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010479 if (win32_warn_bytes_api()) {
10480 Py_DECREF(ofilepath);
10481 return NULL;
10482 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010483 filepath = PyBytes_AsString(ofilepath);
10484 Py_BEGIN_ALLOW_THREADS
10485 rc = ShellExecute((HWND)0, operation, filepath,
10486 NULL, NULL, SW_SHOWNORMAL);
10487 Py_END_ALLOW_THREADS
10488 if (rc <= (HINSTANCE)32) {
10489 PyObject *errval = win32_error("startfile", filepath);
10490 Py_DECREF(ofilepath);
10491 return errval;
10492 }
10493 Py_DECREF(ofilepath);
10494 Py_INCREF(Py_None);
10495 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010496}
10497#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010498
Martin v. Löwis438b5342002-12-27 10:16:42 +000010499#ifdef HAVE_GETLOADAVG
10500PyDoc_STRVAR(posix_getloadavg__doc__,
10501"getloadavg() -> (float, float, float)\n\n\
10502Return the number of processes in the system run queue averaged over\n\
10503the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10504was unobtainable");
10505
10506static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010507posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010508{
10509 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010510 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010511 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10512 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010513 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010514 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010515}
10516#endif
10517
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010518PyDoc_STRVAR(device_encoding__doc__,
10519"device_encoding(fd) -> str\n\n\
10520Return a string describing the encoding of the device\n\
10521if the output is a terminal; else return None.");
10522
10523static PyObject *
10524device_encoding(PyObject *self, PyObject *args)
10525{
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010527
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10529 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010530
10531 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010532}
10533
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010534#ifdef HAVE_SETRESUID
10535PyDoc_STRVAR(posix_setresuid__doc__,
10536"setresuid(ruid, euid, suid)\n\n\
10537Set the current process's real, effective, and saved user ids.");
10538
10539static PyObject*
10540posix_setresuid (PyObject *self, PyObject *args)
10541{
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010543 uid_t ruid, euid, suid;
10544 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10545 _Py_Uid_Converter, &ruid,
10546 _Py_Uid_Converter, &euid,
10547 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 return NULL;
10549 if (setresuid(ruid, euid, suid) < 0)
10550 return posix_error();
10551 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010552}
10553#endif
10554
10555#ifdef HAVE_SETRESGID
10556PyDoc_STRVAR(posix_setresgid__doc__,
10557"setresgid(rgid, egid, sgid)\n\n\
10558Set the current process's real, effective, and saved group ids.");
10559
10560static PyObject*
10561posix_setresgid (PyObject *self, PyObject *args)
10562{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010563 gid_t rgid, egid, sgid;
10564 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10565 _Py_Gid_Converter, &rgid,
10566 _Py_Gid_Converter, &egid,
10567 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 return NULL;
10569 if (setresgid(rgid, egid, sgid) < 0)
10570 return posix_error();
10571 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010572}
10573#endif
10574
10575#ifdef HAVE_GETRESUID
10576PyDoc_STRVAR(posix_getresuid__doc__,
10577"getresuid() -> (ruid, euid, suid)\n\n\
10578Get tuple of the current process's real, effective, and saved user ids.");
10579
10580static PyObject*
10581posix_getresuid (PyObject *self, PyObject *noargs)
10582{
Victor Stinner8c62be82010-05-06 00:08:46 +000010583 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 if (getresuid(&ruid, &euid, &suid) < 0)
10585 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010586 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10587 _PyLong_FromUid(euid),
10588 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010589}
10590#endif
10591
10592#ifdef HAVE_GETRESGID
10593PyDoc_STRVAR(posix_getresgid__doc__,
10594"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010595Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010596
10597static PyObject*
10598posix_getresgid (PyObject *self, PyObject *noargs)
10599{
Victor Stinner8c62be82010-05-06 00:08:46 +000010600 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 if (getresgid(&rgid, &egid, &sgid) < 0)
10602 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010603 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10604 _PyLong_FromGid(egid),
10605 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010606}
10607#endif
10608
Benjamin Peterson9428d532011-09-14 11:45:52 -040010609#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010610
Benjamin Peterson799bd802011-08-31 22:15:17 -040010611PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010612"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10613Return the value of extended attribute attribute on path.\n\
10614\n\
10615path may be either a string or an open file descriptor.\n\
10616If follow_symlinks is False, and the last element of the path is a symbolic\n\
10617 link, getxattr will examine the symbolic link itself instead of the file\n\
10618 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010619
10620static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010621posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010622{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010623 path_t path;
10624 path_t attribute;
10625 int follow_symlinks = 1;
10626 PyObject *buffer = NULL;
10627 int i;
10628 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010629
Larry Hastings9cf065c2012-06-22 16:30:09 -070010630 memset(&path, 0, sizeof(path));
10631 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010632 path.function_name = "getxattr";
10633 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010634 path.allow_fd = 1;
10635 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10636 path_converter, &path,
10637 path_converter, &attribute,
10638 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010639 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010640
Larry Hastings9cf065c2012-06-22 16:30:09 -070010641 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10642 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010643
Larry Hastings9cf065c2012-06-22 16:30:09 -070010644 for (i = 0; ; i++) {
10645 void *ptr;
10646 ssize_t result;
10647 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10648 Py_ssize_t buffer_size = buffer_sizes[i];
10649 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +010010650 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010651 goto exit;
10652 }
10653 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10654 if (!buffer)
10655 goto exit;
10656 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010657
Larry Hastings9cf065c2012-06-22 16:30:09 -070010658 Py_BEGIN_ALLOW_THREADS;
10659 if (path.fd >= 0)
10660 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10661 else if (follow_symlinks)
10662 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10663 else
10664 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10665 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010666
Larry Hastings9cf065c2012-06-22 16:30:09 -070010667 if (result < 0) {
10668 Py_DECREF(buffer);
10669 buffer = NULL;
10670 if (errno == ERANGE)
10671 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010672 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010673 goto exit;
10674 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010675
Larry Hastings9cf065c2012-06-22 16:30:09 -070010676 if (result != buffer_size) {
10677 /* Can only shrink. */
10678 _PyBytes_Resize(&buffer, result);
10679 }
10680 break;
10681 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010682
Larry Hastings9cf065c2012-06-22 16:30:09 -070010683exit:
10684 path_cleanup(&path);
10685 path_cleanup(&attribute);
10686 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010687}
10688
10689PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010690"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10691Set extended attribute attribute on path to value.\n\
10692path may be either a string or an open file descriptor.\n\
10693If follow_symlinks is False, and the last element of the path is a symbolic\n\
10694 link, setxattr will modify the symbolic link itself instead of the file\n\
10695 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010696
10697static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010698posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010699{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010700 path_t path;
10701 path_t attribute;
10702 Py_buffer value;
10703 int flags = 0;
10704 int follow_symlinks = 1;
10705 int result;
10706 PyObject *return_value = NULL;
10707 static char *keywords[] = {"path", "attribute", "value",
10708 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010709
Larry Hastings9cf065c2012-06-22 16:30:09 -070010710 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010711 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010712 path.allow_fd = 1;
10713 memset(&attribute, 0, sizeof(attribute));
10714 memset(&value, 0, sizeof(value));
10715 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10716 keywords,
10717 path_converter, &path,
10718 path_converter, &attribute,
10719 &value, &flags,
10720 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010721 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010722
10723 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10724 goto exit;
10725
Benjamin Peterson799bd802011-08-31 22:15:17 -040010726 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010727 if (path.fd > -1)
10728 result = fsetxattr(path.fd, attribute.narrow,
10729 value.buf, value.len, flags);
10730 else if (follow_symlinks)
10731 result = setxattr(path.narrow, attribute.narrow,
10732 value.buf, value.len, flags);
10733 else
10734 result = lsetxattr(path.narrow, attribute.narrow,
10735 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010736 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010737
Larry Hastings9cf065c2012-06-22 16:30:09 -070010738 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010739 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010740 goto exit;
10741 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010742
Larry Hastings9cf065c2012-06-22 16:30:09 -070010743 return_value = Py_None;
10744 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010745
Larry Hastings9cf065c2012-06-22 16:30:09 -070010746exit:
10747 path_cleanup(&path);
10748 path_cleanup(&attribute);
10749 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010750
Larry Hastings9cf065c2012-06-22 16:30:09 -070010751 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010752}
10753
10754PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010755"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10756Remove extended attribute attribute on path.\n\
10757path may be either a string or an open file descriptor.\n\
10758If follow_symlinks is False, and the last element of the path is a symbolic\n\
10759 link, removexattr will modify the symbolic link itself instead of the file\n\
10760 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010761
10762static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010763posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010764{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010765 path_t path;
10766 path_t attribute;
10767 int follow_symlinks = 1;
10768 int result;
10769 PyObject *return_value = NULL;
10770 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010771
Larry Hastings9cf065c2012-06-22 16:30:09 -070010772 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010773 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010774 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010775 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010776 path.allow_fd = 1;
10777 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10778 keywords,
10779 path_converter, &path,
10780 path_converter, &attribute,
10781 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010782 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010783
10784 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10785 goto exit;
10786
Benjamin Peterson799bd802011-08-31 22:15:17 -040010787 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010788 if (path.fd > -1)
10789 result = fremovexattr(path.fd, attribute.narrow);
10790 else if (follow_symlinks)
10791 result = removexattr(path.narrow, attribute.narrow);
10792 else
10793 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010794 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010795
Larry Hastings9cf065c2012-06-22 16:30:09 -070010796 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010797 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010798 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010799 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010800
Larry Hastings9cf065c2012-06-22 16:30:09 -070010801 return_value = Py_None;
10802 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010803
Larry Hastings9cf065c2012-06-22 16:30:09 -070010804exit:
10805 path_cleanup(&path);
10806 path_cleanup(&attribute);
10807
10808 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010809}
10810
10811PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010812"listxattr(path='.', *, follow_symlinks=True)\n\n\
10813Return a list of extended attributes on path.\n\
10814\n\
10815path may be either None, a string, or an open file descriptor.\n\
10816if path is None, listxattr will examine the current directory.\n\
10817If follow_symlinks is False, and the last element of the path is a symbolic\n\
10818 link, listxattr will examine the symbolic link itself instead of the file\n\
10819 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010820
10821static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010822posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010823{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010824 path_t path;
10825 int follow_symlinks = 1;
10826 Py_ssize_t i;
10827 PyObject *result = NULL;
10828 char *buffer = NULL;
10829 char *name;
10830 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010831
Larry Hastings9cf065c2012-06-22 16:30:09 -070010832 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010833 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010834 path.allow_fd = 1;
10835 path.fd = -1;
10836 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10837 path_converter, &path,
10838 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010839 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010840
Larry Hastings9cf065c2012-06-22 16:30:09 -070010841 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10842 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010843
Larry Hastings9cf065c2012-06-22 16:30:09 -070010844 name = path.narrow ? path.narrow : ".";
10845 for (i = 0; ; i++) {
10846 char *start, *trace, *end;
10847 ssize_t length;
10848 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10849 Py_ssize_t buffer_size = buffer_sizes[i];
10850 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010851 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010852 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010853 break;
10854 }
10855 buffer = PyMem_MALLOC(buffer_size);
10856 if (!buffer) {
10857 PyErr_NoMemory();
10858 break;
10859 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010860
Larry Hastings9cf065c2012-06-22 16:30:09 -070010861 Py_BEGIN_ALLOW_THREADS;
10862 if (path.fd > -1)
10863 length = flistxattr(path.fd, buffer, buffer_size);
10864 else if (follow_symlinks)
10865 length = listxattr(name, buffer, buffer_size);
10866 else
10867 length = llistxattr(name, buffer, buffer_size);
10868 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010869
Larry Hastings9cf065c2012-06-22 16:30:09 -070010870 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010871 if (errno == ERANGE) {
10872 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010873 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010874 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010875 }
Victor Stinner292c8352012-10-30 02:17:38 +010010876 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010877 break;
10878 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010879
Larry Hastings9cf065c2012-06-22 16:30:09 -070010880 result = PyList_New(0);
10881 if (!result) {
10882 goto exit;
10883 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010884
Larry Hastings9cf065c2012-06-22 16:30:09 -070010885 end = buffer + length;
10886 for (trace = start = buffer; trace != end; trace++) {
10887 if (!*trace) {
10888 int error;
10889 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10890 trace - start);
10891 if (!attribute) {
10892 Py_DECREF(result);
10893 result = NULL;
10894 goto exit;
10895 }
10896 error = PyList_Append(result, attribute);
10897 Py_DECREF(attribute);
10898 if (error) {
10899 Py_DECREF(result);
10900 result = NULL;
10901 goto exit;
10902 }
10903 start = trace + 1;
10904 }
10905 }
10906 break;
10907 }
10908exit:
10909 path_cleanup(&path);
10910 if (buffer)
10911 PyMem_FREE(buffer);
10912 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010913}
10914
Benjamin Peterson9428d532011-09-14 11:45:52 -040010915#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010916
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010917
Georg Brandl2fb477c2012-02-21 00:33:36 +010010918PyDoc_STRVAR(posix_urandom__doc__,
10919"urandom(n) -> str\n\n\
10920Return n random bytes suitable for cryptographic use.");
10921
10922static PyObject *
10923posix_urandom(PyObject *self, PyObject *args)
10924{
10925 Py_ssize_t size;
10926 PyObject *result;
10927 int ret;
10928
10929 /* Read arguments */
10930 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10931 return NULL;
10932 if (size < 0)
10933 return PyErr_Format(PyExc_ValueError,
10934 "negative argument not allowed");
10935 result = PyBytes_FromStringAndSize(NULL, size);
10936 if (result == NULL)
10937 return NULL;
10938
10939 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10940 PyBytes_GET_SIZE(result));
10941 if (ret == -1) {
10942 Py_DECREF(result);
10943 return NULL;
10944 }
10945 return result;
10946}
10947
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010948/* Terminal size querying */
10949
10950static PyTypeObject TerminalSizeType;
10951
10952PyDoc_STRVAR(TerminalSize_docstring,
10953 "A tuple of (columns, lines) for holding terminal window size");
10954
10955static PyStructSequence_Field TerminalSize_fields[] = {
10956 {"columns", "width of the terminal window in characters"},
10957 {"lines", "height of the terminal window in characters"},
10958 {NULL, NULL}
10959};
10960
10961static PyStructSequence_Desc TerminalSize_desc = {
10962 "os.terminal_size",
10963 TerminalSize_docstring,
10964 TerminalSize_fields,
10965 2,
10966};
10967
10968#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10969PyDoc_STRVAR(termsize__doc__,
10970 "Return the size of the terminal window as (columns, lines).\n" \
10971 "\n" \
10972 "The optional argument fd (default standard output) specifies\n" \
10973 "which file descriptor should be queried.\n" \
10974 "\n" \
10975 "If the file descriptor is not connected to a terminal, an OSError\n" \
10976 "is thrown.\n" \
10977 "\n" \
10978 "This function will only be defined if an implementation is\n" \
10979 "available for this system.\n" \
10980 "\n" \
10981 "shutil.get_terminal_size is the high-level function which should \n" \
10982 "normally be used, os.get_terminal_size is the low-level implementation.");
10983
10984static PyObject*
10985get_terminal_size(PyObject *self, PyObject *args)
10986{
10987 int columns, lines;
10988 PyObject *termsize;
10989
10990 int fd = fileno(stdout);
10991 /* Under some conditions stdout may not be connected and
10992 * fileno(stdout) may point to an invalid file descriptor. For example
10993 * GUI apps don't have valid standard streams by default.
10994 *
10995 * If this happens, and the optional fd argument is not present,
10996 * the ioctl below will fail returning EBADF. This is what we want.
10997 */
10998
10999 if (!PyArg_ParseTuple(args, "|i", &fd))
11000 return NULL;
11001
11002#ifdef TERMSIZE_USE_IOCTL
11003 {
11004 struct winsize w;
11005 if (ioctl(fd, TIOCGWINSZ, &w))
11006 return PyErr_SetFromErrno(PyExc_OSError);
11007 columns = w.ws_col;
11008 lines = w.ws_row;
11009 }
11010#endif /* TERMSIZE_USE_IOCTL */
11011
11012#ifdef TERMSIZE_USE_CONIO
11013 {
11014 DWORD nhandle;
11015 HANDLE handle;
11016 CONSOLE_SCREEN_BUFFER_INFO csbi;
11017 switch (fd) {
11018 case 0: nhandle = STD_INPUT_HANDLE;
11019 break;
11020 case 1: nhandle = STD_OUTPUT_HANDLE;
11021 break;
11022 case 2: nhandle = STD_ERROR_HANDLE;
11023 break;
11024 default:
11025 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11026 }
11027 handle = GetStdHandle(nhandle);
11028 if (handle == NULL)
11029 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11030 if (handle == INVALID_HANDLE_VALUE)
11031 return PyErr_SetFromWindowsErr(0);
11032
11033 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11034 return PyErr_SetFromWindowsErr(0);
11035
11036 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11037 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11038 }
11039#endif /* TERMSIZE_USE_CONIO */
11040
11041 termsize = PyStructSequence_New(&TerminalSizeType);
11042 if (termsize == NULL)
11043 return NULL;
11044 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11045 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11046 if (PyErr_Occurred()) {
11047 Py_DECREF(termsize);
11048 return NULL;
11049 }
11050 return termsize;
11051}
11052#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11053
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011054PyDoc_STRVAR(posix_cpu_count__doc__,
11055"cpu_count() -> integer\n\n\
11056Return the number of CPUs in the system, or None if this value cannot be\n\
11057established.");
11058
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011059static PyObject *
11060posix_cpu_count(PyObject *self)
11061{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011062 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011063#ifdef MS_WINDOWS
11064 SYSTEM_INFO sysinfo;
11065 GetSystemInfo(&sysinfo);
11066 ncpu = sysinfo.dwNumberOfProcessors;
11067#elif defined(__hpux)
11068 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11069#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11070 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011071#elif defined(__DragonFly__) || \
11072 defined(__OpenBSD__) || \
11073 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011074 defined(__NetBSD__) || \
11075 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011076 int mib[2];
11077 size_t len = sizeof(ncpu);
11078 mib[0] = CTL_HW;
11079 mib[1] = HW_NCPU;
11080 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11081 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011082#endif
11083 if (ncpu >= 1)
11084 return PyLong_FromLong(ncpu);
11085 else
11086 Py_RETURN_NONE;
11087}
11088
Victor Stinnerdaf45552013-08-28 00:53:59 +020011089PyDoc_STRVAR(get_inheritable__doc__,
11090 "get_inheritable(fd) -> bool\n" \
11091 "\n" \
11092 "Get the close-on-exe flag of the specified file descriptor.");
11093
11094static PyObject*
11095posix_get_inheritable(PyObject *self, PyObject *args)
11096{
11097 int fd;
11098 int inheritable;
11099
11100 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd))
11101 return NULL;
11102
11103 if (!_PyVerify_fd(fd))
11104 return posix_error();
11105
11106 inheritable = _Py_get_inheritable(fd);
11107 if (inheritable < 0)
11108 return NULL;
11109 return PyBool_FromLong(inheritable);
11110}
11111
11112PyDoc_STRVAR(set_inheritable__doc__,
11113 "set_inheritable(fd, inheritable)\n" \
11114 "\n" \
11115 "Set the inheritable flag of the specified file descriptor.");
11116
11117static PyObject*
11118posix_set_inheritable(PyObject *self, PyObject *args)
11119{
11120 int fd, inheritable;
11121
11122 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable))
11123 return NULL;
11124
11125 if (!_PyVerify_fd(fd))
11126 return posix_error();
11127
11128 if (_Py_set_inheritable(fd, inheritable, NULL) < 0)
11129 return NULL;
11130 Py_RETURN_NONE;
11131}
11132
11133
11134#ifdef MS_WINDOWS
11135PyDoc_STRVAR(get_handle_inheritable__doc__,
11136 "get_handle_inheritable(fd) -> bool\n" \
11137 "\n" \
11138 "Get the close-on-exe flag of the specified file descriptor.");
11139
11140static PyObject*
11141posix_get_handle_inheritable(PyObject *self, PyObject *args)
11142{
11143 Py_intptr_t handle;
11144 DWORD flags;
11145
11146 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle))
11147 return NULL;
11148
11149 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11150 PyErr_SetFromWindowsErr(0);
11151 return NULL;
11152 }
11153
11154 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT);
11155}
11156
11157PyDoc_STRVAR(set_handle_inheritable__doc__,
11158 "set_handle_inheritable(fd, inheritable)\n" \
11159 "\n" \
11160 "Set the inheritable flag of the specified handle.");
11161
11162static PyObject*
11163posix_set_handle_inheritable(PyObject *self, PyObject *args)
11164{
11165 int inheritable = 1;
11166 Py_intptr_t handle;
11167 DWORD flags;
11168
11169 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable",
11170 &handle, &inheritable))
11171 return NULL;
11172
11173 if (inheritable)
11174 flags = HANDLE_FLAG_INHERIT;
11175 else
11176 flags = 0;
11177 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11178 PyErr_SetFromWindowsErr(0);
11179 return NULL;
11180 }
11181 Py_RETURN_NONE;
11182}
11183#endif /* MS_WINDOWS */
11184
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011185
Larry Hastings7726ac92014-01-31 22:03:12 -080011186/*[clinic input]
11187dump buffer
11188[clinic start generated code]*/
11189
11190#ifndef OS_TTYNAME_METHODDEF
11191 #define OS_TTYNAME_METHODDEF
11192#endif /* !defined(OS_TTYNAME_METHODDEF) */
11193/*[clinic end generated code: output=5d071bbc8f49ea12 input=524ce2e021e4eba6]*/
11194
Larry Hastings31826802013-10-19 00:09:25 -070011195
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011196static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070011197
11198 OS_STAT_METHODDEF
11199 OS_ACCESS_METHODDEF
11200 OS_TTYNAME_METHODDEF
11201
Larry Hastings9cf065c2012-06-22 16:30:09 -070011202 {"chdir", (PyCFunction)posix_chdir,
11203 METH_VARARGS | METH_KEYWORDS,
11204 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011205#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011206 {"chflags", (PyCFunction)posix_chflags,
11207 METH_VARARGS | METH_KEYWORDS,
11208 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011209#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011210 {"chmod", (PyCFunction)posix_chmod,
11211 METH_VARARGS | METH_KEYWORDS,
11212 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011213#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011215#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011216#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070011217 {"chown", (PyCFunction)posix_chown,
11218 METH_VARARGS | METH_KEYWORDS,
11219 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011220#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000011221#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011222 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011223#endif /* HAVE_LCHMOD */
11224#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011225 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011226#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000011227#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011228 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011229#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011230#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011231 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011232#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000011233#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000011234 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000011235#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011236#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000011237 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011238#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011239 {"getcwd", (PyCFunction)posix_getcwd_unicode,
11240 METH_NOARGS, posix_getcwd__doc__},
11241 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
11242 METH_NOARGS, posix_getcwdb__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011243#if defined(HAVE_LINK) || defined(MS_WINDOWS)
11244 {"link", (PyCFunction)posix_link,
11245 METH_VARARGS | METH_KEYWORDS,
11246 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011247#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011248 {"listdir", (PyCFunction)posix_listdir,
11249 METH_VARARGS | METH_KEYWORDS,
11250 posix_listdir__doc__},
11251 {"lstat", (PyCFunction)posix_lstat,
11252 METH_VARARGS | METH_KEYWORDS,
11253 posix_lstat__doc__},
11254 {"mkdir", (PyCFunction)posix_mkdir,
11255 METH_VARARGS | METH_KEYWORDS,
11256 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011257#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011258 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011259#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011260#ifdef HAVE_GETPRIORITY
11261 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11262#endif /* HAVE_GETPRIORITY */
11263#ifdef HAVE_SETPRIORITY
11264 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11265#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011266#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011267 {"readlink", (PyCFunction)posix_readlink,
11268 METH_VARARGS | METH_KEYWORDS,
11269 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011270#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011271#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011272 {"readlink", (PyCFunction)win_readlink,
11273 METH_VARARGS | METH_KEYWORDS,
11274 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011275#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011276 {"rename", (PyCFunction)posix_rename,
11277 METH_VARARGS | METH_KEYWORDS,
11278 posix_rename__doc__},
11279 {"replace", (PyCFunction)posix_replace,
11280 METH_VARARGS | METH_KEYWORDS,
11281 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011282 {"rmdir", (PyCFunction)posix_rmdir,
11283 METH_VARARGS | METH_KEYWORDS,
11284 posix_rmdir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011285 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011286#if defined(HAVE_SYMLINK)
11287 {"symlink", (PyCFunction)posix_symlink,
11288 METH_VARARGS | METH_KEYWORDS,
11289 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011290#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011291#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011293#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011294 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011295#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011296 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011297#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011298 {"unlink", (PyCFunction)posix_unlink,
11299 METH_VARARGS | METH_KEYWORDS,
11300 posix_unlink__doc__},
11301 {"remove", (PyCFunction)posix_unlink,
11302 METH_VARARGS | METH_KEYWORDS,
11303 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011304 {"utime", (PyCFunction)posix_utime,
11305 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011306#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011308#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011309 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011310#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011311 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011312 {"execve", (PyCFunction)posix_execve,
11313 METH_VARARGS | METH_KEYWORDS,
11314 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011315#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011316#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011317 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11318 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000011319#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011320#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011321 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011322#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011323#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011324 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011325#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011326#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011327#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011328 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11329 {"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 +020011330#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011331#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011332 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011333#endif
11334#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011335 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011336#endif
11337#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011338 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011339#endif
11340#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011341 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011342#endif
11343#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011344 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011345#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011346 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011347#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011348 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11349 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11350#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011351#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011352#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011353 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011354#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011355#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011356 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011357#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011358#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011359 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011360#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011361#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011362 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011363#endif /* HAVE_GETEUID */
11364#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011365 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011366#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011367#ifdef HAVE_GETGROUPLIST
11368 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11369#endif
Fred Drakec9680921999-12-13 16:37:25 +000011370#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011371 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011372#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011373 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011374#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011376#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011377#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011378 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011379#endif /* HAVE_GETPPID */
11380#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011382#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011383#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011384 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011385#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011386#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011388#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011389#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011391#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011392#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011394#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011395#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011396 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11397 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011398#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011399#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011400 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011401#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011402#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011403 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011404#endif /* HAVE_SETEUID */
11405#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011406 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011407#endif /* HAVE_SETEGID */
11408#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011409 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011410#endif /* HAVE_SETREUID */
11411#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011412 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011413#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011414#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011415 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011416#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011417#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011418 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011419#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011420#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011421 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011422#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011423#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011424 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011425#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011426#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011428#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011429#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011430 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011431#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011432#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011433 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011434#endif /* HAVE_WAIT3 */
11435#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011436 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011437#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011438#if defined(HAVE_WAITID) && !defined(__APPLE__)
11439 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11440#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011441#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011442 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011443#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011444#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011445 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011446#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011447#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011448 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011449#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011450#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011451 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011452#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011453#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011455#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011456#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011457 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011458#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011459 {"open", (PyCFunction)posix_open,\
11460 METH_VARARGS | METH_KEYWORDS,
11461 posix_open__doc__},
Benjamin Peterson932bba32014-02-11 10:16:16 -050011462 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11464 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11465 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011466 {"dup2", (PyCFunction)posix_dup2,
11467 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011468#ifdef HAVE_LOCKF
11469 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11470#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011471 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11472 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011473#ifdef HAVE_READV
11474 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11475#endif
11476#ifdef HAVE_PREAD
11477 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11478#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011479 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011480#ifdef HAVE_WRITEV
11481 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11482#endif
11483#ifdef HAVE_PWRITE
11484 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11485#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011486#ifdef HAVE_SENDFILE
11487 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11488 posix_sendfile__doc__},
11489#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011490 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011491 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011492#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011493 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011494#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011495#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011496 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011497#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011498#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011499 {"mkfifo", (PyCFunction)posix_mkfifo,
11500 METH_VARARGS | METH_KEYWORDS,
11501 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011502#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011503#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011504 {"mknod", (PyCFunction)posix_mknod,
11505 METH_VARARGS | METH_KEYWORDS,
11506 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011507#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011508#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011509 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11510 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11511 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011512#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011513#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011514 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011515#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011516#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011517 {"truncate", (PyCFunction)posix_truncate,
11518 METH_VARARGS | METH_KEYWORDS,
11519 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011520#endif
Victor Stinnerd6b17692014-09-30 12:20:05 +020011521#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011522 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11523#endif
Victor Stinnerd6b17692014-09-30 12:20:05 +020011524#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Ross Lagerwall7807c352011-03-17 20:20:30 +020011525 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11526#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011527#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011528 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011529#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011530#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011531 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011532#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011533 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011534#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011535 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011536#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011537#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011538 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011539#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011540#ifdef HAVE_SYNC
11541 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11542#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011543#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011544 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011545#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011546#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011547#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011549#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011550#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011551 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011552#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011553#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011554 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011555#endif /* WIFSTOPPED */
11556#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011557 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011558#endif /* WIFSIGNALED */
11559#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011560 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011561#endif /* WIFEXITED */
11562#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011563 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011564#endif /* WEXITSTATUS */
11565#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011566 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011567#endif /* WTERMSIG */
11568#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011569 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011570#endif /* WSTOPSIG */
11571#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011572#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011573 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011574#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011575#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011576 {"statvfs", (PyCFunction)posix_statvfs,
11577 METH_VARARGS | METH_KEYWORDS,
11578 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011579#endif
Fred Drakec9680921999-12-13 16:37:25 +000011580#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011581 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011582#endif
11583#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011584 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011585#endif
11586#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011587 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011588#endif
11589#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011590 {"pathconf", (PyCFunction)posix_pathconf,
11591 METH_VARARGS | METH_KEYWORDS,
11592 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011593#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011594 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011595#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011596 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011597 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011598 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011599 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Tim Golden6b528062013-08-01 12:44:00 +010011600 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011601#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011602#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011603 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011604#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011605 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011606#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011607 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011608#endif
11609#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011610 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011611#endif
11612#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011613 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011614#endif
11615#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011616 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011617#endif
11618
Benjamin Peterson9428d532011-09-14 11:45:52 -040011619#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011620 {"setxattr", (PyCFunction)posix_setxattr,
11621 METH_VARARGS | METH_KEYWORDS,
11622 posix_setxattr__doc__},
11623 {"getxattr", (PyCFunction)posix_getxattr,
11624 METH_VARARGS | METH_KEYWORDS,
11625 posix_getxattr__doc__},
11626 {"removexattr", (PyCFunction)posix_removexattr,
11627 METH_VARARGS | METH_KEYWORDS,
11628 posix_removexattr__doc__},
11629 {"listxattr", (PyCFunction)posix_listxattr,
11630 METH_VARARGS | METH_KEYWORDS,
11631 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011632#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011633#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11634 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11635#endif
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011636 {"cpu_count", (PyCFunction)posix_cpu_count,
11637 METH_NOARGS, posix_cpu_count__doc__},
Victor Stinnerdaf45552013-08-28 00:53:59 +020011638 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__},
11639 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__},
11640#ifdef MS_WINDOWS
11641 {"get_handle_inheritable", posix_get_handle_inheritable,
11642 METH_VARARGS, get_handle_inheritable__doc__},
11643 {"set_handle_inheritable", posix_set_handle_inheritable,
11644 METH_VARARGS, set_handle_inheritable__doc__},
11645#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011646 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011647};
11648
11649
Brian Curtin52173d42010-12-02 18:29:18 +000011650#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011651static int
Brian Curtin52173d42010-12-02 18:29:18 +000011652enable_symlink()
11653{
11654 HANDLE tok;
11655 TOKEN_PRIVILEGES tok_priv;
11656 LUID luid;
11657 int meth_idx = 0;
11658
11659 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011660 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011661
11662 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011663 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011664
11665 tok_priv.PrivilegeCount = 1;
11666 tok_priv.Privileges[0].Luid = luid;
11667 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11668
11669 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11670 sizeof(TOKEN_PRIVILEGES),
11671 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011672 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011673
Brian Curtin3b4499c2010-12-28 14:31:47 +000011674 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11675 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011676}
11677#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11678
Barry Warsaw4a342091996-12-19 23:50:02 +000011679static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011680all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000011681{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011682#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011683 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011684#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011685#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011686 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011687#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011688#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011689 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011690#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011691#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011692 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011693#endif
Fred Drakec9680921999-12-13 16:37:25 +000011694#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011695 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011696#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011697#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011698 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011699#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011700#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011701 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011702#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011703#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011704 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011705#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011706#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011707 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011708#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011709#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011710 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011711#endif
11712#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011713 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011714#endif
11715#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011716 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011717#endif
11718#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011719 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011720#endif
11721#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011722 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011723#endif
11724#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011725 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011726#endif
11727#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011728 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011729#endif
11730#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011731 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011732#endif
11733#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011734 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011735#endif
11736#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011737 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011738#endif
11739#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011740 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011741#endif
11742#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011743 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011744#endif
11745#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011746 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011747#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011748#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011749 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011750#endif
11751#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011752 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011753#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011754#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011755 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011756#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011757#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011758 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011759#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011760#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011761 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011762#endif
11763#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011764 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011765#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011766#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011767 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011768#endif
11769#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011770 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011771#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011772#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011773 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050011774#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011775#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011776 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020011777#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020011778#ifdef O_TMPFILE
11779 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
11780#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011781#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011782 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011783#endif
11784#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011785 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011786#endif
11787#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011788 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011789#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011790#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011791 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020011792#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011793#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011794 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011795#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011796
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011797
Jesus Cea94363612012-06-22 18:32:07 +020011798#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011799 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011800#endif
11801#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011802 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020011803#endif
11804
Tim Peters5aa91602002-01-30 05:46:57 +000011805/* MS Windows */
11806#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011807 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011808 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011809#endif
11810#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011811 /* Optimize for short life (keep in memory). */
11812 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011813 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011814#endif
11815#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011816 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011817 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011818#endif
11819#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011820 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011821 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011822#endif
11823#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011824 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011825 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011826#endif
11827
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011828/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011829#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011830 /* Send a SIGIO signal whenever input or output
11831 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011832 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011833#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011834#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011835 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011836 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011837#endif
11838#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011839 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011840 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011841#endif
11842#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011843 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011844 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011845#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011846#ifdef O_NOLINKS
11847 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011848 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020011849#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011850#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011851 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011852 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011853#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011854
Victor Stinner8c62be82010-05-06 00:08:46 +000011855 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011856#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011857 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011858#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011859#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011860 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011861#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011862#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011863 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011864#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011865#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011866 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011867#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011868#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011869 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011870#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011871#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011872 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011873#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011874#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011875 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011876#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011877#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011878 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011879#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011880#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011881 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011882#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011883#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011884 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011885#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011886#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011887 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011888#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011889#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011890 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011891#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011892#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011893 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011894#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011895#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011896 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011897#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011898#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011899 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011900#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011901#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011902 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011903#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011904#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011905 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011906#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011907
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011908 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011909#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011910 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011911#endif /* ST_RDONLY */
11912#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011913 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011914#endif /* ST_NOSUID */
11915
doko@ubuntu.comca616a22013-12-08 15:23:07 +010011916 /* GNU extensions */
11917#ifdef ST_NODEV
11918 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
11919#endif /* ST_NODEV */
11920#ifdef ST_NOEXEC
11921 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
11922#endif /* ST_NOEXEC */
11923#ifdef ST_SYNCHRONOUS
11924 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
11925#endif /* ST_SYNCHRONOUS */
11926#ifdef ST_MANDLOCK
11927 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
11928#endif /* ST_MANDLOCK */
11929#ifdef ST_WRITE
11930 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
11931#endif /* ST_WRITE */
11932#ifdef ST_APPEND
11933 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
11934#endif /* ST_APPEND */
11935#ifdef ST_NOATIME
11936 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
11937#endif /* ST_NOATIME */
11938#ifdef ST_NODIRATIME
11939 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
11940#endif /* ST_NODIRATIME */
11941#ifdef ST_RELATIME
11942 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
11943#endif /* ST_RELATIME */
11944
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011945 /* FreeBSD sendfile() constants */
11946#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011947 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011948#endif
11949#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011950 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011951#endif
11952#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011953 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011954#endif
11955
Ross Lagerwall7807c352011-03-17 20:20:30 +020011956 /* constants for posix_fadvise */
11957#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011958 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011959#endif
11960#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011961 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011962#endif
11963#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011964 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011965#endif
11966#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011967 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011968#endif
11969#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011970 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011971#endif
11972#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011973 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011974#endif
11975
11976 /* constants for waitid */
11977#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011978 if (PyModule_AddIntMacro(m, P_PID)) return -1;
11979 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
11980 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011981#endif
11982#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011983 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011984#endif
11985#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011986 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011987#endif
11988#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011989 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011990#endif
11991#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011992 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011993#endif
11994#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011995 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011996#endif
11997#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020011998 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020011999#endif
12000#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012001 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012002#endif
12003
12004 /* constants for lockf */
12005#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012006 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012007#endif
12008#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012009 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012010#endif
12011#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012012 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012013#endif
12014#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012015 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012016#endif
12017
Guido van Rossum246bc171999-02-01 23:54:31 +000012018#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012019 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12020 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12021 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12022 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12023 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012024#endif
12025
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012026#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012027 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12028 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12029 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012030#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012031 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012032#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012033#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012034 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012035#endif
12036#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012037 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012038#endif
12039#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012040 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012041#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012042#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012043 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012044#endif
12045#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012046 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012047#endif
12048#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012049 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012050#endif
12051#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012052 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012053#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012054#endif
12055
Benjamin Peterson9428d532011-09-14 11:45:52 -040012056#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012057 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12058 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12059 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012060#endif
12061
Victor Stinner8b905bd2011-10-25 13:34:04 +020012062#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012063 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012064#endif
12065#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012066 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012067#endif
12068#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012069 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012070#endif
12071#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012072 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012073#endif
12074#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012075 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012076#endif
12077#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012078 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012079#endif
12080#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012081 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012082#endif
12083
Victor Stinner8c62be82010-05-06 00:08:46 +000012084 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012085}
12086
12087
Tim Peters5aa91602002-01-30 05:46:57 +000012088#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000012089#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012090#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000012091
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000012092#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000012093#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000012094#define MODNAME "posix"
12095#endif
12096
Martin v. Löwis1a214512008-06-11 05:26:20 +000012097static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012098 PyModuleDef_HEAD_INIT,
12099 MODNAME,
12100 posix__doc__,
12101 -1,
12102 posix_methods,
12103 NULL,
12104 NULL,
12105 NULL,
12106 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012107};
12108
12109
Larry Hastings9cf065c2012-06-22 16:30:09 -070012110static char *have_functions[] = {
12111
12112#ifdef HAVE_FACCESSAT
12113 "HAVE_FACCESSAT",
12114#endif
12115
12116#ifdef HAVE_FCHDIR
12117 "HAVE_FCHDIR",
12118#endif
12119
12120#ifdef HAVE_FCHMOD
12121 "HAVE_FCHMOD",
12122#endif
12123
12124#ifdef HAVE_FCHMODAT
12125 "HAVE_FCHMODAT",
12126#endif
12127
12128#ifdef HAVE_FCHOWN
12129 "HAVE_FCHOWN",
12130#endif
12131
Larry Hastings00964ed2013-08-12 13:49:30 -040012132#ifdef HAVE_FCHOWNAT
12133 "HAVE_FCHOWNAT",
12134#endif
12135
Larry Hastings9cf065c2012-06-22 16:30:09 -070012136#ifdef HAVE_FEXECVE
12137 "HAVE_FEXECVE",
12138#endif
12139
12140#ifdef HAVE_FDOPENDIR
12141 "HAVE_FDOPENDIR",
12142#endif
12143
Georg Brandl306336b2012-06-24 12:55:33 +020012144#ifdef HAVE_FPATHCONF
12145 "HAVE_FPATHCONF",
12146#endif
12147
Larry Hastings9cf065c2012-06-22 16:30:09 -070012148#ifdef HAVE_FSTATAT
12149 "HAVE_FSTATAT",
12150#endif
12151
12152#ifdef HAVE_FSTATVFS
12153 "HAVE_FSTATVFS",
12154#endif
12155
Georg Brandl306336b2012-06-24 12:55:33 +020012156#ifdef HAVE_FTRUNCATE
12157 "HAVE_FTRUNCATE",
12158#endif
12159
Larry Hastings9cf065c2012-06-22 16:30:09 -070012160#ifdef HAVE_FUTIMENS
12161 "HAVE_FUTIMENS",
12162#endif
12163
12164#ifdef HAVE_FUTIMES
12165 "HAVE_FUTIMES",
12166#endif
12167
12168#ifdef HAVE_FUTIMESAT
12169 "HAVE_FUTIMESAT",
12170#endif
12171
12172#ifdef HAVE_LINKAT
12173 "HAVE_LINKAT",
12174#endif
12175
12176#ifdef HAVE_LCHFLAGS
12177 "HAVE_LCHFLAGS",
12178#endif
12179
12180#ifdef HAVE_LCHMOD
12181 "HAVE_LCHMOD",
12182#endif
12183
12184#ifdef HAVE_LCHOWN
12185 "HAVE_LCHOWN",
12186#endif
12187
12188#ifdef HAVE_LSTAT
12189 "HAVE_LSTAT",
12190#endif
12191
12192#ifdef HAVE_LUTIMES
12193 "HAVE_LUTIMES",
12194#endif
12195
12196#ifdef HAVE_MKDIRAT
12197 "HAVE_MKDIRAT",
12198#endif
12199
12200#ifdef HAVE_MKFIFOAT
12201 "HAVE_MKFIFOAT",
12202#endif
12203
12204#ifdef HAVE_MKNODAT
12205 "HAVE_MKNODAT",
12206#endif
12207
12208#ifdef HAVE_OPENAT
12209 "HAVE_OPENAT",
12210#endif
12211
12212#ifdef HAVE_READLINKAT
12213 "HAVE_READLINKAT",
12214#endif
12215
12216#ifdef HAVE_RENAMEAT
12217 "HAVE_RENAMEAT",
12218#endif
12219
12220#ifdef HAVE_SYMLINKAT
12221 "HAVE_SYMLINKAT",
12222#endif
12223
12224#ifdef HAVE_UNLINKAT
12225 "HAVE_UNLINKAT",
12226#endif
12227
12228#ifdef HAVE_UTIMENSAT
12229 "HAVE_UTIMENSAT",
12230#endif
12231
12232#ifdef MS_WINDOWS
12233 "MS_WINDOWS",
12234#endif
12235
12236 NULL
12237};
12238
12239
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012240PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012241INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012242{
Victor Stinner8c62be82010-05-06 00:08:46 +000012243 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012244 PyObject *list;
12245 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012246
Brian Curtin52173d42010-12-02 18:29:18 +000012247#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012248 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012249#endif
12250
Victor Stinner8c62be82010-05-06 00:08:46 +000012251 m = PyModule_Create(&posixmodule);
12252 if (m == NULL)
12253 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012254
Victor Stinner8c62be82010-05-06 00:08:46 +000012255 /* Initialize environ dictionary */
12256 v = convertenviron();
12257 Py_XINCREF(v);
12258 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12259 return NULL;
12260 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012261
Victor Stinner8c62be82010-05-06 00:08:46 +000012262 if (all_ins(m))
12263 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012264
Victor Stinner8c62be82010-05-06 00:08:46 +000012265 if (setup_confname_tables(m))
12266 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012267
Victor Stinner8c62be82010-05-06 00:08:46 +000012268 Py_INCREF(PyExc_OSError);
12269 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012270
Guido van Rossumb3d39562000-01-31 18:41:26 +000012271#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012272 if (posix_putenv_garbage == NULL)
12273 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012274#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012275
Victor Stinner8c62be82010-05-06 00:08:46 +000012276 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012277#if defined(HAVE_WAITID) && !defined(__APPLE__)
12278 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012279 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12280 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012281#endif
12282
Christian Heimes25827622013-10-12 01:27:08 +020012283 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012284 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12285 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12286 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012287 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12288 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012289 structseq_new = StatResultType.tp_new;
12290 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012291
Christian Heimes25827622013-10-12 01:27:08 +020012292 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012293 if (PyStructSequence_InitType2(&StatVFSResultType,
12294 &statvfs_result_desc) < 0)
12295 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012296#ifdef NEED_TICKS_PER_SECOND
12297# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012298 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012299# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012300 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012301# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012302 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012303# endif
12304#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012305
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012306#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012307 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012308 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12309 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012310 SchedParamType.tp_new = sched_param_new;
12311#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012312
12313 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012314 if (PyStructSequence_InitType2(&TerminalSizeType,
12315 &TerminalSize_desc) < 0)
12316 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012317 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012318#if defined(HAVE_WAITID) && !defined(__APPLE__)
12319 Py_INCREF((PyObject*) &WaitidResultType);
12320 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12321#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012322 Py_INCREF((PyObject*) &StatResultType);
12323 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12324 Py_INCREF((PyObject*) &StatVFSResultType);
12325 PyModule_AddObject(m, "statvfs_result",
12326 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012327
12328#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012329 Py_INCREF(&SchedParamType);
12330 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012331#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012332
Larry Hastings605a62d2012-06-24 04:33:36 -070012333 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012334 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12335 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012336 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12337
12338 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012339 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12340 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012341 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12342
Thomas Wouters477c8d52006-05-27 19:21:47 +000012343#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012344 /*
12345 * Step 2 of weak-linking support on Mac OS X.
12346 *
12347 * The code below removes functions that are not available on the
12348 * currently active platform.
12349 *
12350 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012351 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012352 * OSX 10.4.
12353 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012354#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012355 if (fstatvfs == NULL) {
12356 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12357 return NULL;
12358 }
12359 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012360#endif /* HAVE_FSTATVFS */
12361
12362#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012363 if (statvfs == NULL) {
12364 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12365 return NULL;
12366 }
12367 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012368#endif /* HAVE_STATVFS */
12369
12370# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012371 if (lchown == NULL) {
12372 if (PyObject_DelAttrString(m, "lchown") == -1) {
12373 return NULL;
12374 }
12375 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012376#endif /* HAVE_LCHOWN */
12377
12378
12379#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012380
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012381 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012382 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12383
Larry Hastings6fe20b32012-04-19 15:07:49 -070012384 billion = PyLong_FromLong(1000000000);
12385 if (!billion)
12386 return NULL;
12387
Larry Hastings9cf065c2012-06-22 16:30:09 -070012388 /* suppress "function not used" warnings */
12389 {
12390 int ignored;
12391 fd_specified("", -1);
12392 follow_symlinks_specified("", 1);
12393 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12394 dir_fd_converter(Py_None, &ignored);
12395 dir_fd_unavailable(Py_None, &ignored);
12396 }
12397
12398 /*
12399 * provide list of locally available functions
12400 * so os.py can populate support_* lists
12401 */
12402 list = PyList_New(0);
12403 if (!list)
12404 return NULL;
12405 for (trace = have_functions; *trace; trace++) {
12406 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12407 if (!unicode)
12408 return NULL;
12409 if (PyList_Append(list, unicode))
12410 return NULL;
12411 Py_DECREF(unicode);
12412 }
12413 PyModule_AddObject(m, "_have_functions", list);
12414
12415 initialized = 1;
12416
Victor Stinner8c62be82010-05-06 00:08:46 +000012417 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000012418}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012419
12420#ifdef __cplusplus
12421}
12422#endif