blob: 194a2b5aa563d1d4a59366d5e4b9a41feea7a5d8 [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
Victor Stinnerf427a142014-10-22 12:33:23 +02009 test macro, e.g. '_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"
Antoine Pitrou346cbd32017-05-27 17:50:54 +020028#include "pythread.h"
Victor Stinner6036e442015-03-08 01:58:04 +010029#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020030#ifndef MS_WINDOWS
31#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010032#else
33#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020034#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000035
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020036/* On android API level 21, 'AT_EACCESS' is not declared although
37 * HAVE_FACCESSAT is defined. */
38#ifdef __ANDROID__
39#undef HAVE_FACCESSAT
40#endif
41
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000042#include <stdio.h> /* needed for ctermid() */
43
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000044#ifdef __cplusplus
45extern "C" {
46#endif
47
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000048PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000049"This module provides access to operating system functionality that is\n\
50standardized by the C Standard and the POSIX standard (a thinly\n\
51disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000052corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000054
Ross Lagerwall4d076da2011-03-18 06:56:53 +020055#ifdef HAVE_SYS_UIO_H
56#include <sys/uio.h>
57#endif
58
Thomas Wouters0e3f5912006-08-11 14:57:12 +000059#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000060#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000061#endif /* HAVE_SYS_TYPES_H */
62
63#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000066
Guido van Rossum36bc6801995-06-14 22:54:23 +000067#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000068#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000069#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000070
Thomas Wouters0e3f5912006-08-11 14:57:12 +000071#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000072#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000073#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000074
Guido van Rossumb6775db1994-08-01 11:34:53 +000075#ifdef HAVE_FCNTL_H
76#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000077#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000078
Guido van Rossuma6535fd2001-10-18 19:44:10 +000079#ifdef HAVE_GRP_H
80#include <grp.h>
81#endif
82
Barry Warsaw5676bd12003-01-07 20:57:09 +000083#ifdef HAVE_SYSEXITS_H
84#include <sysexits.h>
85#endif /* HAVE_SYSEXITS_H */
86
Anthony Baxter8a560de2004-10-13 15:30:56 +000087#ifdef HAVE_SYS_LOADAVG_H
88#include <sys/loadavg.h>
89#endif
90
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000091#ifdef HAVE_SYS_SENDFILE_H
92#include <sys/sendfile.h>
93#endif
94
Benjamin Peterson94b580d2011-08-02 17:30:04 -050095#ifdef HAVE_SCHED_H
96#include <sched.h>
97#endif
98
Benjamin Peterson2dbda072012-03-16 10:12:55 -050099#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500100#undef HAVE_SCHED_SETAFFINITY
101#endif
102
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200103#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400104#define USE_XATTRS
105#endif
106
107#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400108#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400109#endif
110
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000111#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
112#ifdef HAVE_SYS_SOCKET_H
113#include <sys/socket.h>
114#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000115#endif
116
Victor Stinner8b905bd2011-10-25 13:34:04 +0200117#ifdef HAVE_DLFCN_H
118#include <dlfcn.h>
119#endif
120
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200121#ifdef __hpux
122#include <sys/mpctl.h>
123#endif
124
125#if defined(__DragonFly__) || \
126 defined(__OpenBSD__) || \
127 defined(__FreeBSD__) || \
128 defined(__NetBSD__) || \
129 defined(__APPLE__)
130#include <sys/sysctl.h>
131#endif
132
Victor Stinner9b1f4742016-09-06 16:18:52 -0700133#ifdef HAVE_LINUX_RANDOM_H
134# include <linux/random.h>
135#endif
136#ifdef HAVE_GETRANDOM_SYSCALL
137# include <sys/syscall.h>
138#endif
139
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100140#if defined(MS_WINDOWS)
141# define TERMSIZE_USE_CONIO
142#elif defined(HAVE_SYS_IOCTL_H)
143# include <sys/ioctl.h>
144# if defined(HAVE_TERMIOS_H)
145# include <termios.h>
146# endif
147# if defined(TIOCGWINSZ)
148# define TERMSIZE_USE_IOCTL
149# endif
150#endif /* MS_WINDOWS */
151
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000152/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000153/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000154#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000156#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#include <process.h>
158#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000160#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000161#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000162#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000163#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700164#define HAVE_WSPAWNV 1
165#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#define HAVE_SYSTEM 1
168#define HAVE_CWAIT 1
169#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000170#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000171#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172/* Unix functions that the configure script doesn't check for */
173#define HAVE_EXECV 1
174#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000175#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000176#define HAVE_FORK1 1
177#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#define HAVE_GETEGID 1
179#define HAVE_GETEUID 1
180#define HAVE_GETGID 1
181#define HAVE_GETPPID 1
182#define HAVE_GETUID 1
183#define HAVE_KILL 1
184#define HAVE_OPENDIR 1
185#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000186#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000187#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000188#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000189#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000190#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000191
Victor Stinnera2f7c002012-02-08 03:36:25 +0100192
Larry Hastings61272b72014-01-07 12:41:53 -0800193/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000194# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800195module os
Larry Hastings61272b72014-01-07 12:41:53 -0800196[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000197/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100198
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000199#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000200
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000201#if defined(__sgi)&&_COMPILER_VERSION>=700
202/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
203 (default) */
204extern char *ctermid_r(char *);
205#endif
206
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000207#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000208#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000209extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000210#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000211#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000213#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000214extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000216#endif
217#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000218extern int chdir(char *);
219extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000220#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000221extern int chdir(const char *);
222extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000223#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000225/*#ifdef HAVE_FCHMOD
226extern int fchmod(int, mode_t);
227#endif*/
228/*#ifdef HAVE_LCHMOD
229extern int lchmod(const char *, mode_t);
230#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000231extern int chown(const char *, uid_t, gid_t);
232extern char *getcwd(char *, int);
233extern char *strerror(int);
234extern int link(const char *, const char *);
235extern int rename(const char *, const char *);
236extern int stat(const char *, struct stat *);
237extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000239extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000240#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000242extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000243#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000245
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000246#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000247
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#ifdef HAVE_UTIME_H
249#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000250#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000252#ifdef HAVE_SYS_UTIME_H
253#include <sys/utime.h>
254#define HAVE_UTIME_H /* pretend we do for the rest of this file */
255#endif /* HAVE_SYS_UTIME_H */
256
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#ifdef HAVE_SYS_TIMES_H
258#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000259#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260
261#ifdef HAVE_SYS_PARAM_H
262#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000263#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264
265#ifdef HAVE_SYS_UTSNAME_H
266#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000267#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000269#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000271#define NAMLEN(dirent) strlen((dirent)->d_name)
272#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000273#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000274#include <direct.h>
275#define NAMLEN(dirent) strlen((dirent)->d_name)
276#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000279#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#endif
283#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#endif
286#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000288#endif
289#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000291#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000292#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294#endif
295#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297#endif
298#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000301#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000302#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000303#endif
304#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000305#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000306#endif
307#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000308#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000309#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100310#ifndef IO_REPARSE_TAG_MOUNT_POINT
311#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
312#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000313#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000314#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000315#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000316#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000317#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000318#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
319#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000320static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000321#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000322#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000323
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325#if defined(PATH_MAX) && PATH_MAX > 1024
326#define MAXPATHLEN PATH_MAX
327#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000328#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000329#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000330#endif /* MAXPATHLEN */
331
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000332#ifdef UNION_WAIT
333/* Emulate some macros on systems that have a union instead of macros */
334
335#ifndef WIFEXITED
336#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
337#endif
338
339#ifndef WEXITSTATUS
340#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
341#endif
342
343#ifndef WTERMSIG
344#define WTERMSIG(u_wait) ((u_wait).w_termsig)
345#endif
346
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000347#define WAIT_TYPE union wait
348#define WAIT_STATUS_INT(s) (s.w_status)
349
350#else /* !UNION_WAIT */
351#define WAIT_TYPE int
352#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000353#endif /* UNION_WAIT */
354
Greg Wardb48bc172000-03-01 21:51:56 +0000355/* Don't use the "_r" form if we don't need it (also, won't have a
356 prototype for it, at least on Solaris -- maybe others as well?). */
357#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
358#define USE_CTERMID_R
359#endif
360
Fred Drake699f3522000-06-29 21:12:41 +0000361/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000362#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000363#undef FSTAT
364#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200365#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000366# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700367# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200368# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800369# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000370#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000371# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700372# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000373# define FSTAT fstat
374# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000375#endif
376
Tim Peters11b23062003-04-23 02:39:17 +0000377#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000378#include <sys/mkdev.h>
379#else
380#if defined(MAJOR_IN_SYSMACROS)
381#include <sys/sysmacros.h>
382#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000383#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
384#include <sys/mkdev.h>
385#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000386#endif
Fred Drake699f3522000-06-29 21:12:41 +0000387
Victor Stinner6edddfa2013-11-24 19:22:57 +0100388#define DWORD_MAX 4294967295U
389
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200390#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100391#define INITFUNC PyInit_nt
392#define MODNAME "nt"
393#else
394#define INITFUNC PyInit_posix
395#define MODNAME "posix"
396#endif
397
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200398
399#ifdef HAVE_FORK
400static void
401run_at_forkers(PyObject *lst, int reverse)
402{
403 Py_ssize_t i;
404 PyObject *cpy;
405
406 if (lst != NULL) {
407 assert(PyList_CheckExact(lst));
408
409 /* Use a list copy in case register_at_fork() is called from
410 * one of the callbacks.
411 */
412 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
413 if (cpy == NULL)
414 PyErr_WriteUnraisable(lst);
415 else {
416 if (reverse)
417 PyList_Reverse(cpy);
418 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
419 PyObject *func, *res;
420 func = PyList_GET_ITEM(cpy, i);
421 res = PyObject_CallObject(func, NULL);
422 if (res == NULL)
423 PyErr_WriteUnraisable(func);
424 else
425 Py_DECREF(res);
426 }
427 Py_DECREF(cpy);
428 }
429 }
430}
431
432void
433PyOS_BeforeFork(void)
434{
435 run_at_forkers(PyThreadState_Get()->interp->before_forkers, 1);
436
437 _PyImport_AcquireLock();
438}
439
440void
441PyOS_AfterFork_Parent(void)
442{
443 if (_PyImport_ReleaseLock() <= 0)
444 Py_FatalError("failed releasing import lock after fork");
445
446 run_at_forkers(PyThreadState_Get()->interp->after_forkers_parent, 0);
447}
448
449void
450PyOS_AfterFork_Child(void)
451{
452#ifdef WITH_THREAD
453 /* PyThread_ReInitTLS() must be called early, to make sure that the TLS API
454 * can be called safely. */
455 PyThread_ReInitTLS();
456 _PyGILState_Reinit();
457 PyEval_ReInitThreads();
458 _PyImport_ReInitLock();
459#endif
460 _PySignal_AfterFork();
461
462 run_at_forkers(PyThreadState_Get()->interp->after_forkers_child, 0);
463}
464
465static int
466register_at_forker(PyObject **lst, PyObject *func)
467{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700468 if (func == NULL) /* nothing to register? do nothing. */
469 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200470 if (*lst == NULL) {
471 *lst = PyList_New(0);
472 if (*lst == NULL)
473 return -1;
474 }
475 return PyList_Append(*lst, func);
476}
477#endif
478
479/* Legacy wrapper */
480void
481PyOS_AfterFork(void)
482{
483#ifdef HAVE_FORK
484 PyOS_AfterFork_Child();
485#endif
486}
487
488
Victor Stinner6036e442015-03-08 01:58:04 +0100489#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200490/* defined in fileutils.c */
491PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
492PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
493 ULONG, struct _Py_stat_struct *);
494#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700495
496#ifdef MS_WINDOWS
497static int
498win32_warn_bytes_api()
499{
500 return PyErr_WarnEx(PyExc_DeprecationWarning,
501 "The Windows bytes API has been deprecated, "
502 "use Unicode filenames instead",
503 1);
504}
505#endif
506
507
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200508#ifndef MS_WINDOWS
509PyObject *
510_PyLong_FromUid(uid_t uid)
511{
512 if (uid == (uid_t)-1)
513 return PyLong_FromLong(-1);
514 return PyLong_FromUnsignedLong(uid);
515}
516
517PyObject *
518_PyLong_FromGid(gid_t gid)
519{
520 if (gid == (gid_t)-1)
521 return PyLong_FromLong(-1);
522 return PyLong_FromUnsignedLong(gid);
523}
524
525int
526_Py_Uid_Converter(PyObject *obj, void *p)
527{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528 uid_t uid;
529 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200530 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200531 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700532 unsigned long uresult;
533
534 index = PyNumber_Index(obj);
535 if (index == NULL) {
536 PyErr_Format(PyExc_TypeError,
537 "uid should be integer, not %.200s",
538 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200539 return 0;
540 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700541
542 /*
543 * Handling uid_t is complicated for two reasons:
544 * * Although uid_t is (always?) unsigned, it still
545 * accepts -1.
546 * * We don't know its size in advance--it may be
547 * bigger than an int, or it may be smaller than
548 * a long.
549 *
550 * So a bit of defensive programming is in order.
551 * Start with interpreting the value passed
552 * in as a signed long and see if it works.
553 */
554
555 result = PyLong_AsLongAndOverflow(index, &overflow);
556
557 if (!overflow) {
558 uid = (uid_t)result;
559
560 if (result == -1) {
561 if (PyErr_Occurred())
562 goto fail;
563 /* It's a legitimate -1, we're done. */
564 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200565 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700566
567 /* Any other negative number is disallowed. */
568 if (result < 0)
569 goto underflow;
570
571 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200572 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700573 (long)uid != result)
574 goto underflow;
575 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200576 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700577
578 if (overflow < 0)
579 goto underflow;
580
581 /*
582 * Okay, the value overflowed a signed long. If it
583 * fits in an *unsigned* long, it may still be okay,
584 * as uid_t may be unsigned long on this platform.
585 */
586 uresult = PyLong_AsUnsignedLong(index);
587 if (PyErr_Occurred()) {
588 if (PyErr_ExceptionMatches(PyExc_OverflowError))
589 goto overflow;
590 goto fail;
591 }
592
593 uid = (uid_t)uresult;
594
595 /*
596 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
597 * but this value would get interpreted as (uid_t)-1 by chown
598 * and its siblings. That's not what the user meant! So we
599 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100600 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700601 */
602 if (uid == (uid_t)-1)
603 goto overflow;
604
605 /* Ensure the value wasn't truncated. */
606 if (sizeof(uid_t) < sizeof(long) &&
607 (unsigned long)uid != uresult)
608 goto overflow;
609 /* fallthrough */
610
611success:
612 Py_DECREF(index);
613 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200614 return 1;
615
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200617 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618 "uid is less than minimum");
619 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200620
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700621overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200622 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700623 "uid is greater than maximum");
624 /* fallthrough */
625
626fail:
627 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200628 return 0;
629}
630
631int
632_Py_Gid_Converter(PyObject *obj, void *p)
633{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700634 gid_t gid;
635 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200636 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200637 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700638 unsigned long uresult;
639
640 index = PyNumber_Index(obj);
641 if (index == NULL) {
642 PyErr_Format(PyExc_TypeError,
643 "gid should be integer, not %.200s",
644 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200645 return 0;
646 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700647
648 /*
649 * Handling gid_t is complicated for two reasons:
650 * * Although gid_t is (always?) unsigned, it still
651 * accepts -1.
652 * * We don't know its size in advance--it may be
653 * bigger than an int, or it may be smaller than
654 * a long.
655 *
656 * So a bit of defensive programming is in order.
657 * Start with interpreting the value passed
658 * in as a signed long and see if it works.
659 */
660
661 result = PyLong_AsLongAndOverflow(index, &overflow);
662
663 if (!overflow) {
664 gid = (gid_t)result;
665
666 if (result == -1) {
667 if (PyErr_Occurred())
668 goto fail;
669 /* It's a legitimate -1, we're done. */
670 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200671 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700672
673 /* Any other negative number is disallowed. */
674 if (result < 0) {
675 goto underflow;
676 }
677
678 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200679 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680 (long)gid != result)
681 goto underflow;
682 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200683 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684
685 if (overflow < 0)
686 goto underflow;
687
688 /*
689 * Okay, the value overflowed a signed long. If it
690 * fits in an *unsigned* long, it may still be okay,
691 * as gid_t may be unsigned long on this platform.
692 */
693 uresult = PyLong_AsUnsignedLong(index);
694 if (PyErr_Occurred()) {
695 if (PyErr_ExceptionMatches(PyExc_OverflowError))
696 goto overflow;
697 goto fail;
698 }
699
700 gid = (gid_t)uresult;
701
702 /*
703 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
704 * but this value would get interpreted as (gid_t)-1 by chown
705 * and its siblings. That's not what the user meant! So we
706 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100707 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700708 */
709 if (gid == (gid_t)-1)
710 goto overflow;
711
712 /* Ensure the value wasn't truncated. */
713 if (sizeof(gid_t) < sizeof(long) &&
714 (unsigned long)gid != uresult)
715 goto overflow;
716 /* fallthrough */
717
718success:
719 Py_DECREF(index);
720 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200721 return 1;
722
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700723underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200724 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700725 "gid is less than minimum");
726 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200727
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700728overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200729 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700730 "gid is greater than maximum");
731 /* fallthrough */
732
733fail:
734 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200735 return 0;
736}
737#endif /* MS_WINDOWS */
738
739
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700740#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800741
742
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200743#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
744static int
745_Py_Dev_Converter(PyObject *obj, void *p)
746{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200747 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200748 if (PyErr_Occurred())
749 return 0;
750 return 1;
751}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800752#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200753
754
Larry Hastings9cf065c2012-06-22 16:30:09 -0700755#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400756/*
757 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
758 * without the int cast, the value gets interpreted as uint (4291925331),
759 * which doesn't play nicely with all the initializer lines in this file that
760 * look like this:
761 * int dir_fd = DEFAULT_DIR_FD;
762 */
763#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700764#else
765#define DEFAULT_DIR_FD (-100)
766#endif
767
768static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300769_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200770{
771 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700772 long long_value;
773
774 PyObject *index = PyNumber_Index(o);
775 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700776 return 0;
777 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700778
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300779 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700780 long_value = PyLong_AsLongAndOverflow(index, &overflow);
781 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300782 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200783 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700784 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700785 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700786 return 0;
787 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200788 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700789 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700790 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700791 return 0;
792 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700793
Larry Hastings9cf065c2012-06-22 16:30:09 -0700794 *p = (int)long_value;
795 return 1;
796}
797
798static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200799dir_fd_converter(PyObject *o, void *p)
800{
801 if (o == Py_None) {
802 *(int *)p = DEFAULT_DIR_FD;
803 return 1;
804 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300805 else if (PyIndex_Check(o)) {
806 return _fd_converter(o, (int *)p);
807 }
808 else {
809 PyErr_Format(PyExc_TypeError,
810 "argument should be integer or None, not %.200s",
811 Py_TYPE(o)->tp_name);
812 return 0;
813 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700814}
815
816
Larry Hastings9cf065c2012-06-22 16:30:09 -0700817/*
818 * A PyArg_ParseTuple "converter" function
819 * that handles filesystem paths in the manner
820 * preferred by the os module.
821 *
822 * path_converter accepts (Unicode) strings and their
823 * subclasses, and bytes and their subclasses. What
824 * it does with the argument depends on the platform:
825 *
826 * * On Windows, if we get a (Unicode) string we
827 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700828 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700829 *
830 * * On all other platforms, strings are encoded
831 * to bytes using PyUnicode_FSConverter, then we
832 * extract the char * from the bytes object and
833 * return that.
834 *
835 * path_converter also optionally accepts signed
836 * integers (representing open file descriptors) instead
837 * of path strings.
838 *
839 * Input fields:
840 * path.nullable
841 * If nonzero, the path is permitted to be None.
842 * path.allow_fd
843 * If nonzero, the path is permitted to be a file handle
844 * (a signed int) instead of a string.
845 * path.function_name
846 * If non-NULL, path_converter will use that as the name
847 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700848 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700849 * path.argument_name
850 * If non-NULL, path_converter will use that as the name
851 * of the parameter in error messages.
852 * (If path.argument_name is NULL it uses "path".)
853 *
854 * Output fields:
855 * path.wide
856 * Points to the path if it was expressed as Unicode
857 * and was not encoded. (Only used on Windows.)
858 * path.narrow
859 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700860 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000861 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700862 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700863 * path.fd
864 * Contains a file descriptor if path.accept_fd was true
865 * and the caller provided a signed integer instead of any
866 * sort of string.
867 *
868 * WARNING: if your "path" parameter is optional, and is
869 * unspecified, path_converter will never get called.
870 * So if you set allow_fd, you *MUST* initialize path.fd = -1
871 * yourself!
872 * path.length
873 * The length of the path in characters, if specified as
874 * a string.
875 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800876 * The original object passed in (if get a PathLike object,
877 * the result of PyOS_FSPath() is treated as the original object).
878 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700879 * path.cleanup
880 * For internal use only. May point to a temporary object.
881 * (Pay no attention to the man behind the curtain.)
882 *
883 * At most one of path.wide or path.narrow will be non-NULL.
884 * If path was None and path.nullable was set,
885 * or if path was an integer and path.allow_fd was set,
886 * both path.wide and path.narrow will be NULL
887 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200888 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700889 * path_converter takes care to not write to the path_t
890 * unless it's successful. However it must reset the
891 * "cleanup" field each time it's called.
892 *
893 * Use as follows:
894 * path_t path;
895 * memset(&path, 0, sizeof(path));
896 * PyArg_ParseTuple(args, "O&", path_converter, &path);
897 * // ... use values from path ...
898 * path_cleanup(&path);
899 *
900 * (Note that if PyArg_Parse fails you don't need to call
901 * path_cleanup(). However it is safe to do so.)
902 */
903typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100904 const char *function_name;
905 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700906 int nullable;
907 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300908 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700909#ifdef MS_WINDOWS
910 BOOL narrow;
911#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300912 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700913#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700914 int fd;
915 Py_ssize_t length;
916 PyObject *object;
917 PyObject *cleanup;
918} path_t;
919
Steve Dowercc16be82016-09-08 10:35:16 -0700920#ifdef MS_WINDOWS
921#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
922 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
923#else
Larry Hastings2f936352014-08-05 14:04:04 +1000924#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
925 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700926#endif
Larry Hastings31826802013-10-19 00:09:25 -0700927
Larry Hastings9cf065c2012-06-22 16:30:09 -0700928static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800929path_cleanup(path_t *path)
930{
931 Py_CLEAR(path->object);
932 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700933}
934
935static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300936path_converter(PyObject *o, void *p)
937{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700938 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800939 PyObject *bytes = NULL;
940 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700941 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300942 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700943#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800944 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700945 const wchar_t *wide;
946#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700947
948#define FORMAT_EXCEPTION(exc, fmt) \
949 PyErr_Format(exc, "%s%s" fmt, \
950 path->function_name ? path->function_name : "", \
951 path->function_name ? ": " : "", \
952 path->argument_name ? path->argument_name : "path")
953
954 /* Py_CLEANUP_SUPPORTED support */
955 if (o == NULL) {
956 path_cleanup(path);
957 return 1;
958 }
959
Brett Cannon3f9183b2016-08-26 14:44:48 -0700960 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800961 path->object = path->cleanup = NULL;
962 /* path->object owns a reference to the original object */
963 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700964
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300965 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700967#ifdef MS_WINDOWS
968 path->narrow = FALSE;
969#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700970 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700971#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700972 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800973 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700974 }
975
Brett Cannon3f9183b2016-08-26 14:44:48 -0700976 /* Only call this here so that we don't treat the return value of
977 os.fspath() as an fd or buffer. */
978 is_index = path->allow_fd && PyIndex_Check(o);
979 is_buffer = PyObject_CheckBuffer(o);
980 is_bytes = PyBytes_Check(o);
981 is_unicode = PyUnicode_Check(o);
982
983 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
984 /* Inline PyOS_FSPath() for better error messages. */
985 _Py_IDENTIFIER(__fspath__);
986 PyObject *func = NULL;
987
988 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
989 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800990 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700991 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800992 /* still owns a reference to the original object */
993 Py_DECREF(o);
994 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700995 Py_DECREF(func);
996 if (NULL == o) {
997 goto error_exit;
998 }
999 else if (PyUnicode_Check(o)) {
1000 is_unicode = 1;
1001 }
1002 else if (PyBytes_Check(o)) {
1003 is_bytes = 1;
1004 }
1005 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001006 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001007 }
1008 }
1009
1010 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001011#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001012 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001013 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001014 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001015 }
Victor Stinner59799a82013-11-13 14:17:30 +01001016 if (length > 32767) {
1017 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001018 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001019 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001020 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001021 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001022 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001023 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001024
1025 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001026 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001027 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001028 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001029#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001030 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001031 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001032 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001033#endif
1034 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001035 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001036 bytes = o;
1037 Py_INCREF(bytes);
1038 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001039 else if (is_buffer) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001040 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1041 "%s%s%s should be %s, not %.200s",
1042 path->function_name ? path->function_name : "",
1043 path->function_name ? ": " : "",
1044 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001045 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1046 "integer or None" :
1047 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1048 path->nullable ? "string, bytes, os.PathLike or None" :
1049 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001050 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001051 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001052 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001053 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001054 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001055 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001056 }
1057 }
Steve Dowercc16be82016-09-08 10:35:16 -07001058 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001059 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001060 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001061 }
1062 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001063#ifdef MS_WINDOWS
1064 path->narrow = FALSE;
1065#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001066 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001067#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001068 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001069 }
1070 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001071 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001072 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1073 path->function_name ? path->function_name : "",
1074 path->function_name ? ": " : "",
1075 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001076 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1077 "integer or None" :
1078 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1079 path->nullable ? "string, bytes, os.PathLike or None" :
1080 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001081 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001082 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001083 }
1084
Larry Hastings9cf065c2012-06-22 16:30:09 -07001085 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001086 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001087 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001088 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001089 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001090 }
1091
Steve Dowercc16be82016-09-08 10:35:16 -07001092#ifdef MS_WINDOWS
1093 wo = PyUnicode_DecodeFSDefaultAndSize(
1094 narrow,
1095 length
1096 );
1097 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001098 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001099 }
1100
Xiang Zhang04316c42017-01-08 23:26:57 +08001101 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001102 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001103 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001104 }
1105 if (length > 32767) {
1106 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001107 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001108 }
1109 if (wcslen(wide) != length) {
1110 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001111 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001112 }
1113 path->wide = wide;
1114 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001115 path->cleanup = wo;
1116 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001117#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001118 path->wide = NULL;
1119 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001120 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001121 /* Still a reference owned by path->object, don't have to
1122 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001123 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001124 }
1125 else {
1126 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001127 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001128#endif
1129 path->fd = -1;
1130
1131 success_exit:
1132 path->length = length;
1133 path->object = o;
1134 return Py_CLEANUP_SUPPORTED;
1135
1136 error_exit:
1137 Py_XDECREF(o);
1138 Py_XDECREF(bytes);
1139#ifdef MS_WINDOWS
1140 Py_XDECREF(wo);
1141#endif
1142 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001143}
1144
1145static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001146argument_unavailable_error(const char *function_name, const char *argument_name)
1147{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001148 PyErr_Format(PyExc_NotImplementedError,
1149 "%s%s%s unavailable on this platform",
1150 (function_name != NULL) ? function_name : "",
1151 (function_name != NULL) ? ": ": "",
1152 argument_name);
1153}
1154
1155static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001156dir_fd_unavailable(PyObject *o, void *p)
1157{
1158 int dir_fd;
1159 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001160 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001161 if (dir_fd != DEFAULT_DIR_FD) {
1162 argument_unavailable_error(NULL, "dir_fd");
1163 return 0;
1164 }
1165 *(int *)p = dir_fd;
1166 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001167}
1168
1169static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001170fd_specified(const char *function_name, int fd)
1171{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001172 if (fd == -1)
1173 return 0;
1174
1175 argument_unavailable_error(function_name, "fd");
1176 return 1;
1177}
1178
1179static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001180follow_symlinks_specified(const char *function_name, int follow_symlinks)
1181{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001182 if (follow_symlinks)
1183 return 0;
1184
1185 argument_unavailable_error(function_name, "follow_symlinks");
1186 return 1;
1187}
1188
1189static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001190path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1191{
Steve Dowercc16be82016-09-08 10:35:16 -07001192 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1193#ifndef MS_WINDOWS
1194 && !path->narrow
1195#endif
1196 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001197 PyErr_Format(PyExc_ValueError,
1198 "%s: can't specify dir_fd without matching path",
1199 function_name);
1200 return 1;
1201 }
1202 return 0;
1203}
1204
1205static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001206dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1207{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001208 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1209 PyErr_Format(PyExc_ValueError,
1210 "%s: can't specify both dir_fd and fd",
1211 function_name);
1212 return 1;
1213 }
1214 return 0;
1215}
1216
1217static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001218fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1219 int follow_symlinks)
1220{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001221 if ((fd > 0) && (!follow_symlinks)) {
1222 PyErr_Format(PyExc_ValueError,
1223 "%s: cannot use fd and follow_symlinks together",
1224 function_name);
1225 return 1;
1226 }
1227 return 0;
1228}
1229
1230static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001231dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1232 int follow_symlinks)
1233{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001234 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1235 PyErr_Format(PyExc_ValueError,
1236 "%s: cannot use dir_fd and follow_symlinks together",
1237 function_name);
1238 return 1;
1239 }
1240 return 0;
1241}
1242
Larry Hastings2f936352014-08-05 14:04:04 +10001243#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001244 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001245#else
Larry Hastings2f936352014-08-05 14:04:04 +10001246 typedef off_t Py_off_t;
1247#endif
1248
1249static int
1250Py_off_t_converter(PyObject *arg, void *addr)
1251{
1252#ifdef HAVE_LARGEFILE_SUPPORT
1253 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1254#else
1255 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001256#endif
1257 if (PyErr_Occurred())
1258 return 0;
1259 return 1;
1260}
Larry Hastings2f936352014-08-05 14:04:04 +10001261
1262static PyObject *
1263PyLong_FromPy_off_t(Py_off_t offset)
1264{
1265#ifdef HAVE_LARGEFILE_SUPPORT
1266 return PyLong_FromLongLong(offset);
1267#else
1268 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001269#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001270}
1271
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001272#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001273
1274static int
Brian Curtind25aef52011-06-13 15:16:04 -05001275win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001276{
Martin Panter70214ad2016-08-04 02:38:59 +00001277 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1278 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001279 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001280
1281 if (0 == DeviceIoControl(
1282 reparse_point_handle,
1283 FSCTL_GET_REPARSE_POINT,
1284 NULL, 0, /* in buffer */
1285 target_buffer, sizeof(target_buffer),
1286 &n_bytes_returned,
1287 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001288 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001289
1290 if (reparse_tag)
1291 *reparse_tag = rdb->ReparseTag;
1292
Brian Curtind25aef52011-06-13 15:16:04 -05001293 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001294}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001295
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001296#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001297
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001298/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001299#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001300/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001301** environ directly, we must obtain it with _NSGetEnviron(). See also
1302** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001303*/
1304#include <crt_externs.h>
1305static char **environ;
1306#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001307extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001308#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001309
Barry Warsaw53699e91996-12-10 23:23:01 +00001310static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001311convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001312{
Victor Stinner8c62be82010-05-06 00:08:46 +00001313 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001314#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001315 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001316#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001317 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001318#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001319
Victor Stinner8c62be82010-05-06 00:08:46 +00001320 d = PyDict_New();
1321 if (d == NULL)
1322 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001323#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001324 if (environ == NULL)
1325 environ = *_NSGetEnviron();
1326#endif
1327#ifdef MS_WINDOWS
1328 /* _wenviron must be initialized in this way if the program is started
1329 through main() instead of wmain(). */
1330 _wgetenv(L"");
1331 if (_wenviron == NULL)
1332 return d;
1333 /* This part ignores errors */
1334 for (e = _wenviron; *e != NULL; e++) {
1335 PyObject *k;
1336 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001337 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001338 if (p == NULL)
1339 continue;
1340 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1341 if (k == NULL) {
1342 PyErr_Clear();
1343 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001344 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001345 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1346 if (v == NULL) {
1347 PyErr_Clear();
1348 Py_DECREF(k);
1349 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001350 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001351 if (PyDict_GetItem(d, k) == NULL) {
1352 if (PyDict_SetItem(d, k, v) != 0)
1353 PyErr_Clear();
1354 }
1355 Py_DECREF(k);
1356 Py_DECREF(v);
1357 }
1358#else
1359 if (environ == NULL)
1360 return d;
1361 /* This part ignores errors */
1362 for (e = environ; *e != NULL; e++) {
1363 PyObject *k;
1364 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001365 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 if (p == NULL)
1367 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001368 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001369 if (k == NULL) {
1370 PyErr_Clear();
1371 continue;
1372 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001373 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001374 if (v == NULL) {
1375 PyErr_Clear();
1376 Py_DECREF(k);
1377 continue;
1378 }
1379 if (PyDict_GetItem(d, k) == NULL) {
1380 if (PyDict_SetItem(d, k, v) != 0)
1381 PyErr_Clear();
1382 }
1383 Py_DECREF(k);
1384 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001385 }
1386#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001387 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001388}
1389
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001390/* Set a POSIX-specific error from errno, and return NULL */
1391
Barry Warsawd58d7641998-07-23 16:14:40 +00001392static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001393posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001394{
Victor Stinner8c62be82010-05-06 00:08:46 +00001395 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001396}
Mark Hammondef8b6542001-05-13 08:04:26 +00001397
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001398#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001399static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001400win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001401{
Victor Stinner8c62be82010-05-06 00:08:46 +00001402 /* XXX We should pass the function name along in the future.
1403 (winreg.c also wants to pass the function name.)
1404 This would however require an additional param to the
1405 Windows error object, which is non-trivial.
1406 */
1407 errno = GetLastError();
1408 if (filename)
1409 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1410 else
1411 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001412}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001413
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001414static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001415win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001416{
1417 /* XXX - see win32_error for comments on 'function' */
1418 errno = GetLastError();
1419 if (filename)
1420 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001421 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001422 errno,
1423 filename);
1424 else
1425 return PyErr_SetFromWindowsErr(errno);
1426}
1427
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001428#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001429
Larry Hastings9cf065c2012-06-22 16:30:09 -07001430static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001431path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001432{
1433#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001434 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1435 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001436#else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001437 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001438#endif
1439}
1440
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001441static PyObject *
1442path_object_error2(PyObject *path, PyObject *path2)
1443{
1444#ifdef MS_WINDOWS
1445 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1446 PyExc_OSError, 0, path, path2);
1447#else
1448 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1449#endif
1450}
1451
1452static PyObject *
1453path_error(path_t *path)
1454{
1455 return path_object_error(path->object);
1456}
Larry Hastings31826802013-10-19 00:09:25 -07001457
Larry Hastingsb0827312014-02-09 22:05:19 -08001458static PyObject *
1459path_error2(path_t *path, path_t *path2)
1460{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001461 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001462}
1463
1464
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001465/* POSIX generic methods */
1466
Larry Hastings2f936352014-08-05 14:04:04 +10001467static int
1468fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001469{
Victor Stinner8c62be82010-05-06 00:08:46 +00001470 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001471 int *pointer = (int *)p;
1472 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001473 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001474 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001475 *pointer = fd;
1476 return 1;
1477}
1478
1479static PyObject *
1480posix_fildes_fd(int fd, int (*func)(int))
1481{
1482 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001483 int async_err = 0;
1484
1485 do {
1486 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001487 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001488 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001489 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001490 Py_END_ALLOW_THREADS
1491 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1492 if (res != 0)
1493 return (!async_err) ? posix_error() : NULL;
1494 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001495}
Guido van Rossum21142a01999-01-08 21:05:37 +00001496
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001497
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001498#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001499/* This is a reimplementation of the C library's chdir function,
1500 but one that produces Win32 errors instead of DOS error codes.
1501 chdir is essentially a wrapper around SetCurrentDirectory; however,
1502 it also needs to set "magic" environment variables indicating
1503 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001504static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001505win32_wchdir(LPCWSTR path)
1506{
Victor Stinnered537822015-12-13 21:40:26 +01001507 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001508 int result;
1509 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510
Victor Stinner8c62be82010-05-06 00:08:46 +00001511 if(!SetCurrentDirectoryW(path))
1512 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001513 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001514 if (!result)
1515 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001516 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001517 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001518 if (!new_path) {
1519 SetLastError(ERROR_OUTOFMEMORY);
1520 return FALSE;
1521 }
1522 result = GetCurrentDirectoryW(result, new_path);
1523 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001524 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001525 return FALSE;
1526 }
1527 }
1528 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1529 wcsncmp(new_path, L"//", 2) == 0)
1530 /* UNC path, nothing to do. */
1531 return TRUE;
1532 env[1] = new_path[0];
1533 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001534 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001535 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001536 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001537}
1538#endif
1539
Martin v. Löwis14694662006-02-03 12:54:16 +00001540#ifdef MS_WINDOWS
1541/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1542 - time stamps are restricted to second resolution
1543 - file modification times suffer from forth-and-back conversions between
1544 UTC and local time
1545 Therefore, we implement our own stat, based on the Win32 API directly.
1546*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001547#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001548#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001549
Victor Stinner6036e442015-03-08 01:58:04 +01001550static void
Steve Dowercc16be82016-09-08 10:35:16 -07001551find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1552 BY_HANDLE_FILE_INFORMATION *info,
1553 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001554{
1555 memset(info, 0, sizeof(*info));
1556 info->dwFileAttributes = pFileData->dwFileAttributes;
1557 info->ftCreationTime = pFileData->ftCreationTime;
1558 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1559 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1560 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1561 info->nFileSizeLow = pFileData->nFileSizeLow;
1562/* info->nNumberOfLinks = 1; */
1563 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1564 *reparse_tag = pFileData->dwReserved0;
1565 else
1566 *reparse_tag = 0;
1567}
1568
Guido van Rossumd8faa362007-04-27 19:54:29 +00001569static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001570attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001571{
Victor Stinner8c62be82010-05-06 00:08:46 +00001572 HANDLE hFindFile;
1573 WIN32_FIND_DATAW FileData;
1574 hFindFile = FindFirstFileW(pszFile, &FileData);
1575 if (hFindFile == INVALID_HANDLE_VALUE)
1576 return FALSE;
1577 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001578 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001579 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001580}
1581
Brian Curtind25aef52011-06-13 15:16:04 -05001582static BOOL
1583get_target_path(HANDLE hdl, wchar_t **target_path)
1584{
1585 int buf_size, result_length;
1586 wchar_t *buf;
1587
1588 /* We have a good handle to the target, use it to determine
1589 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001590 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1591 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001592 if(!buf_size)
1593 return FALSE;
1594
Victor Stinnerc36674a2016-03-16 14:30:16 +01001595 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001596 if (!buf) {
1597 SetLastError(ERROR_OUTOFMEMORY);
1598 return FALSE;
1599 }
1600
Steve Dower2ea51c92015-03-20 21:49:12 -07001601 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001602 buf, buf_size, VOLUME_NAME_DOS);
1603
1604 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001605 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001606 return FALSE;
1607 }
1608
1609 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001610 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001611 return FALSE;
1612 }
1613
1614 buf[result_length] = 0;
1615
1616 *target_path = buf;
1617 return TRUE;
1618}
1619
1620static int
Steve Dowercc16be82016-09-08 10:35:16 -07001621win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001622 BOOL traverse)
1623{
Victor Stinner26de69d2011-06-17 15:15:38 +02001624 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001625 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001626 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001627 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001628 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001629 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001630
Steve Dowercc16be82016-09-08 10:35:16 -07001631 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001632 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001633 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001634 0, /* share mode */
1635 NULL, /* security attributes */
1636 OPEN_EXISTING,
1637 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001638 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1639 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001640 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001641 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1642 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001643 NULL);
1644
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001645 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001646 /* Either the target doesn't exist, or we don't have access to
1647 get a handle to it. If the former, we need to return an error.
1648 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001649 DWORD lastError = GetLastError();
1650 if (lastError != ERROR_ACCESS_DENIED &&
1651 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001652 return -1;
1653 /* Could not get attributes on open file. Fall back to
1654 reading the directory. */
1655 if (!attributes_from_dir(path, &info, &reparse_tag))
1656 /* Very strange. This should not fail now */
1657 return -1;
1658 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1659 if (traverse) {
1660 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001661 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001662 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001663 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001664 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001665 } else {
1666 if (!GetFileInformationByHandle(hFile, &info)) {
1667 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001668 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001669 }
1670 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001671 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1672 return -1;
1673
1674 /* Close the outer open file handle now that we're about to
1675 reopen it with different flags. */
1676 if (!CloseHandle(hFile))
1677 return -1;
1678
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001679 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001680 /* In order to call GetFinalPathNameByHandle we need to open
1681 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001682 hFile2 = CreateFileW(
1683 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1684 NULL, OPEN_EXISTING,
1685 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1686 NULL);
1687 if (hFile2 == INVALID_HANDLE_VALUE)
1688 return -1;
1689
1690 if (!get_target_path(hFile2, &target_path))
1691 return -1;
1692
Steve Dowercc16be82016-09-08 10:35:16 -07001693 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001694 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001695 return code;
1696 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001697 } else
1698 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001699 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001700 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001701
1702 /* Set S_IEXEC if it is an .exe, .bat, ... */
1703 dot = wcsrchr(path, '.');
1704 if (dot) {
1705 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1706 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1707 result->st_mode |= 0111;
1708 }
1709 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001710}
1711
1712static int
Steve Dowercc16be82016-09-08 10:35:16 -07001713win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001714{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001715 /* Protocol violation: we explicitly clear errno, instead of
1716 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001717 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001718 errno = 0;
1719 return code;
1720}
Brian Curtind25aef52011-06-13 15:16:04 -05001721/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001722
1723 In Posix, stat automatically traverses symlinks and returns the stat
1724 structure for the target. In Windows, the equivalent GetFileAttributes by
1725 default does not traverse symlinks and instead returns attributes for
1726 the symlink.
1727
1728 Therefore, win32_lstat will get the attributes traditionally, and
1729 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001730 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001731
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001732static int
Steve Dowercc16be82016-09-08 10:35:16 -07001733win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001734{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001735 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001736}
1737
Victor Stinner8c62be82010-05-06 00:08:46 +00001738static int
Steve Dowercc16be82016-09-08 10:35:16 -07001739win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001740{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001741 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001742}
1743
Martin v. Löwis14694662006-02-03 12:54:16 +00001744#endif /* MS_WINDOWS */
1745
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001746PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001747"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001748This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001749 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001750or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1751\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001752Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1753or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001754\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001755See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001756
1757static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001758 {"st_mode", "protection bits"},
1759 {"st_ino", "inode"},
1760 {"st_dev", "device"},
1761 {"st_nlink", "number of hard links"},
1762 {"st_uid", "user ID of owner"},
1763 {"st_gid", "group ID of owner"},
1764 {"st_size", "total size, in bytes"},
1765 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1766 {NULL, "integer time of last access"},
1767 {NULL, "integer time of last modification"},
1768 {NULL, "integer time of last change"},
1769 {"st_atime", "time of last access"},
1770 {"st_mtime", "time of last modification"},
1771 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001772 {"st_atime_ns", "time of last access in nanoseconds"},
1773 {"st_mtime_ns", "time of last modification in nanoseconds"},
1774 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001775#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001776 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001777#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001778#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001779 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001780#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001781#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001782 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001783#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001784#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001785 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001786#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001787#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001789#endif
1790#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001791 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001792#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001793#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1794 {"st_file_attributes", "Windows file attribute bits"},
1795#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001796 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001797};
1798
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001799#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001800#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001801#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001802#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001803#endif
1804
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001805#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001806#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1807#else
1808#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1809#endif
1810
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001811#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001812#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1813#else
1814#define ST_RDEV_IDX ST_BLOCKS_IDX
1815#endif
1816
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001817#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1818#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1819#else
1820#define ST_FLAGS_IDX ST_RDEV_IDX
1821#endif
1822
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001823#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001824#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001825#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001826#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001827#endif
1828
1829#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1830#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1831#else
1832#define ST_BIRTHTIME_IDX ST_GEN_IDX
1833#endif
1834
Zachary Ware63f277b2014-06-19 09:46:37 -05001835#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1836#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1837#else
1838#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1839#endif
1840
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001841static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001842 "stat_result", /* name */
1843 stat_result__doc__, /* doc */
1844 stat_result_fields,
1845 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001846};
1847
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001848PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001849"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1850This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001851 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001852or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001853\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001854See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001855
1856static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001857 {"f_bsize", },
1858 {"f_frsize", },
1859 {"f_blocks", },
1860 {"f_bfree", },
1861 {"f_bavail", },
1862 {"f_files", },
1863 {"f_ffree", },
1864 {"f_favail", },
1865 {"f_flag", },
1866 {"f_namemax",},
1867 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001868};
1869
1870static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001871 "statvfs_result", /* name */
1872 statvfs_result__doc__, /* doc */
1873 statvfs_result_fields,
1874 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001875};
1876
Ross Lagerwall7807c352011-03-17 20:20:30 +02001877#if defined(HAVE_WAITID) && !defined(__APPLE__)
1878PyDoc_STRVAR(waitid_result__doc__,
1879"waitid_result: Result from waitid.\n\n\
1880This object may be accessed either as a tuple of\n\
1881 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1882or via the attributes si_pid, si_uid, and so on.\n\
1883\n\
1884See os.waitid for more information.");
1885
1886static PyStructSequence_Field waitid_result_fields[] = {
1887 {"si_pid", },
1888 {"si_uid", },
1889 {"si_signo", },
1890 {"si_status", },
1891 {"si_code", },
1892 {0}
1893};
1894
1895static PyStructSequence_Desc waitid_result_desc = {
1896 "waitid_result", /* name */
1897 waitid_result__doc__, /* doc */
1898 waitid_result_fields,
1899 5
1900};
1901static PyTypeObject WaitidResultType;
1902#endif
1903
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001904static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001905static PyTypeObject StatResultType;
1906static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001907#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001908static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001909#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001910static newfunc structseq_new;
1911
1912static PyObject *
1913statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1914{
Victor Stinner8c62be82010-05-06 00:08:46 +00001915 PyStructSequence *result;
1916 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001917
Victor Stinner8c62be82010-05-06 00:08:46 +00001918 result = (PyStructSequence*)structseq_new(type, args, kwds);
1919 if (!result)
1920 return NULL;
1921 /* If we have been initialized from a tuple,
1922 st_?time might be set to None. Initialize it
1923 from the int slots. */
1924 for (i = 7; i <= 9; i++) {
1925 if (result->ob_item[i+3] == Py_None) {
1926 Py_DECREF(Py_None);
1927 Py_INCREF(result->ob_item[i]);
1928 result->ob_item[i+3] = result->ob_item[i];
1929 }
1930 }
1931 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001932}
1933
1934
1935
1936/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001937static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001938
1939PyDoc_STRVAR(stat_float_times__doc__,
1940"stat_float_times([newval]) -> oldval\n\n\
1941Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001942\n\
1943If value is True, future calls to stat() return floats; if it is False,\n\
1944future calls return ints.\n\
1945If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001946
Larry Hastings2f936352014-08-05 14:04:04 +10001947/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001948static PyObject*
1949stat_float_times(PyObject* self, PyObject *args)
1950{
Victor Stinner8c62be82010-05-06 00:08:46 +00001951 int newval = -1;
1952 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1953 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001954 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1955 "stat_float_times() is deprecated",
1956 1))
1957 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 if (newval == -1)
1959 /* Return old value */
1960 return PyBool_FromLong(_stat_float_times);
1961 _stat_float_times = newval;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001962 Py_RETURN_NONE;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001963}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001964
Larry Hastings6fe20b32012-04-19 15:07:49 -07001965static PyObject *billion = NULL;
1966
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001967static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001968fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001969{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001970 PyObject *s = _PyLong_FromTime_t(sec);
1971 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1972 PyObject *s_in_ns = NULL;
1973 PyObject *ns_total = NULL;
1974 PyObject *float_s = NULL;
1975
1976 if (!(s && ns_fractional))
1977 goto exit;
1978
1979 s_in_ns = PyNumber_Multiply(s, billion);
1980 if (!s_in_ns)
1981 goto exit;
1982
1983 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1984 if (!ns_total)
1985 goto exit;
1986
Victor Stinner4195b5c2012-02-08 23:03:19 +01001987 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001988 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1989 if (!float_s)
1990 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001992 else {
1993 float_s = s;
1994 Py_INCREF(float_s);
1995 }
1996
1997 PyStructSequence_SET_ITEM(v, index, s);
1998 PyStructSequence_SET_ITEM(v, index+3, float_s);
1999 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2000 s = NULL;
2001 float_s = NULL;
2002 ns_total = NULL;
2003exit:
2004 Py_XDECREF(s);
2005 Py_XDECREF(ns_fractional);
2006 Py_XDECREF(s_in_ns);
2007 Py_XDECREF(ns_total);
2008 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002009}
2010
Tim Peters5aa91602002-01-30 05:46:57 +00002011/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002012 (used by posix_stat() and posix_fstat()) */
2013static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002014_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002015{
Victor Stinner8c62be82010-05-06 00:08:46 +00002016 unsigned long ansec, mnsec, cnsec;
2017 PyObject *v = PyStructSequence_New(&StatResultType);
2018 if (v == NULL)
2019 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002020
Victor Stinner8c62be82010-05-06 00:08:46 +00002021 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002022 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002023 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002024#ifdef MS_WINDOWS
2025 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002026#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002027 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002028#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002030#if defined(MS_WINDOWS)
2031 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2032 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2033#else
2034 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2035 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2036#endif
xdegaye50e86032017-05-22 11:15:08 +02002037 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2038 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002039
Martin v. Löwis14694662006-02-03 12:54:16 +00002040#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 ansec = st->st_atim.tv_nsec;
2042 mnsec = st->st_mtim.tv_nsec;
2043 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002044#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002045 ansec = st->st_atimespec.tv_nsec;
2046 mnsec = st->st_mtimespec.tv_nsec;
2047 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002048#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002049 ansec = st->st_atime_nsec;
2050 mnsec = st->st_mtime_nsec;
2051 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002052#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002054#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002055 fill_time(v, 7, st->st_atime, ansec);
2056 fill_time(v, 8, st->st_mtime, mnsec);
2057 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002058
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002059#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002060 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2061 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002062#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002063#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002064 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2065 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002066#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002067#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002068 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2069 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002070#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002071#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002072 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2073 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002074#endif
2075#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002076 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002077 PyObject *val;
2078 unsigned long bsec,bnsec;
2079 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002080#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002081 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002082#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002083 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002084#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002085 if (_stat_float_times) {
2086 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2087 } else {
2088 val = PyLong_FromLong((long)bsec);
2089 }
2090 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2091 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002092 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002093#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002094#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002095 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2096 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002097#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002098#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2099 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2100 PyLong_FromUnsignedLong(st->st_file_attributes));
2101#endif
Fred Drake699f3522000-06-29 21:12:41 +00002102
Victor Stinner8c62be82010-05-06 00:08:46 +00002103 if (PyErr_Occurred()) {
2104 Py_DECREF(v);
2105 return NULL;
2106 }
Fred Drake699f3522000-06-29 21:12:41 +00002107
Victor Stinner8c62be82010-05-06 00:08:46 +00002108 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002109}
2110
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002111/* POSIX methods */
2112
Guido van Rossum94f6f721999-01-06 18:42:14 +00002113
2114static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002115posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002116 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002117{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002118 STRUCT_STAT st;
2119 int result;
2120
2121#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2122 if (follow_symlinks_specified(function_name, follow_symlinks))
2123 return NULL;
2124#endif
2125
2126 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2127 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2128 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2129 return NULL;
2130
2131 Py_BEGIN_ALLOW_THREADS
2132 if (path->fd != -1)
2133 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002134#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002135 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002136 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002137 else
Steve Dowercc16be82016-09-08 10:35:16 -07002138 result = win32_lstat(path->wide, &st);
2139#else
2140 else
2141#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002142 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2143 result = LSTAT(path->narrow, &st);
2144 else
Steve Dowercc16be82016-09-08 10:35:16 -07002145#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002146#ifdef HAVE_FSTATAT
2147 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2148 result = fstatat(dir_fd, path->narrow, &st,
2149 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2150 else
Steve Dowercc16be82016-09-08 10:35:16 -07002151#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002152 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002153#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002154 Py_END_ALLOW_THREADS
2155
Victor Stinner292c8352012-10-30 02:17:38 +01002156 if (result != 0) {
2157 return path_error(path);
2158 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002159
2160 return _pystat_fromstructstat(&st);
2161}
2162
Larry Hastings2f936352014-08-05 14:04:04 +10002163/*[python input]
2164
2165for s in """
2166
2167FACCESSAT
2168FCHMODAT
2169FCHOWNAT
2170FSTATAT
2171LINKAT
2172MKDIRAT
2173MKFIFOAT
2174MKNODAT
2175OPENAT
2176READLINKAT
2177SYMLINKAT
2178UNLINKAT
2179
2180""".strip().split():
2181 s = s.strip()
2182 print("""
2183#ifdef HAVE_{s}
2184 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002185#else
Larry Hastings2f936352014-08-05 14:04:04 +10002186 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002187#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002188""".rstrip().format(s=s))
2189
2190for s in """
2191
2192FCHDIR
2193FCHMOD
2194FCHOWN
2195FDOPENDIR
2196FEXECVE
2197FPATHCONF
2198FSTATVFS
2199FTRUNCATE
2200
2201""".strip().split():
2202 s = s.strip()
2203 print("""
2204#ifdef HAVE_{s}
2205 #define PATH_HAVE_{s} 1
2206#else
2207 #define PATH_HAVE_{s} 0
2208#endif
2209
2210""".rstrip().format(s=s))
2211[python start generated code]*/
2212
2213#ifdef HAVE_FACCESSAT
2214 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2215#else
2216 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2217#endif
2218
2219#ifdef HAVE_FCHMODAT
2220 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2221#else
2222 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2223#endif
2224
2225#ifdef HAVE_FCHOWNAT
2226 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2227#else
2228 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2229#endif
2230
2231#ifdef HAVE_FSTATAT
2232 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2233#else
2234 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2235#endif
2236
2237#ifdef HAVE_LINKAT
2238 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2239#else
2240 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2241#endif
2242
2243#ifdef HAVE_MKDIRAT
2244 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2245#else
2246 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2247#endif
2248
2249#ifdef HAVE_MKFIFOAT
2250 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2251#else
2252 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2253#endif
2254
2255#ifdef HAVE_MKNODAT
2256 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2257#else
2258 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2259#endif
2260
2261#ifdef HAVE_OPENAT
2262 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2263#else
2264 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2265#endif
2266
2267#ifdef HAVE_READLINKAT
2268 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2269#else
2270 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2271#endif
2272
2273#ifdef HAVE_SYMLINKAT
2274 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2275#else
2276 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2277#endif
2278
2279#ifdef HAVE_UNLINKAT
2280 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2281#else
2282 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2283#endif
2284
2285#ifdef HAVE_FCHDIR
2286 #define PATH_HAVE_FCHDIR 1
2287#else
2288 #define PATH_HAVE_FCHDIR 0
2289#endif
2290
2291#ifdef HAVE_FCHMOD
2292 #define PATH_HAVE_FCHMOD 1
2293#else
2294 #define PATH_HAVE_FCHMOD 0
2295#endif
2296
2297#ifdef HAVE_FCHOWN
2298 #define PATH_HAVE_FCHOWN 1
2299#else
2300 #define PATH_HAVE_FCHOWN 0
2301#endif
2302
2303#ifdef HAVE_FDOPENDIR
2304 #define PATH_HAVE_FDOPENDIR 1
2305#else
2306 #define PATH_HAVE_FDOPENDIR 0
2307#endif
2308
2309#ifdef HAVE_FEXECVE
2310 #define PATH_HAVE_FEXECVE 1
2311#else
2312 #define PATH_HAVE_FEXECVE 0
2313#endif
2314
2315#ifdef HAVE_FPATHCONF
2316 #define PATH_HAVE_FPATHCONF 1
2317#else
2318 #define PATH_HAVE_FPATHCONF 0
2319#endif
2320
2321#ifdef HAVE_FSTATVFS
2322 #define PATH_HAVE_FSTATVFS 1
2323#else
2324 #define PATH_HAVE_FSTATVFS 0
2325#endif
2326
2327#ifdef HAVE_FTRUNCATE
2328 #define PATH_HAVE_FTRUNCATE 1
2329#else
2330 #define PATH_HAVE_FTRUNCATE 0
2331#endif
2332/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002333
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002334#ifdef MS_WINDOWS
2335 #undef PATH_HAVE_FTRUNCATE
2336 #define PATH_HAVE_FTRUNCATE 1
2337#endif
Larry Hastings31826802013-10-19 00:09:25 -07002338
Larry Hastings61272b72014-01-07 12:41:53 -08002339/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002340
2341class path_t_converter(CConverter):
2342
2343 type = "path_t"
2344 impl_by_reference = True
2345 parse_by_reference = True
2346
2347 converter = 'path_converter'
2348
2349 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002350 # right now path_t doesn't support default values.
2351 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002352 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002353 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002354
Larry Hastings2f936352014-08-05 14:04:04 +10002355 if self.c_default not in (None, 'Py_None'):
2356 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002357
2358 self.nullable = nullable
2359 self.allow_fd = allow_fd
2360
Larry Hastings7726ac92014-01-31 22:03:12 -08002361 def pre_render(self):
2362 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002363 if isinstance(value, str):
2364 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002365 return str(int(bool(value)))
2366
2367 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002368 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002369 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002370 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002371 strify(self.nullable),
2372 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002373 )
2374
2375 def cleanup(self):
2376 return "path_cleanup(&" + self.name + ");\n"
2377
2378
2379class dir_fd_converter(CConverter):
2380 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002381
Larry Hastings2f936352014-08-05 14:04:04 +10002382 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002383 if self.default in (unspecified, None):
2384 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002385 if isinstance(requires, str):
2386 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2387 else:
2388 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002389
Larry Hastings2f936352014-08-05 14:04:04 +10002390class fildes_converter(CConverter):
2391 type = 'int'
2392 converter = 'fildes_converter'
2393
2394class uid_t_converter(CConverter):
2395 type = "uid_t"
2396 converter = '_Py_Uid_Converter'
2397
2398class gid_t_converter(CConverter):
2399 type = "gid_t"
2400 converter = '_Py_Gid_Converter'
2401
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002402class dev_t_converter(CConverter):
2403 type = 'dev_t'
2404 converter = '_Py_Dev_Converter'
2405
2406class dev_t_return_converter(unsigned_long_return_converter):
2407 type = 'dev_t'
2408 conversion_fn = '_PyLong_FromDev'
2409 unsigned_cast = '(dev_t)'
2410
Larry Hastings2f936352014-08-05 14:04:04 +10002411class FSConverter_converter(CConverter):
2412 type = 'PyObject *'
2413 converter = 'PyUnicode_FSConverter'
2414 def converter_init(self):
2415 if self.default is not unspecified:
2416 fail("FSConverter_converter does not support default values")
2417 self.c_default = 'NULL'
2418
2419 def cleanup(self):
2420 return "Py_XDECREF(" + self.name + ");\n"
2421
2422class pid_t_converter(CConverter):
2423 type = 'pid_t'
2424 format_unit = '" _Py_PARSE_PID "'
2425
2426class idtype_t_converter(int_converter):
2427 type = 'idtype_t'
2428
2429class id_t_converter(CConverter):
2430 type = 'id_t'
2431 format_unit = '" _Py_PARSE_PID "'
2432
Benjamin Petersonca470632016-09-06 13:47:26 -07002433class intptr_t_converter(CConverter):
2434 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002435 format_unit = '" _Py_PARSE_INTPTR "'
2436
2437class Py_off_t_converter(CConverter):
2438 type = 'Py_off_t'
2439 converter = 'Py_off_t_converter'
2440
2441class Py_off_t_return_converter(long_return_converter):
2442 type = 'Py_off_t'
2443 conversion_fn = 'PyLong_FromPy_off_t'
2444
2445class path_confname_converter(CConverter):
2446 type="int"
2447 converter="conv_path_confname"
2448
2449class confstr_confname_converter(path_confname_converter):
2450 converter='conv_confstr_confname'
2451
2452class sysconf_confname_converter(path_confname_converter):
2453 converter="conv_sysconf_confname"
2454
2455class sched_param_converter(CConverter):
2456 type = 'struct sched_param'
2457 converter = 'convert_sched_param'
2458 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002459
Larry Hastings61272b72014-01-07 12:41:53 -08002460[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002461/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002462
Larry Hastings61272b72014-01-07 12:41:53 -08002463/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002464
Larry Hastings2a727912014-01-16 11:32:01 -08002465os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002466
2467 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002468 Path to be examined; can be string, bytes, path-like object or
2469 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002470
2471 *
2472
Larry Hastings2f936352014-08-05 14:04:04 +10002473 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002474 If not None, it should be a file descriptor open to a directory,
2475 and path should be a relative string; path will then be relative to
2476 that directory.
2477
2478 follow_symlinks: bool = True
2479 If False, and the last element of the path is a symbolic link,
2480 stat will examine the symbolic link itself instead of the file
2481 the link points to.
2482
2483Perform a stat system call on the given path.
2484
2485dir_fd and follow_symlinks may not be implemented
2486 on your platform. If they are unavailable, using them will raise a
2487 NotImplementedError.
2488
2489It's an error to use dir_fd or follow_symlinks when specifying path as
2490 an open file descriptor.
2491
Larry Hastings61272b72014-01-07 12:41:53 -08002492[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002493
Larry Hastings31826802013-10-19 00:09:25 -07002494static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002495os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002496/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002497{
2498 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2499}
2500
Larry Hastings2f936352014-08-05 14:04:04 +10002501
2502/*[clinic input]
2503os.lstat
2504
2505 path : path_t
2506
2507 *
2508
2509 dir_fd : dir_fd(requires='fstatat') = None
2510
2511Perform a stat system call on the given path, without following symbolic links.
2512
2513Like stat(), but do not follow symbolic links.
2514Equivalent to stat(path, follow_symlinks=False).
2515[clinic start generated code]*/
2516
Larry Hastings2f936352014-08-05 14:04:04 +10002517static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002518os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2519/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002520{
2521 int follow_symlinks = 0;
2522 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2523}
Larry Hastings31826802013-10-19 00:09:25 -07002524
Larry Hastings2f936352014-08-05 14:04:04 +10002525
Larry Hastings61272b72014-01-07 12:41:53 -08002526/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002527os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002528
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002529 path: path_t
2530 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002531
2532 mode: int
2533 Operating-system mode bitfield. Can be F_OK to test existence,
2534 or the inclusive-OR of R_OK, W_OK, and X_OK.
2535
2536 *
2537
Larry Hastings2f936352014-08-05 14:04:04 +10002538 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002539 If not None, it should be a file descriptor open to a directory,
2540 and path should be relative; path will then be relative to that
2541 directory.
2542
2543 effective_ids: bool = False
2544 If True, access will use the effective uid/gid instead of
2545 the real uid/gid.
2546
2547 follow_symlinks: bool = True
2548 If False, and the last element of the path is a symbolic link,
2549 access will examine the symbolic link itself instead of the file
2550 the link points to.
2551
2552Use the real uid/gid to test for access to a path.
2553
2554{parameters}
2555dir_fd, effective_ids, and follow_symlinks may not be implemented
2556 on your platform. If they are unavailable, using them will raise a
2557 NotImplementedError.
2558
2559Note that most operations will use the effective uid/gid, therefore this
2560 routine can be used in a suid/sgid environment to test if the invoking user
2561 has the specified access to the path.
2562
Larry Hastings61272b72014-01-07 12:41:53 -08002563[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002564
Larry Hastings2f936352014-08-05 14:04:04 +10002565static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002566os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002567 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002568/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002569{
Larry Hastings2f936352014-08-05 14:04:04 +10002570 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002571
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002572#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002573 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002574#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002575 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002576#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002577
Larry Hastings9cf065c2012-06-22 16:30:09 -07002578#ifndef HAVE_FACCESSAT
2579 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002580 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002581
2582 if (effective_ids) {
2583 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002584 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002585 }
2586#endif
2587
2588#ifdef MS_WINDOWS
2589 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002590 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002591 Py_END_ALLOW_THREADS
2592
2593 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002594 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002595 * * we didn't get a -1, and
2596 * * write access wasn't requested,
2597 * * or the file isn't read-only,
2598 * * or it's a directory.
2599 * (Directories cannot be read-only on Windows.)
2600 */
Larry Hastings2f936352014-08-05 14:04:04 +10002601 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002602 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002604 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002605#else
2606
2607 Py_BEGIN_ALLOW_THREADS
2608#ifdef HAVE_FACCESSAT
2609 if ((dir_fd != DEFAULT_DIR_FD) ||
2610 effective_ids ||
2611 !follow_symlinks) {
2612 int flags = 0;
2613 if (!follow_symlinks)
2614 flags |= AT_SYMLINK_NOFOLLOW;
2615 if (effective_ids)
2616 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002617 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002618 }
2619 else
2620#endif
Larry Hastings31826802013-10-19 00:09:25 -07002621 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002622 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002623 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002624#endif
2625
Larry Hastings9cf065c2012-06-22 16:30:09 -07002626 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002627}
2628
Guido van Rossumd371ff11999-01-25 16:12:23 +00002629#ifndef F_OK
2630#define F_OK 0
2631#endif
2632#ifndef R_OK
2633#define R_OK 4
2634#endif
2635#ifndef W_OK
2636#define W_OK 2
2637#endif
2638#ifndef X_OK
2639#define X_OK 1
2640#endif
2641
Larry Hastings31826802013-10-19 00:09:25 -07002642
Guido van Rossumd371ff11999-01-25 16:12:23 +00002643#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002644/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002645os.ttyname -> DecodeFSDefault
2646
2647 fd: int
2648 Integer file descriptor handle.
2649
2650 /
2651
2652Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002653[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002654
Larry Hastings31826802013-10-19 00:09:25 -07002655static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002656os_ttyname_impl(PyObject *module, int fd)
2657/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002658{
2659 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002660
Larry Hastings31826802013-10-19 00:09:25 -07002661 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002662 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002663 posix_error();
2664 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002665}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002666#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002667
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002668#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002669/*[clinic input]
2670os.ctermid
2671
2672Return the name of the controlling terminal for this process.
2673[clinic start generated code]*/
2674
Larry Hastings2f936352014-08-05 14:04:04 +10002675static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002676os_ctermid_impl(PyObject *module)
2677/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002678{
Victor Stinner8c62be82010-05-06 00:08:46 +00002679 char *ret;
2680 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002681
Greg Wardb48bc172000-03-01 21:51:56 +00002682#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002683 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002684#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002685 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002686#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002687 if (ret == NULL)
2688 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002689 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002690}
Larry Hastings2f936352014-08-05 14:04:04 +10002691#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002692
Larry Hastings2f936352014-08-05 14:04:04 +10002693
2694/*[clinic input]
2695os.chdir
2696
2697 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2698
2699Change the current working directory to the specified path.
2700
2701path may always be specified as a string.
2702On some platforms, path may also be specified as an open file descriptor.
2703 If this functionality is unavailable, using it raises an exception.
2704[clinic start generated code]*/
2705
Larry Hastings2f936352014-08-05 14:04:04 +10002706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002707os_chdir_impl(PyObject *module, path_t *path)
2708/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002709{
2710 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002711
2712 Py_BEGIN_ALLOW_THREADS
2713#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002714 /* on unix, success = 0, on windows, success = !0 */
2715 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002716#else
2717#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002718 if (path->fd != -1)
2719 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002720 else
2721#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002722 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002723#endif
2724 Py_END_ALLOW_THREADS
2725
2726 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002727 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002728 }
2729
Larry Hastings2f936352014-08-05 14:04:04 +10002730 Py_RETURN_NONE;
2731}
2732
2733
2734#ifdef HAVE_FCHDIR
2735/*[clinic input]
2736os.fchdir
2737
2738 fd: fildes
2739
2740Change to the directory of the given file descriptor.
2741
2742fd must be opened on a directory, not a file.
2743Equivalent to os.chdir(fd).
2744
2745[clinic start generated code]*/
2746
Fred Drake4d1e64b2002-04-15 19:40:07 +00002747static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002748os_fchdir_impl(PyObject *module, int fd)
2749/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002750{
Larry Hastings2f936352014-08-05 14:04:04 +10002751 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002752}
2753#endif /* HAVE_FCHDIR */
2754
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002755
Larry Hastings2f936352014-08-05 14:04:04 +10002756/*[clinic input]
2757os.chmod
2758
2759 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2760 Path to be modified. May always be specified as a str or bytes.
2761 On some platforms, path may also be specified as an open file descriptor.
2762 If this functionality is unavailable, using it raises an exception.
2763
2764 mode: int
2765 Operating-system mode bitfield.
2766
2767 *
2768
2769 dir_fd : dir_fd(requires='fchmodat') = None
2770 If not None, it should be a file descriptor open to a directory,
2771 and path should be relative; path will then be relative to that
2772 directory.
2773
2774 follow_symlinks: bool = True
2775 If False, and the last element of the path is a symbolic link,
2776 chmod will modify the symbolic link itself instead of the file
2777 the link points to.
2778
2779Change the access permissions of a file.
2780
2781It is an error to use dir_fd or follow_symlinks when specifying path as
2782 an open file descriptor.
2783dir_fd and follow_symlinks may not be implemented on your platform.
2784 If they are unavailable, using them will raise a NotImplementedError.
2785
2786[clinic start generated code]*/
2787
Larry Hastings2f936352014-08-05 14:04:04 +10002788static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002789os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002790 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002791/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002792{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002794
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002795#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002796 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002797#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002798
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799#ifdef HAVE_FCHMODAT
2800 int fchmodat_nofollow_unsupported = 0;
2801#endif
2802
Larry Hastings9cf065c2012-06-22 16:30:09 -07002803#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2804 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002805 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002806#endif
2807
2808#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002809 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002810 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002811 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002812 result = 0;
2813 else {
2814 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002815 attr &= ~FILE_ATTRIBUTE_READONLY;
2816 else
2817 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002818 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002819 }
2820 Py_END_ALLOW_THREADS
2821
2822 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002823 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 }
2825#else /* MS_WINDOWS */
2826 Py_BEGIN_ALLOW_THREADS
2827#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002828 if (path->fd != -1)
2829 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002830 else
2831#endif
2832#ifdef HAVE_LCHMOD
2833 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002834 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835 else
2836#endif
2837#ifdef HAVE_FCHMODAT
2838 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2839 /*
2840 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2841 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002842 * and then says it isn't implemented yet.
2843 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844 *
2845 * Once it is supported, os.chmod will automatically
2846 * support dir_fd and follow_symlinks=False. (Hopefully.)
2847 * Until then, we need to be careful what exception we raise.
2848 */
Larry Hastings2f936352014-08-05 14:04:04 +10002849 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002850 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2851 /*
2852 * But wait! We can't throw the exception without allowing threads,
2853 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2854 */
2855 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002856 result &&
2857 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2858 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002859 }
2860 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002861#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002862 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002863 Py_END_ALLOW_THREADS
2864
2865 if (result) {
2866#ifdef HAVE_FCHMODAT
2867 if (fchmodat_nofollow_unsupported) {
2868 if (dir_fd != DEFAULT_DIR_FD)
2869 dir_fd_and_follow_symlinks_invalid("chmod",
2870 dir_fd, follow_symlinks);
2871 else
2872 follow_symlinks_specified("chmod", follow_symlinks);
2873 }
2874 else
2875#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002876 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002877 }
2878#endif
2879
Larry Hastings2f936352014-08-05 14:04:04 +10002880 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002881}
2882
Larry Hastings9cf065c2012-06-22 16:30:09 -07002883
Christian Heimes4e30a842007-11-30 22:12:06 +00002884#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002885/*[clinic input]
2886os.fchmod
2887
2888 fd: int
2889 mode: int
2890
2891Change the access permissions of the file given by file descriptor fd.
2892
2893Equivalent to os.chmod(fd, mode).
2894[clinic start generated code]*/
2895
Larry Hastings2f936352014-08-05 14:04:04 +10002896static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002897os_fchmod_impl(PyObject *module, int fd, int mode)
2898/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002899{
2900 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002901 int async_err = 0;
2902
2903 do {
2904 Py_BEGIN_ALLOW_THREADS
2905 res = fchmod(fd, mode);
2906 Py_END_ALLOW_THREADS
2907 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2908 if (res != 0)
2909 return (!async_err) ? posix_error() : NULL;
2910
Victor Stinner8c62be82010-05-06 00:08:46 +00002911 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002912}
2913#endif /* HAVE_FCHMOD */
2914
Larry Hastings2f936352014-08-05 14:04:04 +10002915
Christian Heimes4e30a842007-11-30 22:12:06 +00002916#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002917/*[clinic input]
2918os.lchmod
2919
2920 path: path_t
2921 mode: int
2922
2923Change the access permissions of a file, without following symbolic links.
2924
2925If path is a symlink, this affects the link itself rather than the target.
2926Equivalent to chmod(path, mode, follow_symlinks=False)."
2927[clinic start generated code]*/
2928
Larry Hastings2f936352014-08-05 14:04:04 +10002929static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002930os_lchmod_impl(PyObject *module, path_t *path, int mode)
2931/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002932{
Victor Stinner8c62be82010-05-06 00:08:46 +00002933 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002934 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002935 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002936 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002937 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002938 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002939 return NULL;
2940 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002941 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002942}
2943#endif /* HAVE_LCHMOD */
2944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002945
Thomas Wouterscf297e42007-02-23 15:07:44 +00002946#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002947/*[clinic input]
2948os.chflags
2949
2950 path: path_t
2951 flags: unsigned_long(bitwise=True)
2952 follow_symlinks: bool=True
2953
2954Set file flags.
2955
2956If follow_symlinks is False, and the last element of the path is a symbolic
2957 link, chflags will change flags on the symbolic link itself instead of the
2958 file the link points to.
2959follow_symlinks may not be implemented on your platform. If it is
2960unavailable, using it will raise a NotImplementedError.
2961
2962[clinic start generated code]*/
2963
Larry Hastings2f936352014-08-05 14:04:04 +10002964static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002965os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002966 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002967/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002968{
2969 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002970
2971#ifndef HAVE_LCHFLAGS
2972 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002973 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002974#endif
2975
Victor Stinner8c62be82010-05-06 00:08:46 +00002976 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002977#ifdef HAVE_LCHFLAGS
2978 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002979 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002980 else
2981#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002982 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002983 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002984
Larry Hastings2f936352014-08-05 14:04:04 +10002985 if (result)
2986 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002987
Larry Hastings2f936352014-08-05 14:04:04 +10002988 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002989}
2990#endif /* HAVE_CHFLAGS */
2991
Larry Hastings2f936352014-08-05 14:04:04 +10002992
Thomas Wouterscf297e42007-02-23 15:07:44 +00002993#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002994/*[clinic input]
2995os.lchflags
2996
2997 path: path_t
2998 flags: unsigned_long(bitwise=True)
2999
3000Set file flags.
3001
3002This function will not follow symbolic links.
3003Equivalent to chflags(path, flags, follow_symlinks=False).
3004[clinic start generated code]*/
3005
Larry Hastings2f936352014-08-05 14:04:04 +10003006static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003007os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3008/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003009{
Victor Stinner8c62be82010-05-06 00:08:46 +00003010 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003011 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003012 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003013 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003014 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003015 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003016 }
Victor Stinner292c8352012-10-30 02:17:38 +01003017 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003018}
3019#endif /* HAVE_LCHFLAGS */
3020
Larry Hastings2f936352014-08-05 14:04:04 +10003021
Martin v. Löwis244edc82001-10-04 22:44:26 +00003022#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003023/*[clinic input]
3024os.chroot
3025 path: path_t
3026
3027Change root directory to path.
3028
3029[clinic start generated code]*/
3030
Larry Hastings2f936352014-08-05 14:04:04 +10003031static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003032os_chroot_impl(PyObject *module, path_t *path)
3033/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003034{
3035 int res;
3036 Py_BEGIN_ALLOW_THREADS
3037 res = chroot(path->narrow);
3038 Py_END_ALLOW_THREADS
3039 if (res < 0)
3040 return path_error(path);
3041 Py_RETURN_NONE;
3042}
3043#endif /* HAVE_CHROOT */
3044
Martin v. Löwis244edc82001-10-04 22:44:26 +00003045
Guido van Rossum21142a01999-01-08 21:05:37 +00003046#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003047/*[clinic input]
3048os.fsync
3049
3050 fd: fildes
3051
3052Force write of fd to disk.
3053[clinic start generated code]*/
3054
Larry Hastings2f936352014-08-05 14:04:04 +10003055static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003056os_fsync_impl(PyObject *module, int fd)
3057/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003058{
3059 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003060}
3061#endif /* HAVE_FSYNC */
3062
Larry Hastings2f936352014-08-05 14:04:04 +10003063
Ross Lagerwall7807c352011-03-17 20:20:30 +02003064#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003065/*[clinic input]
3066os.sync
3067
3068Force write of everything to disk.
3069[clinic start generated code]*/
3070
Larry Hastings2f936352014-08-05 14:04:04 +10003071static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003072os_sync_impl(PyObject *module)
3073/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003074{
3075 Py_BEGIN_ALLOW_THREADS
3076 sync();
3077 Py_END_ALLOW_THREADS
3078 Py_RETURN_NONE;
3079}
Larry Hastings2f936352014-08-05 14:04:04 +10003080#endif /* HAVE_SYNC */
3081
Ross Lagerwall7807c352011-03-17 20:20:30 +02003082
Guido van Rossum21142a01999-01-08 21:05:37 +00003083#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003084#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003085extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3086#endif
3087
Larry Hastings2f936352014-08-05 14:04:04 +10003088/*[clinic input]
3089os.fdatasync
3090
3091 fd: fildes
3092
3093Force write of fd to disk without forcing update of metadata.
3094[clinic start generated code]*/
3095
Larry Hastings2f936352014-08-05 14:04:04 +10003096static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003097os_fdatasync_impl(PyObject *module, int fd)
3098/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003099{
3100 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003101}
3102#endif /* HAVE_FDATASYNC */
3103
3104
Fredrik Lundh10723342000-07-10 16:38:09 +00003105#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003106/*[clinic input]
3107os.chown
3108
3109 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3110 Path to be examined; can be string, bytes, or open-file-descriptor int.
3111
3112 uid: uid_t
3113
3114 gid: gid_t
3115
3116 *
3117
3118 dir_fd : dir_fd(requires='fchownat') = None
3119 If not None, it should be a file descriptor open to a directory,
3120 and path should be relative; path will then be relative to that
3121 directory.
3122
3123 follow_symlinks: bool = True
3124 If False, and the last element of the path is a symbolic link,
3125 stat will examine the symbolic link itself instead of the file
3126 the link points to.
3127
3128Change the owner and group id of path to the numeric uid and gid.\
3129
3130path may always be specified as a string.
3131On some platforms, path may also be specified as an open file descriptor.
3132 If this functionality is unavailable, using it raises an exception.
3133If dir_fd is not None, it should be a file descriptor open to a directory,
3134 and path should be relative; path will then be relative to that directory.
3135If follow_symlinks is False, and the last element of the path is a symbolic
3136 link, chown will modify the symbolic link itself instead of the file the
3137 link points to.
3138It is an error to use dir_fd or follow_symlinks when specifying path as
3139 an open file descriptor.
3140dir_fd and follow_symlinks may not be implemented on your platform.
3141 If they are unavailable, using them will raise a NotImplementedError.
3142
3143[clinic start generated code]*/
3144
Larry Hastings2f936352014-08-05 14:04:04 +10003145static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003146os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003147 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003148/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003149{
3150 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003151
3152#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3153 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003154 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003155#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003156 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3157 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3158 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003159
3160#ifdef __APPLE__
3161 /*
3162 * This is for Mac OS X 10.3, which doesn't have lchown.
3163 * (But we still have an lchown symbol because of weak-linking.)
3164 * It doesn't have fchownat either. So there's no possibility
3165 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003166 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003167 if ((!follow_symlinks) && (lchown == NULL)) {
3168 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003169 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003170 }
3171#endif
3172
Victor Stinner8c62be82010-05-06 00:08:46 +00003173 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003174#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003175 if (path->fd != -1)
3176 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003177 else
3178#endif
3179#ifdef HAVE_LCHOWN
3180 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003181 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003182 else
3183#endif
3184#ifdef HAVE_FCHOWNAT
3185 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003186 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003187 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3188 else
3189#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003190 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003191 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192
Larry Hastings2f936352014-08-05 14:04:04 +10003193 if (result)
3194 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003195
Larry Hastings2f936352014-08-05 14:04:04 +10003196 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003197}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003198#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003199
Larry Hastings2f936352014-08-05 14:04:04 +10003200
Christian Heimes4e30a842007-11-30 22:12:06 +00003201#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003202/*[clinic input]
3203os.fchown
3204
3205 fd: int
3206 uid: uid_t
3207 gid: gid_t
3208
3209Change the owner and group id of the file specified by file descriptor.
3210
3211Equivalent to os.chown(fd, uid, gid).
3212
3213[clinic start generated code]*/
3214
Larry Hastings2f936352014-08-05 14:04:04 +10003215static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003216os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3217/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003218{
Victor Stinner8c62be82010-05-06 00:08:46 +00003219 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003220 int async_err = 0;
3221
3222 do {
3223 Py_BEGIN_ALLOW_THREADS
3224 res = fchown(fd, uid, gid);
3225 Py_END_ALLOW_THREADS
3226 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3227 if (res != 0)
3228 return (!async_err) ? posix_error() : NULL;
3229
Victor Stinner8c62be82010-05-06 00:08:46 +00003230 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003231}
3232#endif /* HAVE_FCHOWN */
3233
Larry Hastings2f936352014-08-05 14:04:04 +10003234
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003235#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003236/*[clinic input]
3237os.lchown
3238
3239 path : path_t
3240 uid: uid_t
3241 gid: gid_t
3242
3243Change the owner and group id of path to the numeric uid and gid.
3244
3245This function will not follow symbolic links.
3246Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3247[clinic start generated code]*/
3248
Larry Hastings2f936352014-08-05 14:04:04 +10003249static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003250os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3251/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003252{
Victor Stinner8c62be82010-05-06 00:08:46 +00003253 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003254 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003255 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003257 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003258 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003259 }
Larry Hastings2f936352014-08-05 14:04:04 +10003260 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003261}
3262#endif /* HAVE_LCHOWN */
3263
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003264
Barry Warsaw53699e91996-12-10 23:23:01 +00003265static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003266posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003267{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003268 char *buf, *tmpbuf;
3269 char *cwd;
3270 const size_t chunk = 1024;
3271 size_t buflen = 0;
3272 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003273
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003274#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003275 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003276 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003277 wchar_t *wbuf2 = wbuf;
3278 PyObject *resobj;
3279 DWORD len;
3280 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003281 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003282 /* If the buffer is large enough, len does not include the
3283 terminating \0. If the buffer is too small, len includes
3284 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003285 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003286 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 if (wbuf2)
3288 len = GetCurrentDirectoryW(len, wbuf2);
3289 }
3290 Py_END_ALLOW_THREADS
3291 if (!wbuf2) {
3292 PyErr_NoMemory();
3293 return NULL;
3294 }
3295 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003296 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003297 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003298 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003299 }
3300 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003301 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003302 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003303 return resobj;
3304 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003305
3306 if (win32_warn_bytes_api())
3307 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003308#endif
3309
Victor Stinner4403d7d2015-04-25 00:16:10 +02003310 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003311 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003312 do {
3313 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003314#ifdef MS_WINDOWS
3315 if (buflen > INT_MAX) {
3316 PyErr_NoMemory();
3317 break;
3318 }
3319#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003320 tmpbuf = PyMem_RawRealloc(buf, buflen);
3321 if (tmpbuf == NULL)
3322 break;
3323
3324 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003325#ifdef MS_WINDOWS
3326 cwd = getcwd(buf, (int)buflen);
3327#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003328 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003329#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003330 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003331 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003332
3333 if (cwd == NULL) {
3334 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003335 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003336 }
3337
Victor Stinner8c62be82010-05-06 00:08:46 +00003338 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003339 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3340 else
3341 obj = PyUnicode_DecodeFSDefault(buf);
3342 PyMem_RawFree(buf);
3343
3344 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003345}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003346
Larry Hastings2f936352014-08-05 14:04:04 +10003347
3348/*[clinic input]
3349os.getcwd
3350
3351Return a unicode string representing the current working directory.
3352[clinic start generated code]*/
3353
Larry Hastings2f936352014-08-05 14:04:04 +10003354static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003355os_getcwd_impl(PyObject *module)
3356/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003357{
3358 return posix_getcwd(0);
3359}
3360
Larry Hastings2f936352014-08-05 14:04:04 +10003361
3362/*[clinic input]
3363os.getcwdb
3364
3365Return a bytes string representing the current working directory.
3366[clinic start generated code]*/
3367
Larry Hastings2f936352014-08-05 14:04:04 +10003368static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003369os_getcwdb_impl(PyObject *module)
3370/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003371{
3372 return posix_getcwd(1);
3373}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003374
Larry Hastings2f936352014-08-05 14:04:04 +10003375
Larry Hastings9cf065c2012-06-22 16:30:09 -07003376#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3377#define HAVE_LINK 1
3378#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003379
Guido van Rossumb6775db1994-08-01 11:34:53 +00003380#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003381/*[clinic input]
3382
3383os.link
3384
3385 src : path_t
3386 dst : path_t
3387 *
3388 src_dir_fd : dir_fd = None
3389 dst_dir_fd : dir_fd = None
3390 follow_symlinks: bool = True
3391
3392Create a hard link to a file.
3393
3394If either src_dir_fd or dst_dir_fd is not None, it should be a file
3395 descriptor open to a directory, and the respective path string (src or dst)
3396 should be relative; the path will then be relative to that directory.
3397If follow_symlinks is False, and the last element of src is a symbolic
3398 link, link will create a link to the symbolic link itself instead of the
3399 file the link points to.
3400src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3401 platform. If they are unavailable, using them will raise a
3402 NotImplementedError.
3403[clinic start generated code]*/
3404
Larry Hastings2f936352014-08-05 14:04:04 +10003405static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003406os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003407 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003408/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003409{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003410#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003411 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003412#else
3413 int result;
3414#endif
3415
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416#ifndef HAVE_LINKAT
3417 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3418 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003419 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420 }
3421#endif
3422
Steve Dowercc16be82016-09-08 10:35:16 -07003423#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003424 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425 PyErr_SetString(PyExc_NotImplementedError,
3426 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003427 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428 }
Steve Dowercc16be82016-09-08 10:35:16 -07003429#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003430
Brian Curtin1b9df392010-11-24 20:24:31 +00003431#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003433 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003435
Larry Hastings2f936352014-08-05 14:04:04 +10003436 if (!result)
3437 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438#else
3439 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003440#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3442 (dst_dir_fd != DEFAULT_DIR_FD) ||
3443 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003444 result = linkat(src_dir_fd, src->narrow,
3445 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3447 else
Steve Dowercc16be82016-09-08 10:35:16 -07003448#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003449 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003450 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003451
Larry Hastings2f936352014-08-05 14:04:04 +10003452 if (result)
3453 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003454#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003455
Larry Hastings2f936352014-08-05 14:04:04 +10003456 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003457}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458#endif
3459
Brian Curtin1b9df392010-11-24 20:24:31 +00003460
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003461#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003462static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003463_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003464{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465 PyObject *v;
3466 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3467 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003468 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003469 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003470 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003472
Steve Dowercc16be82016-09-08 10:35:16 -07003473 WIN32_FIND_DATAW wFileData;
3474 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003475
Steve Dowercc16be82016-09-08 10:35:16 -07003476 if (!path->wide) { /* Default arg: "." */
3477 po_wchars = L".";
3478 len = 1;
3479 } else {
3480 po_wchars = path->wide;
3481 len = wcslen(path->wide);
3482 }
3483 /* The +5 is so we can append "\\*.*\0" */
3484 wnamebuf = PyMem_New(wchar_t, len + 5);
3485 if (!wnamebuf) {
3486 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 }
Steve Dowercc16be82016-09-08 10:35:16 -07003489 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003491 wchar_t wch = wnamebuf[len-1];
3492 if (wch != SEP && wch != ALTSEP && wch != L':')
3493 wnamebuf[len++] = SEP;
3494 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003495 }
Steve Dowercc16be82016-09-08 10:35:16 -07003496 if ((list = PyList_New(0)) == NULL) {
3497 goto exit;
3498 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003499 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003500 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003501 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003502 if (hFindFile == INVALID_HANDLE_VALUE) {
3503 int error = GetLastError();
3504 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003505 goto exit;
3506 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003507 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003509 }
3510 do {
3511 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003512 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3513 wcscmp(wFileData.cFileName, L"..") != 0) {
3514 v = PyUnicode_FromWideChar(wFileData.cFileName,
3515 wcslen(wFileData.cFileName));
3516 if (path->narrow && v) {
3517 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3518 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003519 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 Py_DECREF(list);
3521 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 break;
3523 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003524 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003525 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526 Py_DECREF(list);
3527 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003528 break;
3529 }
3530 Py_DECREF(v);
3531 }
3532 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003533 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 Py_END_ALLOW_THREADS
3535 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3536 it got to the end of the directory. */
3537 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003538 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003539 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003540 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003541 }
3542 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003543
Larry Hastings9cf065c2012-06-22 16:30:09 -07003544exit:
3545 if (hFindFile != INVALID_HANDLE_VALUE) {
3546 if (FindClose(hFindFile) == FALSE) {
3547 if (list != NULL) {
3548 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003549 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 }
3551 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003552 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003553 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003554
Larry Hastings9cf065c2012-06-22 16:30:09 -07003555 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003556} /* end of _listdir_windows_no_opendir */
3557
3558#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3559
3560static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003561_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003562{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003563 PyObject *v;
3564 DIR *dirp = NULL;
3565 struct dirent *ep;
3566 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003567#ifdef HAVE_FDOPENDIR
3568 int fd = -1;
3569#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003570
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003572#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003573 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003574 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003575 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003576 if (fd == -1)
3577 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578
Larry Hastingsfdaea062012-06-25 04:42:23 -07003579 return_str = 1;
3580
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581 Py_BEGIN_ALLOW_THREADS
3582 dirp = fdopendir(fd);
3583 Py_END_ALLOW_THREADS
3584 }
3585 else
3586#endif
3587 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003588 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003589 if (path->narrow) {
3590 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003591 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003592 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003593 }
3594 else {
3595 name = ".";
3596 return_str = 1;
3597 }
3598
Larry Hastings9cf065c2012-06-22 16:30:09 -07003599 Py_BEGIN_ALLOW_THREADS
3600 dirp = opendir(name);
3601 Py_END_ALLOW_THREADS
3602 }
3603
3604 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003605 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003606#ifdef HAVE_FDOPENDIR
3607 if (fd != -1) {
3608 Py_BEGIN_ALLOW_THREADS
3609 close(fd);
3610 Py_END_ALLOW_THREADS
3611 }
3612#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003613 goto exit;
3614 }
3615 if ((list = PyList_New(0)) == NULL) {
3616 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003617 }
3618 for (;;) {
3619 errno = 0;
3620 Py_BEGIN_ALLOW_THREADS
3621 ep = readdir(dirp);
3622 Py_END_ALLOW_THREADS
3623 if (ep == NULL) {
3624 if (errno == 0) {
3625 break;
3626 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003627 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003628 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003629 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003630 }
3631 }
3632 if (ep->d_name[0] == '.' &&
3633 (NAMLEN(ep) == 1 ||
3634 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3635 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003636 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003637 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3638 else
3639 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003640 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003641 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003642 break;
3643 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003644 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003646 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003647 break;
3648 }
3649 Py_DECREF(v);
3650 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003651
Larry Hastings9cf065c2012-06-22 16:30:09 -07003652exit:
3653 if (dirp != NULL) {
3654 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003655#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003656 if (fd > -1)
3657 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003658#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003659 closedir(dirp);
3660 Py_END_ALLOW_THREADS
3661 }
3662
Larry Hastings9cf065c2012-06-22 16:30:09 -07003663 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003664} /* end of _posix_listdir */
3665#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003666
Larry Hastings2f936352014-08-05 14:04:04 +10003667
3668/*[clinic input]
3669os.listdir
3670
3671 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3672
3673Return a list containing the names of the files in the directory.
3674
3675path can be specified as either str or bytes. If path is bytes,
3676 the filenames returned will also be bytes; in all other circumstances
3677 the filenames returned will be str.
3678If path is None, uses the path='.'.
3679On some platforms, path may also be specified as an open file descriptor;\
3680 the file descriptor must refer to a directory.
3681 If this functionality is unavailable, using it raises NotImplementedError.
3682
3683The list is in arbitrary order. It does not include the special
3684entries '.' and '..' even if they are present in the directory.
3685
3686
3687[clinic start generated code]*/
3688
Larry Hastings2f936352014-08-05 14:04:04 +10003689static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003690os_listdir_impl(PyObject *module, path_t *path)
3691/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003692{
3693#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3694 return _listdir_windows_no_opendir(path, NULL);
3695#else
3696 return _posix_listdir(path, NULL);
3697#endif
3698}
3699
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003700#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003701/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003702/*[clinic input]
3703os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003704
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003705 path: path_t
3706 /
3707
3708[clinic start generated code]*/
3709
3710static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003711os__getfullpathname_impl(PyObject *module, path_t *path)
3712/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003713{
Steve Dowercc16be82016-09-08 10:35:16 -07003714 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3715 wchar_t *wtemp;
3716 DWORD result;
3717 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003718
Steve Dowercc16be82016-09-08 10:35:16 -07003719 result = GetFullPathNameW(path->wide,
3720 Py_ARRAY_LENGTH(woutbuf),
3721 woutbuf, &wtemp);
3722 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3723 woutbufp = PyMem_New(wchar_t, result);
3724 if (!woutbufp)
3725 return PyErr_NoMemory();
3726 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003727 }
Steve Dowercc16be82016-09-08 10:35:16 -07003728 if (result) {
3729 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3730 if (path->narrow)
3731 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3732 } else
3733 v = win32_error_object("GetFullPathNameW", path->object);
3734 if (woutbufp != woutbuf)
3735 PyMem_Free(woutbufp);
3736 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003737}
Brian Curtind40e6f72010-07-08 21:39:08 +00003738
Brian Curtind25aef52011-06-13 15:16:04 -05003739
Larry Hastings2f936352014-08-05 14:04:04 +10003740/*[clinic input]
3741os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003742
Larry Hastings2f936352014-08-05 14:04:04 +10003743 path: unicode
3744 /
3745
3746A helper function for samepath on windows.
3747[clinic start generated code]*/
3748
Larry Hastings2f936352014-08-05 14:04:04 +10003749static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003750os__getfinalpathname_impl(PyObject *module, PyObject *path)
3751/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003752{
3753 HANDLE hFile;
3754 int buf_size;
3755 wchar_t *target_path;
3756 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003757 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003758 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003759
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03003760 path_wchar = _PyUnicode_AsUnicode(path);
Larry Hastings2f936352014-08-05 14:04:04 +10003761 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003762 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003763
Brian Curtind40e6f72010-07-08 21:39:08 +00003764 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003765 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003766 0, /* desired access */
3767 0, /* share mode */
3768 NULL, /* security attributes */
3769 OPEN_EXISTING,
3770 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3771 FILE_FLAG_BACKUP_SEMANTICS,
3772 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003773
Victor Stinnereb5657a2011-09-30 01:44:27 +02003774 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003775 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003776
3777 /* We have a good handle to the target, use it to determine the
3778 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003779 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003780
3781 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003782 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003783
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003784 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003785 if(!target_path)
3786 return PyErr_NoMemory();
3787
Steve Dower2ea51c92015-03-20 21:49:12 -07003788 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3789 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003790 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003791 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003792
3793 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003794 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003795
3796 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003797 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003798 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003799 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003800}
Brian Curtin62857742010-09-06 17:07:27 +00003801
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003802/*[clinic input]
3803os._isdir
3804
3805 path: path_t
3806 /
3807
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003808Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003809[clinic start generated code]*/
3810
Brian Curtin9c669cc2011-06-08 18:17:18 -05003811static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003812os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003813/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003814{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003815 DWORD attributes;
3816
Steve Dowerb22a6772016-07-17 20:49:38 -07003817 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003818 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003819 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003820
Brian Curtin9c669cc2011-06-08 18:17:18 -05003821 if (attributes == INVALID_FILE_ATTRIBUTES)
3822 Py_RETURN_FALSE;
3823
Brian Curtin9c669cc2011-06-08 18:17:18 -05003824 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3825 Py_RETURN_TRUE;
3826 else
3827 Py_RETURN_FALSE;
3828}
Tim Golden6b528062013-08-01 12:44:00 +01003829
Tim Golden6b528062013-08-01 12:44:00 +01003830
Larry Hastings2f936352014-08-05 14:04:04 +10003831/*[clinic input]
3832os._getvolumepathname
3833
3834 path: unicode
3835
3836A helper function for ismount on Win32.
3837[clinic start generated code]*/
3838
Larry Hastings2f936352014-08-05 14:04:04 +10003839static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003840os__getvolumepathname_impl(PyObject *module, PyObject *path)
3841/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003842{
3843 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003844 const wchar_t *path_wchar;
3845 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003846 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003847 BOOL ret;
3848
Larry Hastings2f936352014-08-05 14:04:04 +10003849 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3850 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003851 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003852 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003853
3854 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003855 buflen = Py_MAX(buflen, MAX_PATH);
3856
3857 if (buflen > DWORD_MAX) {
3858 PyErr_SetString(PyExc_OverflowError, "path too long");
3859 return NULL;
3860 }
3861
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003862 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003863 if (mountpath == NULL)
3864 return PyErr_NoMemory();
3865
3866 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003867 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003868 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003869 Py_END_ALLOW_THREADS
3870
3871 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003872 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003873 goto exit;
3874 }
3875 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3876
3877exit:
3878 PyMem_Free(mountpath);
3879 return result;
3880}
Tim Golden6b528062013-08-01 12:44:00 +01003881
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003882#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003883
Larry Hastings2f936352014-08-05 14:04:04 +10003884
3885/*[clinic input]
3886os.mkdir
3887
3888 path : path_t
3889
3890 mode: int = 0o777
3891
3892 *
3893
3894 dir_fd : dir_fd(requires='mkdirat') = None
3895
3896# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3897
3898Create a directory.
3899
3900If dir_fd is not None, it should be a file descriptor open to a directory,
3901 and path should be relative; path will then be relative to that directory.
3902dir_fd may not be implemented on your platform.
3903 If it is unavailable, using it will raise a NotImplementedError.
3904
3905The mode argument is ignored on Windows.
3906[clinic start generated code]*/
3907
Larry Hastings2f936352014-08-05 14:04:04 +10003908static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003909os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3910/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003911{
3912 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003913
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003914#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003915 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003916 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003917 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003918
Larry Hastings2f936352014-08-05 14:04:04 +10003919 if (!result)
3920 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003921#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003923#if HAVE_MKDIRAT
3924 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003925 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003926 else
3927#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003928#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003929 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003930#else
Larry Hastings2f936352014-08-05 14:04:04 +10003931 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003932#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003933 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003934 if (result < 0)
3935 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003936#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003937 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003938}
3939
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003940
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003941/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3942#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003943#include <sys/resource.h>
3944#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003945
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003946
3947#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003948/*[clinic input]
3949os.nice
3950
3951 increment: int
3952 /
3953
3954Add increment to the priority of process and return the new priority.
3955[clinic start generated code]*/
3956
Larry Hastings2f936352014-08-05 14:04:04 +10003957static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003958os_nice_impl(PyObject *module, int increment)
3959/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003960{
3961 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003962
Victor Stinner8c62be82010-05-06 00:08:46 +00003963 /* There are two flavours of 'nice': one that returns the new
3964 priority (as required by almost all standards out there) and the
3965 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3966 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003967
Victor Stinner8c62be82010-05-06 00:08:46 +00003968 If we are of the nice family that returns the new priority, we
3969 need to clear errno before the call, and check if errno is filled
3970 before calling posix_error() on a returnvalue of -1, because the
3971 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003972
Victor Stinner8c62be82010-05-06 00:08:46 +00003973 errno = 0;
3974 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003975#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003976 if (value == 0)
3977 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003978#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003979 if (value == -1 && errno != 0)
3980 /* either nice() or getpriority() returned an error */
3981 return posix_error();
3982 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003983}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003984#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003985
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003986
3987#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003988/*[clinic input]
3989os.getpriority
3990
3991 which: int
3992 who: int
3993
3994Return program scheduling priority.
3995[clinic start generated code]*/
3996
Larry Hastings2f936352014-08-05 14:04:04 +10003997static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003998os_getpriority_impl(PyObject *module, int which, int who)
3999/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004000{
4001 int retval;
4002
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004003 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004004 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004005 if (errno != 0)
4006 return posix_error();
4007 return PyLong_FromLong((long)retval);
4008}
4009#endif /* HAVE_GETPRIORITY */
4010
4011
4012#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004013/*[clinic input]
4014os.setpriority
4015
4016 which: int
4017 who: int
4018 priority: int
4019
4020Set program scheduling priority.
4021[clinic start generated code]*/
4022
Larry Hastings2f936352014-08-05 14:04:04 +10004023static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004024os_setpriority_impl(PyObject *module, int which, int who, int priority)
4025/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004026{
4027 int retval;
4028
4029 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004030 if (retval == -1)
4031 return posix_error();
4032 Py_RETURN_NONE;
4033}
4034#endif /* HAVE_SETPRIORITY */
4035
4036
Barry Warsaw53699e91996-12-10 23:23:01 +00004037static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004038internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004039{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004040 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004041 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004042
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004043#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004044 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004045 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004046#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004047 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004048#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004049
Larry Hastings9cf065c2012-06-22 16:30:09 -07004050 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4051 (dst_dir_fd != DEFAULT_DIR_FD);
4052#ifndef HAVE_RENAMEAT
4053 if (dir_fd_specified) {
4054 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004055 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004056 }
4057#endif
4058
Larry Hastings9cf065c2012-06-22 16:30:09 -07004059#ifdef MS_WINDOWS
4060 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004061 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004062 Py_END_ALLOW_THREADS
4063
Larry Hastings2f936352014-08-05 14:04:04 +10004064 if (!result)
4065 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004066
4067#else
Steve Dowercc16be82016-09-08 10:35:16 -07004068 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4069 PyErr_Format(PyExc_ValueError,
4070 "%s: src and dst must be the same type", function_name);
4071 return NULL;
4072 }
4073
Larry Hastings9cf065c2012-06-22 16:30:09 -07004074 Py_BEGIN_ALLOW_THREADS
4075#ifdef HAVE_RENAMEAT
4076 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004077 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004078 else
4079#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004080 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004081 Py_END_ALLOW_THREADS
4082
Larry Hastings2f936352014-08-05 14:04:04 +10004083 if (result)
4084 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004085#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004086 Py_RETURN_NONE;
4087}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004088
Larry Hastings2f936352014-08-05 14:04:04 +10004089
4090/*[clinic input]
4091os.rename
4092
4093 src : path_t
4094 dst : path_t
4095 *
4096 src_dir_fd : dir_fd = None
4097 dst_dir_fd : dir_fd = None
4098
4099Rename a file or directory.
4100
4101If either src_dir_fd or dst_dir_fd is not None, it should be a file
4102 descriptor open to a directory, and the respective path string (src or dst)
4103 should be relative; the path will then be relative to that directory.
4104src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4105 If they are unavailable, using them will raise a NotImplementedError.
4106[clinic start generated code]*/
4107
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004108static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004109os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004110 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004111/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004112{
Larry Hastings2f936352014-08-05 14:04:04 +10004113 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004114}
4115
Larry Hastings2f936352014-08-05 14:04:04 +10004116
4117/*[clinic input]
4118os.replace = os.rename
4119
4120Rename a file or directory, overwriting the destination.
4121
4122If either src_dir_fd or dst_dir_fd is not None, it should be a file
4123 descriptor open to a directory, and the respective path string (src or dst)
4124 should be relative; the path will then be relative to that directory.
4125src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4126 If they are unavailable, using them will raise a NotImplementedError."
4127[clinic start generated code]*/
4128
Larry Hastings2f936352014-08-05 14:04:04 +10004129static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004130os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4131 int dst_dir_fd)
4132/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004133{
4134 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4135}
4136
4137
4138/*[clinic input]
4139os.rmdir
4140
4141 path: path_t
4142 *
4143 dir_fd: dir_fd(requires='unlinkat') = None
4144
4145Remove a directory.
4146
4147If dir_fd is not None, it should be a file descriptor open to a directory,
4148 and path should be relative; path will then be relative to that directory.
4149dir_fd may not be implemented on your platform.
4150 If it is unavailable, using it will raise a NotImplementedError.
4151[clinic start generated code]*/
4152
Larry Hastings2f936352014-08-05 14:04:04 +10004153static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004154os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4155/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004156{
4157 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004158
4159 Py_BEGIN_ALLOW_THREADS
4160#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004161 /* Windows, success=1, UNIX, success=0 */
4162 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004163#else
4164#ifdef HAVE_UNLINKAT
4165 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004166 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004167 else
4168#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004169 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004170#endif
4171 Py_END_ALLOW_THREADS
4172
Larry Hastings2f936352014-08-05 14:04:04 +10004173 if (result)
4174 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004175
Larry Hastings2f936352014-08-05 14:04:04 +10004176 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004177}
4178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004179
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004180#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004181#ifdef MS_WINDOWS
4182/*[clinic input]
4183os.system -> long
4184
4185 command: Py_UNICODE
4186
4187Execute the command in a subshell.
4188[clinic start generated code]*/
4189
Larry Hastings2f936352014-08-05 14:04:04 +10004190static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004191os_system_impl(PyObject *module, Py_UNICODE *command)
4192/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004193{
4194 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004195 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004196 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004197 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004198 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004199 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004200 return result;
4201}
4202#else /* MS_WINDOWS */
4203/*[clinic input]
4204os.system -> long
4205
4206 command: FSConverter
4207
4208Execute the command in a subshell.
4209[clinic start generated code]*/
4210
Larry Hastings2f936352014-08-05 14:04:04 +10004211static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004212os_system_impl(PyObject *module, PyObject *command)
4213/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004214{
4215 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004216 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004217 Py_BEGIN_ALLOW_THREADS
4218 result = system(bytes);
4219 Py_END_ALLOW_THREADS
4220 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004221}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004222#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004223#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004225
Larry Hastings2f936352014-08-05 14:04:04 +10004226/*[clinic input]
4227os.umask
4228
4229 mask: int
4230 /
4231
4232Set the current numeric umask and return the previous umask.
4233[clinic start generated code]*/
4234
Larry Hastings2f936352014-08-05 14:04:04 +10004235static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004236os_umask_impl(PyObject *module, int mask)
4237/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004238{
4239 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004240 if (i < 0)
4241 return posix_error();
4242 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004243}
4244
Brian Curtind40e6f72010-07-08 21:39:08 +00004245#ifdef MS_WINDOWS
4246
4247/* override the default DeleteFileW behavior so that directory
4248symlinks can be removed with this function, the same as with
4249Unix symlinks */
4250BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4251{
4252 WIN32_FILE_ATTRIBUTE_DATA info;
4253 WIN32_FIND_DATAW find_data;
4254 HANDLE find_data_handle;
4255 int is_directory = 0;
4256 int is_link = 0;
4257
4258 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4259 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004260
Brian Curtind40e6f72010-07-08 21:39:08 +00004261 /* Get WIN32_FIND_DATA structure for the path to determine if
4262 it is a symlink */
4263 if(is_directory &&
4264 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4265 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4266
4267 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004268 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4269 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4270 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4271 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004272 FindClose(find_data_handle);
4273 }
4274 }
4275 }
4276
4277 if (is_directory && is_link)
4278 return RemoveDirectoryW(lpFileName);
4279
4280 return DeleteFileW(lpFileName);
4281}
4282#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004283
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004284
Larry Hastings2f936352014-08-05 14:04:04 +10004285/*[clinic input]
4286os.unlink
4287
4288 path: path_t
4289 *
4290 dir_fd: dir_fd(requires='unlinkat')=None
4291
4292Remove a file (same as remove()).
4293
4294If dir_fd is not None, it should be a file descriptor open to a directory,
4295 and path should be relative; path will then be relative to that directory.
4296dir_fd may not be implemented on your platform.
4297 If it is unavailable, using it will raise a NotImplementedError.
4298
4299[clinic start generated code]*/
4300
Larry Hastings2f936352014-08-05 14:04:04 +10004301static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004302os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4303/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004304{
4305 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004306
4307 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004308 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004309#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004310 /* Windows, success=1, UNIX, success=0 */
4311 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004312#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004313#ifdef HAVE_UNLINKAT
4314 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004315 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004316 else
4317#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004318 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004319#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004320 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004321 Py_END_ALLOW_THREADS
4322
Larry Hastings2f936352014-08-05 14:04:04 +10004323 if (result)
4324 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004325
Larry Hastings2f936352014-08-05 14:04:04 +10004326 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004327}
4328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004329
Larry Hastings2f936352014-08-05 14:04:04 +10004330/*[clinic input]
4331os.remove = os.unlink
4332
4333Remove a file (same as unlink()).
4334
4335If dir_fd is not None, it should be a file descriptor open to a directory,
4336 and path should be relative; path will then be relative to that directory.
4337dir_fd may not be implemented on your platform.
4338 If it is unavailable, using it will raise a NotImplementedError.
4339[clinic start generated code]*/
4340
Larry Hastings2f936352014-08-05 14:04:04 +10004341static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004342os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4343/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004344{
4345 return os_unlink_impl(module, path, dir_fd);
4346}
4347
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004348
Larry Hastings605a62d2012-06-24 04:33:36 -07004349static PyStructSequence_Field uname_result_fields[] = {
4350 {"sysname", "operating system name"},
4351 {"nodename", "name of machine on network (implementation-defined)"},
4352 {"release", "operating system release"},
4353 {"version", "operating system version"},
4354 {"machine", "hardware identifier"},
4355 {NULL}
4356};
4357
4358PyDoc_STRVAR(uname_result__doc__,
4359"uname_result: Result from os.uname().\n\n\
4360This object may be accessed either as a tuple of\n\
4361 (sysname, nodename, release, version, machine),\n\
4362or via the attributes sysname, nodename, release, version, and machine.\n\
4363\n\
4364See os.uname for more information.");
4365
4366static PyStructSequence_Desc uname_result_desc = {
4367 "uname_result", /* name */
4368 uname_result__doc__, /* doc */
4369 uname_result_fields,
4370 5
4371};
4372
4373static PyTypeObject UnameResultType;
4374
4375
4376#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004377/*[clinic input]
4378os.uname
4379
4380Return an object identifying the current operating system.
4381
4382The object behaves like a named tuple with the following fields:
4383 (sysname, nodename, release, version, machine)
4384
4385[clinic start generated code]*/
4386
Larry Hastings2f936352014-08-05 14:04:04 +10004387static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004388os_uname_impl(PyObject *module)
4389/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004390{
Victor Stinner8c62be82010-05-06 00:08:46 +00004391 struct utsname u;
4392 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004393 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004394
Victor Stinner8c62be82010-05-06 00:08:46 +00004395 Py_BEGIN_ALLOW_THREADS
4396 res = uname(&u);
4397 Py_END_ALLOW_THREADS
4398 if (res < 0)
4399 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004400
4401 value = PyStructSequence_New(&UnameResultType);
4402 if (value == NULL)
4403 return NULL;
4404
4405#define SET(i, field) \
4406 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004407 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004408 if (!o) { \
4409 Py_DECREF(value); \
4410 return NULL; \
4411 } \
4412 PyStructSequence_SET_ITEM(value, i, o); \
4413 } \
4414
4415 SET(0, u.sysname);
4416 SET(1, u.nodename);
4417 SET(2, u.release);
4418 SET(3, u.version);
4419 SET(4, u.machine);
4420
4421#undef SET
4422
4423 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004424}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004425#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004426
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004427
Larry Hastings9cf065c2012-06-22 16:30:09 -07004428
4429typedef struct {
4430 int now;
4431 time_t atime_s;
4432 long atime_ns;
4433 time_t mtime_s;
4434 long mtime_ns;
4435} utime_t;
4436
4437/*
Victor Stinner484df002014-10-09 13:52:31 +02004438 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004439 * they also intentionally leak the declaration of a pointer named "time"
4440 */
4441#define UTIME_TO_TIMESPEC \
4442 struct timespec ts[2]; \
4443 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004444 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004445 time = NULL; \
4446 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004447 ts[0].tv_sec = ut->atime_s; \
4448 ts[0].tv_nsec = ut->atime_ns; \
4449 ts[1].tv_sec = ut->mtime_s; \
4450 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004451 time = ts; \
4452 } \
4453
4454#define UTIME_TO_TIMEVAL \
4455 struct timeval tv[2]; \
4456 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004457 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004458 time = NULL; \
4459 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004460 tv[0].tv_sec = ut->atime_s; \
4461 tv[0].tv_usec = ut->atime_ns / 1000; \
4462 tv[1].tv_sec = ut->mtime_s; \
4463 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004464 time = tv; \
4465 } \
4466
4467#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004468 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004469 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004470 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004471 time = NULL; \
4472 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004473 u.actime = ut->atime_s; \
4474 u.modtime = ut->mtime_s; \
4475 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004476 }
4477
4478#define UTIME_TO_TIME_T \
4479 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004480 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004481 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004482 time = NULL; \
4483 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004484 timet[0] = ut->atime_s; \
4485 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004486 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004487 } \
4488
4489
Victor Stinner528a9ab2015-09-03 21:30:26 +02004490#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004491
4492static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004493utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004494{
4495#ifdef HAVE_UTIMENSAT
4496 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4497 UTIME_TO_TIMESPEC;
4498 return utimensat(dir_fd, path, time, flags);
4499#elif defined(HAVE_FUTIMESAT)
4500 UTIME_TO_TIMEVAL;
4501 /*
4502 * follow_symlinks will never be false here;
4503 * we only allow !follow_symlinks and dir_fd together
4504 * if we have utimensat()
4505 */
4506 assert(follow_symlinks);
4507 return futimesat(dir_fd, path, time);
4508#endif
4509}
4510
Larry Hastings2f936352014-08-05 14:04:04 +10004511 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4512#else
4513 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004514#endif
4515
Victor Stinner528a9ab2015-09-03 21:30:26 +02004516#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004517
4518static int
Victor Stinner484df002014-10-09 13:52:31 +02004519utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004520{
4521#ifdef HAVE_FUTIMENS
4522 UTIME_TO_TIMESPEC;
4523 return futimens(fd, time);
4524#else
4525 UTIME_TO_TIMEVAL;
4526 return futimes(fd, time);
4527#endif
4528}
4529
Larry Hastings2f936352014-08-05 14:04:04 +10004530 #define PATH_UTIME_HAVE_FD 1
4531#else
4532 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004533#endif
4534
Victor Stinner5ebae872015-09-22 01:29:33 +02004535#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4536# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4537#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538
Victor Stinner4552ced2015-09-21 22:37:15 +02004539#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004540
4541static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004542utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004543{
4544#ifdef HAVE_UTIMENSAT
4545 UTIME_TO_TIMESPEC;
4546 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4547#else
4548 UTIME_TO_TIMEVAL;
4549 return lutimes(path, time);
4550#endif
4551}
4552
4553#endif
4554
4555#ifndef MS_WINDOWS
4556
4557static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004558utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004559{
4560#ifdef HAVE_UTIMENSAT
4561 UTIME_TO_TIMESPEC;
4562 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4563#elif defined(HAVE_UTIMES)
4564 UTIME_TO_TIMEVAL;
4565 return utimes(path, time);
4566#elif defined(HAVE_UTIME_H)
4567 UTIME_TO_UTIMBUF;
4568 return utime(path, time);
4569#else
4570 UTIME_TO_TIME_T;
4571 return utime(path, time);
4572#endif
4573}
4574
4575#endif
4576
Larry Hastings76ad59b2012-05-03 00:30:07 -07004577static int
4578split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4579{
4580 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004581 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004582 divmod = PyNumber_Divmod(py_long, billion);
4583 if (!divmod)
4584 goto exit;
4585 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4586 if ((*s == -1) && PyErr_Occurred())
4587 goto exit;
4588 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004589 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004590 goto exit;
4591
4592 result = 1;
4593exit:
4594 Py_XDECREF(divmod);
4595 return result;
4596}
4597
Larry Hastings2f936352014-08-05 14:04:04 +10004598
4599/*[clinic input]
4600os.utime
4601
4602 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4603 times: object = NULL
4604 *
4605 ns: object = NULL
4606 dir_fd: dir_fd(requires='futimensat') = None
4607 follow_symlinks: bool=True
4608
Martin Panter0ff89092015-09-09 01:56:53 +00004609# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004610
4611Set the access and modified time of path.
4612
4613path may always be specified as a string.
4614On some platforms, path may also be specified as an open file descriptor.
4615 If this functionality is unavailable, using it raises an exception.
4616
4617If times is not None, it must be a tuple (atime, mtime);
4618 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004619If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004620 atime_ns and mtime_ns should be expressed as integer nanoseconds
4621 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004622If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004623Specifying tuples for both times and ns is an error.
4624
4625If dir_fd is not None, it should be a file descriptor open to a directory,
4626 and path should be relative; path will then be relative to that directory.
4627If follow_symlinks is False, and the last element of the path is a symbolic
4628 link, utime will modify the symbolic link itself instead of the file the
4629 link points to.
4630It is an error to use dir_fd or follow_symlinks when specifying path
4631 as an open file descriptor.
4632dir_fd and follow_symlinks may not be available on your platform.
4633 If they are unavailable, using them will raise a NotImplementedError.
4634
4635[clinic start generated code]*/
4636
Larry Hastings2f936352014-08-05 14:04:04 +10004637static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004638os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4639 int dir_fd, int follow_symlinks)
4640/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004641{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004642#ifdef MS_WINDOWS
4643 HANDLE hFile;
4644 FILETIME atime, mtime;
4645#else
4646 int result;
4647#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004648
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004650 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004651
Christian Heimesb3c87242013-08-01 00:08:16 +02004652 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004653
Larry Hastings9cf065c2012-06-22 16:30:09 -07004654 if (times && (times != Py_None) && ns) {
4655 PyErr_SetString(PyExc_ValueError,
4656 "utime: you may specify either 'times'"
4657 " or 'ns' but not both");
4658 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004659 }
4660
4661 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004662 time_t a_sec, m_sec;
4663 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004664 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004665 PyErr_SetString(PyExc_TypeError,
4666 "utime: 'times' must be either"
4667 " a tuple of two ints or None");
4668 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004669 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004670 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004671 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004672 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004673 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004674 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004676 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004677 utime.atime_s = a_sec;
4678 utime.atime_ns = a_nsec;
4679 utime.mtime_s = m_sec;
4680 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004681 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004682 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004683 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004684 PyErr_SetString(PyExc_TypeError,
4685 "utime: 'ns' must be a tuple of two ints");
4686 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004687 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004688 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004689 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004691 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004692 &utime.mtime_s, &utime.mtime_ns)) {
4693 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004694 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004695 }
4696 else {
4697 /* times and ns are both None/unspecified. use "now". */
4698 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004699 }
4700
Victor Stinner4552ced2015-09-21 22:37:15 +02004701#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702 if (follow_symlinks_specified("utime", follow_symlinks))
4703 goto exit;
4704#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004705
Larry Hastings2f936352014-08-05 14:04:04 +10004706 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4707 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4708 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004709 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004710
Larry Hastings9cf065c2012-06-22 16:30:09 -07004711#if !defined(HAVE_UTIMENSAT)
4712 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004713 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004714 "utime: cannot use dir_fd and follow_symlinks "
4715 "together on this platform");
4716 goto exit;
4717 }
4718#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004719
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004720#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004721 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004722 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4723 NULL, OPEN_EXISTING,
4724 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004725 Py_END_ALLOW_THREADS
4726 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004727 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004728 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004729 }
4730
Larry Hastings9cf065c2012-06-22 16:30:09 -07004731 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004732 GetSystemTimeAsFileTime(&mtime);
4733 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004734 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004735 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004736 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4737 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004738 }
4739 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4740 /* Avoid putting the file name into the error here,
4741 as that may confuse the user into believing that
4742 something is wrong with the file, when it also
4743 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004744 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004746 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004747#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004748 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004749
Victor Stinner4552ced2015-09-21 22:37:15 +02004750#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004751 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004752 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004754#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755
Victor Stinner528a9ab2015-09-03 21:30:26 +02004756#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004758 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004759 else
4760#endif
4761
Victor Stinner528a9ab2015-09-03 21:30:26 +02004762#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004763 if (path->fd != -1)
4764 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 else
4766#endif
4767
Larry Hastings2f936352014-08-05 14:04:04 +10004768 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004769
4770 Py_END_ALLOW_THREADS
4771
4772 if (result < 0) {
4773 /* see previous comment about not putting filename in error here */
4774 return_value = posix_error();
4775 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004776 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004777
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004778#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004779
4780 Py_INCREF(Py_None);
4781 return_value = Py_None;
4782
4783exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004784#ifdef MS_WINDOWS
4785 if (hFile != INVALID_HANDLE_VALUE)
4786 CloseHandle(hFile);
4787#endif
4788 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004789}
4790
Guido van Rossum3b066191991-06-04 19:40:25 +00004791/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004792
Larry Hastings2f936352014-08-05 14:04:04 +10004793
4794/*[clinic input]
4795os._exit
4796
4797 status: int
4798
4799Exit to the system with specified status, without normal exit processing.
4800[clinic start generated code]*/
4801
Larry Hastings2f936352014-08-05 14:04:04 +10004802static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004803os__exit_impl(PyObject *module, int status)
4804/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004805{
4806 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004807 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004808}
4809
Steve Dowercc16be82016-09-08 10:35:16 -07004810#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4811#define EXECV_CHAR wchar_t
4812#else
4813#define EXECV_CHAR char
4814#endif
4815
Martin v. Löwis114619e2002-10-07 06:44:21 +00004816#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4817static void
Steve Dowercc16be82016-09-08 10:35:16 -07004818free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004819{
Victor Stinner8c62be82010-05-06 00:08:46 +00004820 Py_ssize_t i;
4821 for (i = 0; i < count; i++)
4822 PyMem_Free(array[i]);
4823 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004824}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004825
Berker Peksag81816462016-09-15 20:19:47 +03004826static int
4827fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004828{
Victor Stinner8c62be82010-05-06 00:08:46 +00004829 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004830 PyObject *ub;
4831 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004832#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004833 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004834 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004835 *out = PyUnicode_AsWideCharString(ub, &size);
4836 if (*out)
4837 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004838#else
Berker Peksag81816462016-09-15 20:19:47 +03004839 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004840 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004841 size = PyBytes_GET_SIZE(ub);
4842 *out = PyMem_Malloc(size + 1);
4843 if (*out) {
4844 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4845 result = 1;
4846 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004847 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004848#endif
Berker Peksag81816462016-09-15 20:19:47 +03004849 Py_DECREF(ub);
4850 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004851}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004852#endif
4853
Ross Lagerwall7807c352011-03-17 20:20:30 +02004854#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004855static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004856parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4857{
Victor Stinner8c62be82010-05-06 00:08:46 +00004858 Py_ssize_t i, pos, envc;
4859 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004860 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004861 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004862
Victor Stinner8c62be82010-05-06 00:08:46 +00004863 i = PyMapping_Size(env);
4864 if (i < 0)
4865 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004866 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 if (envlist == NULL) {
4868 PyErr_NoMemory();
4869 return NULL;
4870 }
4871 envc = 0;
4872 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004873 if (!keys)
4874 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004875 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004876 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004877 goto error;
4878 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4879 PyErr_Format(PyExc_TypeError,
4880 "env.keys() or env.values() is not a list");
4881 goto error;
4882 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004883
Victor Stinner8c62be82010-05-06 00:08:46 +00004884 for (pos = 0; pos < i; pos++) {
4885 key = PyList_GetItem(keys, pos);
4886 val = PyList_GetItem(vals, pos);
4887 if (!key || !val)
4888 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004889
Berker Peksag81816462016-09-15 20:19:47 +03004890#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4891 if (!PyUnicode_FSDecoder(key, &key2))
4892 goto error;
4893 if (!PyUnicode_FSDecoder(val, &val2)) {
4894 Py_DECREF(key2);
4895 goto error;
4896 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004897 /* Search from index 1 because on Windows starting '=' is allowed for
4898 defining hidden environment variables. */
4899 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4900 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4901 {
4902 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004903 Py_DECREF(key2);
4904 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004905 goto error;
4906 }
Berker Peksag81816462016-09-15 20:19:47 +03004907 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4908#else
4909 if (!PyUnicode_FSConverter(key, &key2))
4910 goto error;
4911 if (!PyUnicode_FSConverter(val, &val2)) {
4912 Py_DECREF(key2);
4913 goto error;
4914 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004915 if (PyBytes_GET_SIZE(key2) == 0 ||
4916 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4917 {
4918 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004919 Py_DECREF(key2);
4920 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004921 goto error;
4922 }
Berker Peksag81816462016-09-15 20:19:47 +03004923 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4924 PyBytes_AS_STRING(val2));
4925#endif
4926 Py_DECREF(key2);
4927 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004928 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004930
4931 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4932 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004933 goto error;
4934 }
Berker Peksag81816462016-09-15 20:19:47 +03004935
Steve Dowercc16be82016-09-08 10:35:16 -07004936 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004937 }
4938 Py_DECREF(vals);
4939 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004940
Victor Stinner8c62be82010-05-06 00:08:46 +00004941 envlist[envc] = 0;
4942 *envc_ptr = envc;
4943 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004944
4945error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004946 Py_XDECREF(keys);
4947 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004948 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004949 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004950}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004951
Steve Dowercc16be82016-09-08 10:35:16 -07004952static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004953parse_arglist(PyObject* argv, Py_ssize_t *argc)
4954{
4955 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004956 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004957 if (argvlist == NULL) {
4958 PyErr_NoMemory();
4959 return NULL;
4960 }
4961 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004962 PyObject* item = PySequence_ITEM(argv, i);
4963 if (item == NULL)
4964 goto fail;
4965 if (!fsconvert_strdup(item, &argvlist[i])) {
4966 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004967 goto fail;
4968 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004969 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004970 }
4971 argvlist[*argc] = NULL;
4972 return argvlist;
4973fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004974 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004975 free_string_array(argvlist, *argc);
4976 return NULL;
4977}
Steve Dowercc16be82016-09-08 10:35:16 -07004978
Ross Lagerwall7807c352011-03-17 20:20:30 +02004979#endif
4980
Larry Hastings2f936352014-08-05 14:04:04 +10004981
Ross Lagerwall7807c352011-03-17 20:20:30 +02004982#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004983/*[clinic input]
4984os.execv
4985
Steve Dowercc16be82016-09-08 10:35:16 -07004986 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004987 Path of executable file.
4988 argv: object
4989 Tuple or list of strings.
4990 /
4991
4992Execute an executable path with arguments, replacing current process.
4993[clinic start generated code]*/
4994
Larry Hastings2f936352014-08-05 14:04:04 +10004995static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004996os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4997/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004998{
Steve Dowercc16be82016-09-08 10:35:16 -07004999 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005000 Py_ssize_t argc;
5001
5002 /* execv has two arguments: (path, argv), where
5003 argv is a list or tuple of strings. */
5004
Ross Lagerwall7807c352011-03-17 20:20:30 +02005005 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5006 PyErr_SetString(PyExc_TypeError,
5007 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005008 return NULL;
5009 }
5010 argc = PySequence_Size(argv);
5011 if (argc < 1) {
5012 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005013 return NULL;
5014 }
5015
5016 argvlist = parse_arglist(argv, &argc);
5017 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005018 return NULL;
5019 }
Steve Dowerbce26262016-11-19 19:17:26 -08005020 if (!argvlist[0][0]) {
5021 PyErr_SetString(PyExc_ValueError,
5022 "execv() arg 2 first element cannot be empty");
5023 free_string_array(argvlist, argc);
5024 return NULL;
5025 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005026
Steve Dowerbce26262016-11-19 19:17:26 -08005027 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005028#ifdef HAVE_WEXECV
5029 _wexecv(path->wide, argvlist);
5030#else
5031 execv(path->narrow, argvlist);
5032#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005033 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005034
5035 /* If we get here it's definitely an error */
5036
5037 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005038 return posix_error();
5039}
5040
Larry Hastings2f936352014-08-05 14:04:04 +10005041
5042/*[clinic input]
5043os.execve
5044
5045 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5046 Path of executable file.
5047 argv: object
5048 Tuple or list of strings.
5049 env: object
5050 Dictionary of strings mapping to strings.
5051
5052Execute an executable path with arguments, replacing current process.
5053[clinic start generated code]*/
5054
Larry Hastings2f936352014-08-05 14:04:04 +10005055static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005056os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5057/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005058{
Steve Dowercc16be82016-09-08 10:35:16 -07005059 EXECV_CHAR **argvlist = NULL;
5060 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005061 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005062
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 /* execve has three arguments: (path, argv, env), where
5064 argv is a list or tuple of strings and env is a dictionary
5065 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005066
Ross Lagerwall7807c352011-03-17 20:20:30 +02005067 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005068 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005069 "execve: argv must be a tuple or list");
5070 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005071 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005072 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005073 if (argc < 1) {
5074 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5075 return NULL;
5076 }
5077
Victor Stinner8c62be82010-05-06 00:08:46 +00005078 if (!PyMapping_Check(env)) {
5079 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005080 "execve: environment must be a mapping object");
5081 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005082 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005083
Ross Lagerwall7807c352011-03-17 20:20:30 +02005084 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005085 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005086 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005087 }
Steve Dowerbce26262016-11-19 19:17:26 -08005088 if (!argvlist[0][0]) {
5089 PyErr_SetString(PyExc_ValueError,
5090 "execve: argv first element cannot be empty");
5091 goto fail;
5092 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005093
Victor Stinner8c62be82010-05-06 00:08:46 +00005094 envlist = parse_envlist(env, &envc);
5095 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005096 goto fail;
5097
Steve Dowerbce26262016-11-19 19:17:26 -08005098 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005099#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005100 if (path->fd > -1)
5101 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005102 else
5103#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005104#ifdef HAVE_WEXECV
5105 _wexecve(path->wide, argvlist, envlist);
5106#else
Larry Hastings2f936352014-08-05 14:04:04 +10005107 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005108#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005109 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005110
5111 /* If we get here it's definitely an error */
5112
Larry Hastings2f936352014-08-05 14:04:04 +10005113 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005114
Steve Dowercc16be82016-09-08 10:35:16 -07005115 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005116 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005117 if (argvlist)
5118 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005119 return NULL;
5120}
Steve Dowercc16be82016-09-08 10:35:16 -07005121
Larry Hastings9cf065c2012-06-22 16:30:09 -07005122#endif /* HAVE_EXECV */
5123
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005124
Steve Dowercc16be82016-09-08 10:35:16 -07005125#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005126/*[clinic input]
5127os.spawnv
5128
5129 mode: int
5130 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005131 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005132 Path of executable file.
5133 argv: object
5134 Tuple or list of strings.
5135 /
5136
5137Execute the program specified by path in a new process.
5138[clinic start generated code]*/
5139
Larry Hastings2f936352014-08-05 14:04:04 +10005140static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005141os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5142/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005143{
Steve Dowercc16be82016-09-08 10:35:16 -07005144 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005145 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005146 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005147 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005148 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005149
Victor Stinner8c62be82010-05-06 00:08:46 +00005150 /* spawnv has three arguments: (mode, path, argv), where
5151 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005152
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 if (PyList_Check(argv)) {
5154 argc = PyList_Size(argv);
5155 getitem = PyList_GetItem;
5156 }
5157 else if (PyTuple_Check(argv)) {
5158 argc = PyTuple_Size(argv);
5159 getitem = PyTuple_GetItem;
5160 }
5161 else {
5162 PyErr_SetString(PyExc_TypeError,
5163 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 return NULL;
5165 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005166 if (argc == 0) {
5167 PyErr_SetString(PyExc_ValueError,
5168 "spawnv() arg 2 cannot be empty");
5169 return NULL;
5170 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005171
Steve Dowercc16be82016-09-08 10:35:16 -07005172 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005173 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005174 return PyErr_NoMemory();
5175 }
5176 for (i = 0; i < argc; i++) {
5177 if (!fsconvert_strdup((*getitem)(argv, i),
5178 &argvlist[i])) {
5179 free_string_array(argvlist, i);
5180 PyErr_SetString(
5181 PyExc_TypeError,
5182 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005183 return NULL;
5184 }
Steve Dower93ff8722016-11-19 19:03:54 -08005185 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005186 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005187 PyErr_SetString(
5188 PyExc_ValueError,
5189 "spawnv() arg 2 first element cannot be empty");
5190 return NULL;
5191 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 }
5193 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005194
Victor Stinner8c62be82010-05-06 00:08:46 +00005195 if (mode == _OLD_P_OVERLAY)
5196 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005197
Victor Stinner8c62be82010-05-06 00:08:46 +00005198 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005199 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005200#ifdef HAVE_WSPAWNV
5201 spawnval = _wspawnv(mode, path->wide, argvlist);
5202#else
5203 spawnval = _spawnv(mode, path->narrow, argvlist);
5204#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005205 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005206 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005207
Victor Stinner8c62be82010-05-06 00:08:46 +00005208 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005209
Victor Stinner8c62be82010-05-06 00:08:46 +00005210 if (spawnval == -1)
5211 return posix_error();
5212 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005213 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005214}
5215
5216
Larry Hastings2f936352014-08-05 14:04:04 +10005217/*[clinic input]
5218os.spawnve
5219
5220 mode: int
5221 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005222 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005223 Path of executable file.
5224 argv: object
5225 Tuple or list of strings.
5226 env: object
5227 Dictionary of strings mapping to strings.
5228 /
5229
5230Execute the program specified by path in a new process.
5231[clinic start generated code]*/
5232
Larry Hastings2f936352014-08-05 14:04:04 +10005233static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005234os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005235 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005236/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005237{
Steve Dowercc16be82016-09-08 10:35:16 -07005238 EXECV_CHAR **argvlist;
5239 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005240 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005241 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005242 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005243 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005244 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005245
Victor Stinner8c62be82010-05-06 00:08:46 +00005246 /* spawnve has four arguments: (mode, path, argv, env), where
5247 argv is a list or tuple of strings and env is a dictionary
5248 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005249
Victor Stinner8c62be82010-05-06 00:08:46 +00005250 if (PyList_Check(argv)) {
5251 argc = PyList_Size(argv);
5252 getitem = PyList_GetItem;
5253 }
5254 else if (PyTuple_Check(argv)) {
5255 argc = PyTuple_Size(argv);
5256 getitem = PyTuple_GetItem;
5257 }
5258 else {
5259 PyErr_SetString(PyExc_TypeError,
5260 "spawnve() arg 2 must be a tuple or list");
5261 goto fail_0;
5262 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005263 if (argc == 0) {
5264 PyErr_SetString(PyExc_ValueError,
5265 "spawnve() arg 2 cannot be empty");
5266 goto fail_0;
5267 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005268 if (!PyMapping_Check(env)) {
5269 PyErr_SetString(PyExc_TypeError,
5270 "spawnve() arg 3 must be a mapping object");
5271 goto fail_0;
5272 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005273
Steve Dowercc16be82016-09-08 10:35:16 -07005274 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005275 if (argvlist == NULL) {
5276 PyErr_NoMemory();
5277 goto fail_0;
5278 }
5279 for (i = 0; i < argc; i++) {
5280 if (!fsconvert_strdup((*getitem)(argv, i),
5281 &argvlist[i]))
5282 {
5283 lastarg = i;
5284 goto fail_1;
5285 }
Steve Dowerbce26262016-11-19 19:17:26 -08005286 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005287 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005288 PyErr_SetString(
5289 PyExc_ValueError,
5290 "spawnv() arg 2 first element cannot be empty");
5291 goto fail_1;
5292 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005293 }
5294 lastarg = argc;
5295 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005296
Victor Stinner8c62be82010-05-06 00:08:46 +00005297 envlist = parse_envlist(env, &envc);
5298 if (envlist == NULL)
5299 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005300
Victor Stinner8c62be82010-05-06 00:08:46 +00005301 if (mode == _OLD_P_OVERLAY)
5302 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005303
Victor Stinner8c62be82010-05-06 00:08:46 +00005304 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005305 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005306#ifdef HAVE_WSPAWNV
5307 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5308#else
5309 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5310#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005311 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005312 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005313
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 if (spawnval == -1)
5315 (void) posix_error();
5316 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005317 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005318
Victor Stinner8c62be82010-05-06 00:08:46 +00005319 while (--envc >= 0)
5320 PyMem_DEL(envlist[envc]);
5321 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005322 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005323 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005324 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005325 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005326}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005327
Guido van Rossuma1065681999-01-25 23:20:23 +00005328#endif /* HAVE_SPAWNV */
5329
5330
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005331#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005332
5333/* Helper function to validate arguments.
5334 Returns 0 on success. non-zero on failure with a TypeError raised.
5335 If obj is non-NULL it must be callable. */
5336static int
5337check_null_or_callable(PyObject *obj, const char* obj_name)
5338{
5339 if (obj && !PyCallable_Check(obj)) {
5340 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5341 obj_name, Py_TYPE(obj)->tp_name);
5342 return -1;
5343 }
5344 return 0;
5345}
5346
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005347/*[clinic input]
5348os.register_at_fork
5349
Gregory P. Smith163468a2017-05-29 10:03:41 -07005350 *
5351 before: object=NULL
5352 A callable to be called in the parent before the fork() syscall.
5353 after_in_child: object=NULL
5354 A callable to be called in the child after fork().
5355 after_in_parent: object=NULL
5356 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005357
Gregory P. Smith163468a2017-05-29 10:03:41 -07005358Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005359
Gregory P. Smith163468a2017-05-29 10:03:41 -07005360'before' callbacks are called in reverse order.
5361'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005362
5363[clinic start generated code]*/
5364
5365static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005366os_register_at_fork_impl(PyObject *module, PyObject *before,
5367 PyObject *after_in_child, PyObject *after_in_parent)
5368/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005369{
5370 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005371
Gregory P. Smith163468a2017-05-29 10:03:41 -07005372 if (!before && !after_in_child && !after_in_parent) {
5373 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5374 return NULL;
5375 }
5376 if (check_null_or_callable(before, "before") ||
5377 check_null_or_callable(after_in_child, "after_in_child") ||
5378 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005379 return NULL;
5380 }
5381 interp = PyThreadState_Get()->interp;
5382
Gregory P. Smith163468a2017-05-29 10:03:41 -07005383 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005384 return NULL;
5385 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005386 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005387 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005388 }
5389 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5390 return NULL;
5391 }
5392 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005393}
5394#endif /* HAVE_FORK */
5395
5396
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005397#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005398/*[clinic input]
5399os.fork1
5400
5401Fork a child process with a single multiplexed (i.e., not bound) thread.
5402
5403Return 0 to child process and PID of child to parent process.
5404[clinic start generated code]*/
5405
Larry Hastings2f936352014-08-05 14:04:04 +10005406static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005407os_fork1_impl(PyObject *module)
5408/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005409{
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005411
5412 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005413 pid = fork1();
5414 if (pid == 0) {
5415 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005416 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005417 } else {
5418 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005419 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005420 }
5421 if (pid == -1)
5422 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005423 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005424}
Larry Hastings2f936352014-08-05 14:04:04 +10005425#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005426
5427
Guido van Rossumad0ee831995-03-01 10:34:45 +00005428#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005429/*[clinic input]
5430os.fork
5431
5432Fork a child process.
5433
5434Return 0 to child process and PID of child to parent process.
5435[clinic start generated code]*/
5436
Larry Hastings2f936352014-08-05 14:04:04 +10005437static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005438os_fork_impl(PyObject *module)
5439/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005440{
Victor Stinner8c62be82010-05-06 00:08:46 +00005441 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005442
5443 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005444 pid = fork();
5445 if (pid == 0) {
5446 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005447 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005448 } else {
5449 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005450 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005451 }
5452 if (pid == -1)
5453 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005454 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005455}
Larry Hastings2f936352014-08-05 14:04:04 +10005456#endif /* HAVE_FORK */
5457
Guido van Rossum85e3b011991-06-03 12:42:10 +00005458
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005459#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005460#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005461/*[clinic input]
5462os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005463
Larry Hastings2f936352014-08-05 14:04:04 +10005464 policy: int
5465
5466Get the maximum scheduling priority for policy.
5467[clinic start generated code]*/
5468
Larry Hastings2f936352014-08-05 14:04:04 +10005469static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005470os_sched_get_priority_max_impl(PyObject *module, int policy)
5471/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005472{
5473 int max;
5474
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005475 max = sched_get_priority_max(policy);
5476 if (max < 0)
5477 return posix_error();
5478 return PyLong_FromLong(max);
5479}
5480
Larry Hastings2f936352014-08-05 14:04:04 +10005481
5482/*[clinic input]
5483os.sched_get_priority_min
5484
5485 policy: int
5486
5487Get the minimum scheduling priority for policy.
5488[clinic start generated code]*/
5489
Larry Hastings2f936352014-08-05 14:04:04 +10005490static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005491os_sched_get_priority_min_impl(PyObject *module, int policy)
5492/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005493{
5494 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005495 if (min < 0)
5496 return posix_error();
5497 return PyLong_FromLong(min);
5498}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005499#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5500
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005501
Larry Hastings2f936352014-08-05 14:04:04 +10005502#ifdef HAVE_SCHED_SETSCHEDULER
5503/*[clinic input]
5504os.sched_getscheduler
5505 pid: pid_t
5506 /
5507
5508Get the scheduling policy for the process identifiedy by pid.
5509
5510Passing 0 for pid returns the scheduling policy for the calling process.
5511[clinic start generated code]*/
5512
Larry Hastings2f936352014-08-05 14:04:04 +10005513static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005514os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5515/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005516{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005517 int policy;
5518
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005519 policy = sched_getscheduler(pid);
5520 if (policy < 0)
5521 return posix_error();
5522 return PyLong_FromLong(policy);
5523}
Larry Hastings2f936352014-08-05 14:04:04 +10005524#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005525
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005526
5527#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005528/*[clinic input]
5529class os.sched_param "PyObject *" "&SchedParamType"
5530
5531@classmethod
5532os.sched_param.__new__
5533
5534 sched_priority: object
5535 A scheduling parameter.
5536
5537Current has only one field: sched_priority");
5538[clinic start generated code]*/
5539
Larry Hastings2f936352014-08-05 14:04:04 +10005540static PyObject *
5541os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005542/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005543{
5544 PyObject *res;
5545
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005546 res = PyStructSequence_New(type);
5547 if (!res)
5548 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005549 Py_INCREF(sched_priority);
5550 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005551 return res;
5552}
5553
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005554
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005555PyDoc_VAR(os_sched_param__doc__);
5556
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005557static PyStructSequence_Field sched_param_fields[] = {
5558 {"sched_priority", "the scheduling priority"},
5559 {0}
5560};
5561
5562static PyStructSequence_Desc sched_param_desc = {
5563 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005564 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005565 sched_param_fields,
5566 1
5567};
5568
5569static int
5570convert_sched_param(PyObject *param, struct sched_param *res)
5571{
5572 long priority;
5573
5574 if (Py_TYPE(param) != &SchedParamType) {
5575 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5576 return 0;
5577 }
5578 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5579 if (priority == -1 && PyErr_Occurred())
5580 return 0;
5581 if (priority > INT_MAX || priority < INT_MIN) {
5582 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5583 return 0;
5584 }
5585 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5586 return 1;
5587}
Larry Hastings2f936352014-08-05 14:04:04 +10005588#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005589
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005590
5591#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005592/*[clinic input]
5593os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005594
Larry Hastings2f936352014-08-05 14:04:04 +10005595 pid: pid_t
5596 policy: int
5597 param: sched_param
5598 /
5599
5600Set the scheduling policy for the process identified by pid.
5601
5602If pid is 0, the calling process is changed.
5603param is an instance of sched_param.
5604[clinic start generated code]*/
5605
Larry Hastings2f936352014-08-05 14:04:04 +10005606static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005607os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005608 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005609/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005610{
Jesus Cea9c822272011-09-10 01:40:52 +02005611 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005612 ** sched_setscheduler() returns 0 in Linux, but the previous
5613 ** scheduling policy under Solaris/Illumos, and others.
5614 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005615 */
Larry Hastings2f936352014-08-05 14:04:04 +10005616 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005617 return posix_error();
5618 Py_RETURN_NONE;
5619}
Larry Hastings2f936352014-08-05 14:04:04 +10005620#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005621
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005622
5623#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005624/*[clinic input]
5625os.sched_getparam
5626 pid: pid_t
5627 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005628
Larry Hastings2f936352014-08-05 14:04:04 +10005629Returns scheduling parameters for the process identified by pid.
5630
5631If pid is 0, returns parameters for the calling process.
5632Return value is an instance of sched_param.
5633[clinic start generated code]*/
5634
Larry Hastings2f936352014-08-05 14:04:04 +10005635static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005636os_sched_getparam_impl(PyObject *module, pid_t pid)
5637/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005638{
5639 struct sched_param param;
5640 PyObject *result;
5641 PyObject *priority;
5642
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005643 if (sched_getparam(pid, &param))
5644 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005645 result = PyStructSequence_New(&SchedParamType);
5646 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005647 return NULL;
5648 priority = PyLong_FromLong(param.sched_priority);
5649 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005650 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005651 return NULL;
5652 }
Larry Hastings2f936352014-08-05 14:04:04 +10005653 PyStructSequence_SET_ITEM(result, 0, priority);
5654 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005655}
5656
Larry Hastings2f936352014-08-05 14:04:04 +10005657
5658/*[clinic input]
5659os.sched_setparam
5660 pid: pid_t
5661 param: sched_param
5662 /
5663
5664Set scheduling parameters for the process identified by pid.
5665
5666If pid is 0, sets parameters for the calling process.
5667param should be an instance of sched_param.
5668[clinic start generated code]*/
5669
Larry Hastings2f936352014-08-05 14:04:04 +10005670static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005671os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005672 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005673/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005674{
5675 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005676 return posix_error();
5677 Py_RETURN_NONE;
5678}
Larry Hastings2f936352014-08-05 14:04:04 +10005679#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005680
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005681
5682#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005683/*[clinic input]
5684os.sched_rr_get_interval -> double
5685 pid: pid_t
5686 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005687
Larry Hastings2f936352014-08-05 14:04:04 +10005688Return the round-robin quantum for the process identified by pid, in seconds.
5689
5690Value returned is a float.
5691[clinic start generated code]*/
5692
Larry Hastings2f936352014-08-05 14:04:04 +10005693static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005694os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5695/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005696{
5697 struct timespec interval;
5698 if (sched_rr_get_interval(pid, &interval)) {
5699 posix_error();
5700 return -1.0;
5701 }
5702 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5703}
5704#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005705
Larry Hastings2f936352014-08-05 14:04:04 +10005706
5707/*[clinic input]
5708os.sched_yield
5709
5710Voluntarily relinquish the CPU.
5711[clinic start generated code]*/
5712
Larry Hastings2f936352014-08-05 14:04:04 +10005713static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005714os_sched_yield_impl(PyObject *module)
5715/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005716{
5717 if (sched_yield())
5718 return posix_error();
5719 Py_RETURN_NONE;
5720}
5721
Benjamin Peterson2740af82011-08-02 17:41:34 -05005722#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005723/* The minimum number of CPUs allocated in a cpu_set_t */
5724static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005725
Larry Hastings2f936352014-08-05 14:04:04 +10005726/*[clinic input]
5727os.sched_setaffinity
5728 pid: pid_t
5729 mask : object
5730 /
5731
5732Set the CPU affinity of the process identified by pid to mask.
5733
5734mask should be an iterable of integers identifying CPUs.
5735[clinic start generated code]*/
5736
Larry Hastings2f936352014-08-05 14:04:04 +10005737static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005738os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5739/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005740{
Antoine Pitrou84869872012-08-04 16:16:35 +02005741 int ncpus;
5742 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005743 cpu_set_t *cpu_set = NULL;
5744 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005745
Larry Hastings2f936352014-08-05 14:04:04 +10005746 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005747 if (iterator == NULL)
5748 return NULL;
5749
5750 ncpus = NCPUS_START;
5751 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005752 cpu_set = CPU_ALLOC(ncpus);
5753 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005754 PyErr_NoMemory();
5755 goto error;
5756 }
Larry Hastings2f936352014-08-05 14:04:04 +10005757 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005758
5759 while ((item = PyIter_Next(iterator))) {
5760 long cpu;
5761 if (!PyLong_Check(item)) {
5762 PyErr_Format(PyExc_TypeError,
5763 "expected an iterator of ints, "
5764 "but iterator yielded %R",
5765 Py_TYPE(item));
5766 Py_DECREF(item);
5767 goto error;
5768 }
5769 cpu = PyLong_AsLong(item);
5770 Py_DECREF(item);
5771 if (cpu < 0) {
5772 if (!PyErr_Occurred())
5773 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5774 goto error;
5775 }
5776 if (cpu > INT_MAX - 1) {
5777 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5778 goto error;
5779 }
5780 if (cpu >= ncpus) {
5781 /* Grow CPU mask to fit the CPU number */
5782 int newncpus = ncpus;
5783 cpu_set_t *newmask;
5784 size_t newsetsize;
5785 while (newncpus <= cpu) {
5786 if (newncpus > INT_MAX / 2)
5787 newncpus = cpu + 1;
5788 else
5789 newncpus = newncpus * 2;
5790 }
5791 newmask = CPU_ALLOC(newncpus);
5792 if (newmask == NULL) {
5793 PyErr_NoMemory();
5794 goto error;
5795 }
5796 newsetsize = CPU_ALLOC_SIZE(newncpus);
5797 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005798 memcpy(newmask, cpu_set, setsize);
5799 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005800 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005801 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005802 ncpus = newncpus;
5803 }
Larry Hastings2f936352014-08-05 14:04:04 +10005804 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005805 }
5806 Py_CLEAR(iterator);
5807
Larry Hastings2f936352014-08-05 14:04:04 +10005808 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005809 posix_error();
5810 goto error;
5811 }
Larry Hastings2f936352014-08-05 14:04:04 +10005812 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005813 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005814
5815error:
Larry Hastings2f936352014-08-05 14:04:04 +10005816 if (cpu_set)
5817 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005818 Py_XDECREF(iterator);
5819 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005820}
5821
Larry Hastings2f936352014-08-05 14:04:04 +10005822
5823/*[clinic input]
5824os.sched_getaffinity
5825 pid: pid_t
5826 /
5827
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005828Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005829
5830The affinity is returned as a set of CPU identifiers.
5831[clinic start generated code]*/
5832
Larry Hastings2f936352014-08-05 14:04:04 +10005833static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005834os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005835/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005836{
Antoine Pitrou84869872012-08-04 16:16:35 +02005837 int cpu, ncpus, count;
5838 size_t setsize;
5839 cpu_set_t *mask = NULL;
5840 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005841
Antoine Pitrou84869872012-08-04 16:16:35 +02005842 ncpus = NCPUS_START;
5843 while (1) {
5844 setsize = CPU_ALLOC_SIZE(ncpus);
5845 mask = CPU_ALLOC(ncpus);
5846 if (mask == NULL)
5847 return PyErr_NoMemory();
5848 if (sched_getaffinity(pid, setsize, mask) == 0)
5849 break;
5850 CPU_FREE(mask);
5851 if (errno != EINVAL)
5852 return posix_error();
5853 if (ncpus > INT_MAX / 2) {
5854 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5855 "a large enough CPU set");
5856 return NULL;
5857 }
5858 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005859 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005860
5861 res = PySet_New(NULL);
5862 if (res == NULL)
5863 goto error;
5864 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5865 if (CPU_ISSET_S(cpu, setsize, mask)) {
5866 PyObject *cpu_num = PyLong_FromLong(cpu);
5867 --count;
5868 if (cpu_num == NULL)
5869 goto error;
5870 if (PySet_Add(res, cpu_num)) {
5871 Py_DECREF(cpu_num);
5872 goto error;
5873 }
5874 Py_DECREF(cpu_num);
5875 }
5876 }
5877 CPU_FREE(mask);
5878 return res;
5879
5880error:
5881 if (mask)
5882 CPU_FREE(mask);
5883 Py_XDECREF(res);
5884 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005885}
5886
Benjamin Peterson2740af82011-08-02 17:41:34 -05005887#endif /* HAVE_SCHED_SETAFFINITY */
5888
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005889#endif /* HAVE_SCHED_H */
5890
Larry Hastings2f936352014-08-05 14:04:04 +10005891
Neal Norwitzb59798b2003-03-21 01:43:31 +00005892/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005893/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5894#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005895#define DEV_PTY_FILE "/dev/ptc"
5896#define HAVE_DEV_PTMX
5897#else
5898#define DEV_PTY_FILE "/dev/ptmx"
5899#endif
5900
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005901#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005902#ifdef HAVE_PTY_H
5903#include <pty.h>
5904#else
5905#ifdef HAVE_LIBUTIL_H
5906#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005907#else
5908#ifdef HAVE_UTIL_H
5909#include <util.h>
5910#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005911#endif /* HAVE_LIBUTIL_H */
5912#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005913#ifdef HAVE_STROPTS_H
5914#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005915#endif
5916#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005917
Larry Hastings2f936352014-08-05 14:04:04 +10005918
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005919#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005920/*[clinic input]
5921os.openpty
5922
5923Open a pseudo-terminal.
5924
5925Return a tuple of (master_fd, slave_fd) containing open file descriptors
5926for both the master and slave ends.
5927[clinic start generated code]*/
5928
Larry Hastings2f936352014-08-05 14:04:04 +10005929static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005930os_openpty_impl(PyObject *module)
5931/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005932{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005933 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005934#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005936#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005937#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005938 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005939#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005940 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005941#endif
5942#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005943
Thomas Wouters70c21a12000-07-14 14:28:33 +00005944#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005945 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005946 goto posix_error;
5947
5948 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5949 goto error;
5950 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5951 goto error;
5952
Neal Norwitzb59798b2003-03-21 01:43:31 +00005953#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005954 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5955 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005956 goto posix_error;
5957 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5958 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005959
Victor Stinnerdaf45552013-08-28 00:53:59 +02005960 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005961 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005962 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005963
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005964#else
Victor Stinner000de532013-11-25 23:19:58 +01005965 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005966 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005967 goto posix_error;
5968
Victor Stinner8c62be82010-05-06 00:08:46 +00005969 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005970
Victor Stinner8c62be82010-05-06 00:08:46 +00005971 /* change permission of slave */
5972 if (grantpt(master_fd) < 0) {
5973 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005974 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005975 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005976
Victor Stinner8c62be82010-05-06 00:08:46 +00005977 /* unlock slave */
5978 if (unlockpt(master_fd) < 0) {
5979 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005980 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005981 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005982
Victor Stinner8c62be82010-05-06 00:08:46 +00005983 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005984
Victor Stinner8c62be82010-05-06 00:08:46 +00005985 slave_name = ptsname(master_fd); /* get name of slave */
5986 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005987 goto posix_error;
5988
5989 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005990 if (slave_fd == -1)
5991 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005992
5993 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5994 goto posix_error;
5995
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005996#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5998 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005999#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006000 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006001#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006002#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006003#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006004
Victor Stinner8c62be82010-05-06 00:08:46 +00006005 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006006
Victor Stinnerdaf45552013-08-28 00:53:59 +02006007posix_error:
6008 posix_error();
6009error:
6010 if (master_fd != -1)
6011 close(master_fd);
6012 if (slave_fd != -1)
6013 close(slave_fd);
6014 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006015}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006016#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006017
Larry Hastings2f936352014-08-05 14:04:04 +10006018
Fred Drake8cef4cf2000-06-28 16:40:38 +00006019#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006020/*[clinic input]
6021os.forkpty
6022
6023Fork a new process with a new pseudo-terminal as controlling tty.
6024
6025Returns a tuple of (pid, master_fd).
6026Like fork(), return pid of 0 to the child process,
6027and pid of child to the parent process.
6028To both, return fd of newly opened pseudo-terminal.
6029[clinic start generated code]*/
6030
Larry Hastings2f936352014-08-05 14:04:04 +10006031static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006032os_forkpty_impl(PyObject *module)
6033/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006034{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006035 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006037
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006038 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006039 pid = forkpty(&master_fd, NULL, NULL, NULL);
6040 if (pid == 0) {
6041 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006042 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006043 } else {
6044 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006045 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006046 }
6047 if (pid == -1)
6048 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006049 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006050}
Larry Hastings2f936352014-08-05 14:04:04 +10006051#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006052
Ross Lagerwall7807c352011-03-17 20:20:30 +02006053
Guido van Rossumad0ee831995-03-01 10:34:45 +00006054#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006055/*[clinic input]
6056os.getegid
6057
6058Return the current process's effective group id.
6059[clinic start generated code]*/
6060
Larry Hastings2f936352014-08-05 14:04:04 +10006061static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006062os_getegid_impl(PyObject *module)
6063/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006064{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006065 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006066}
Larry Hastings2f936352014-08-05 14:04:04 +10006067#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006068
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006069
Guido van Rossumad0ee831995-03-01 10:34:45 +00006070#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006071/*[clinic input]
6072os.geteuid
6073
6074Return the current process's effective user id.
6075[clinic start generated code]*/
6076
Larry Hastings2f936352014-08-05 14:04:04 +10006077static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006078os_geteuid_impl(PyObject *module)
6079/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006080{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006081 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006082}
Larry Hastings2f936352014-08-05 14:04:04 +10006083#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006084
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006085
Guido van Rossumad0ee831995-03-01 10:34:45 +00006086#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006087/*[clinic input]
6088os.getgid
6089
6090Return the current process's group id.
6091[clinic start generated code]*/
6092
Larry Hastings2f936352014-08-05 14:04:04 +10006093static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006094os_getgid_impl(PyObject *module)
6095/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006096{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006097 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006098}
Larry Hastings2f936352014-08-05 14:04:04 +10006099#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006100
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006101
Berker Peksag39404992016-09-15 20:45:16 +03006102#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006103/*[clinic input]
6104os.getpid
6105
6106Return the current process id.
6107[clinic start generated code]*/
6108
Larry Hastings2f936352014-08-05 14:04:04 +10006109static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006110os_getpid_impl(PyObject *module)
6111/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006112{
Victor Stinner8c62be82010-05-06 00:08:46 +00006113 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006114}
Berker Peksag39404992016-09-15 20:45:16 +03006115#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006116
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006117#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006118
6119/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006120PyDoc_STRVAR(posix_getgrouplist__doc__,
6121"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6122Returns a list of groups to which a user belongs.\n\n\
6123 user: username to lookup\n\
6124 group: base group id of the user");
6125
6126static PyObject *
6127posix_getgrouplist(PyObject *self, PyObject *args)
6128{
6129#ifdef NGROUPS_MAX
6130#define MAX_GROUPS NGROUPS_MAX
6131#else
6132 /* defined to be 16 on Solaris7, so this should be a small number */
6133#define MAX_GROUPS 64
6134#endif
6135
6136 const char *user;
6137 int i, ngroups;
6138 PyObject *list;
6139#ifdef __APPLE__
6140 int *groups, basegid;
6141#else
6142 gid_t *groups, basegid;
6143#endif
6144 ngroups = MAX_GROUPS;
6145
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006146#ifdef __APPLE__
6147 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006148 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006149#else
6150 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6151 _Py_Gid_Converter, &basegid))
6152 return NULL;
6153#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006154
6155#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006156 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006157#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006158 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006159#endif
6160 if (groups == NULL)
6161 return PyErr_NoMemory();
6162
6163 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6164 PyMem_Del(groups);
6165 return posix_error();
6166 }
6167
6168 list = PyList_New(ngroups);
6169 if (list == NULL) {
6170 PyMem_Del(groups);
6171 return NULL;
6172 }
6173
6174 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006175#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006176 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006177#else
6178 PyObject *o = _PyLong_FromGid(groups[i]);
6179#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006180 if (o == NULL) {
6181 Py_DECREF(list);
6182 PyMem_Del(groups);
6183 return NULL;
6184 }
6185 PyList_SET_ITEM(list, i, o);
6186 }
6187
6188 PyMem_Del(groups);
6189
6190 return list;
6191}
Larry Hastings2f936352014-08-05 14:04:04 +10006192#endif /* HAVE_GETGROUPLIST */
6193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006194
Fred Drakec9680921999-12-13 16:37:25 +00006195#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006196/*[clinic input]
6197os.getgroups
6198
6199Return list of supplemental group IDs for the process.
6200[clinic start generated code]*/
6201
Larry Hastings2f936352014-08-05 14:04:04 +10006202static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006203os_getgroups_impl(PyObject *module)
6204/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006205{
6206 PyObject *result = NULL;
6207
Fred Drakec9680921999-12-13 16:37:25 +00006208#ifdef NGROUPS_MAX
6209#define MAX_GROUPS NGROUPS_MAX
6210#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006211 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006212#define MAX_GROUPS 64
6213#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006214 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006215
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006216 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006217 * This is a helper variable to store the intermediate result when
6218 * that happens.
6219 *
6220 * To keep the code readable the OSX behaviour is unconditional,
6221 * according to the POSIX spec this should be safe on all unix-y
6222 * systems.
6223 */
6224 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006225 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006226
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006227#ifdef __APPLE__
6228 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6229 * there are more groups than can fit in grouplist. Therefore, on OS X
6230 * always first call getgroups with length 0 to get the actual number
6231 * of groups.
6232 */
6233 n = getgroups(0, NULL);
6234 if (n < 0) {
6235 return posix_error();
6236 } else if (n <= MAX_GROUPS) {
6237 /* groups will fit in existing array */
6238 alt_grouplist = grouplist;
6239 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006240 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006241 if (alt_grouplist == NULL) {
6242 errno = EINVAL;
6243 return posix_error();
6244 }
6245 }
6246
6247 n = getgroups(n, alt_grouplist);
6248 if (n == -1) {
6249 if (alt_grouplist != grouplist) {
6250 PyMem_Free(alt_grouplist);
6251 }
6252 return posix_error();
6253 }
6254#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006255 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006256 if (n < 0) {
6257 if (errno == EINVAL) {
6258 n = getgroups(0, NULL);
6259 if (n == -1) {
6260 return posix_error();
6261 }
6262 if (n == 0) {
6263 /* Avoid malloc(0) */
6264 alt_grouplist = grouplist;
6265 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006266 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006267 if (alt_grouplist == NULL) {
6268 errno = EINVAL;
6269 return posix_error();
6270 }
6271 n = getgroups(n, alt_grouplist);
6272 if (n == -1) {
6273 PyMem_Free(alt_grouplist);
6274 return posix_error();
6275 }
6276 }
6277 } else {
6278 return posix_error();
6279 }
6280 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006281#endif
6282
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006283 result = PyList_New(n);
6284 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006285 int i;
6286 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006287 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006289 Py_DECREF(result);
6290 result = NULL;
6291 break;
Fred Drakec9680921999-12-13 16:37:25 +00006292 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006294 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006295 }
6296
6297 if (alt_grouplist != grouplist) {
6298 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006299 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006300
Fred Drakec9680921999-12-13 16:37:25 +00006301 return result;
6302}
Larry Hastings2f936352014-08-05 14:04:04 +10006303#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006304
Antoine Pitroub7572f02009-12-02 20:46:48 +00006305#ifdef HAVE_INITGROUPS
6306PyDoc_STRVAR(posix_initgroups__doc__,
6307"initgroups(username, gid) -> None\n\n\
6308Call the system initgroups() to initialize the group access list with all of\n\
6309the groups of which the specified username is a member, plus the specified\n\
6310group id.");
6311
Larry Hastings2f936352014-08-05 14:04:04 +10006312/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006313static PyObject *
6314posix_initgroups(PyObject *self, PyObject *args)
6315{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006316 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006317 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006318 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006319#ifdef __APPLE__
6320 int gid;
6321#else
6322 gid_t gid;
6323#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006324
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006325#ifdef __APPLE__
6326 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6327 PyUnicode_FSConverter, &oname,
6328 &gid))
6329#else
6330 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6331 PyUnicode_FSConverter, &oname,
6332 _Py_Gid_Converter, &gid))
6333#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006334 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006335 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006336
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006337 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006338 Py_DECREF(oname);
6339 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006341
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006342 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006343}
Larry Hastings2f936352014-08-05 14:04:04 +10006344#endif /* HAVE_INITGROUPS */
6345
Antoine Pitroub7572f02009-12-02 20:46:48 +00006346
Martin v. Löwis606edc12002-06-13 21:09:11 +00006347#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006348/*[clinic input]
6349os.getpgid
6350
6351 pid: pid_t
6352
6353Call the system call getpgid(), and return the result.
6354[clinic start generated code]*/
6355
Larry Hastings2f936352014-08-05 14:04:04 +10006356static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006357os_getpgid_impl(PyObject *module, pid_t pid)
6358/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006359{
6360 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006361 if (pgid < 0)
6362 return posix_error();
6363 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006364}
6365#endif /* HAVE_GETPGID */
6366
6367
Guido van Rossumb6775db1994-08-01 11:34:53 +00006368#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006369/*[clinic input]
6370os.getpgrp
6371
6372Return the current process group id.
6373[clinic start generated code]*/
6374
Larry Hastings2f936352014-08-05 14:04:04 +10006375static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006376os_getpgrp_impl(PyObject *module)
6377/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006378{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006379#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006380 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006381#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006382 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006383#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006384}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006385#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006387
Guido van Rossumb6775db1994-08-01 11:34:53 +00006388#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006389/*[clinic input]
6390os.setpgrp
6391
6392Make the current process the leader of its process group.
6393[clinic start generated code]*/
6394
Larry Hastings2f936352014-08-05 14:04:04 +10006395static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006396os_setpgrp_impl(PyObject *module)
6397/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006398{
Guido van Rossum64933891994-10-20 21:56:42 +00006399#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006401#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006402 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006403#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006404 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006405 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006406}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006407#endif /* HAVE_SETPGRP */
6408
Guido van Rossumad0ee831995-03-01 10:34:45 +00006409#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006410
6411#ifdef MS_WINDOWS
6412#include <tlhelp32.h>
6413
6414static PyObject*
6415win32_getppid()
6416{
6417 HANDLE snapshot;
6418 pid_t mypid;
6419 PyObject* result = NULL;
6420 BOOL have_record;
6421 PROCESSENTRY32 pe;
6422
6423 mypid = getpid(); /* This function never fails */
6424
6425 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6426 if (snapshot == INVALID_HANDLE_VALUE)
6427 return PyErr_SetFromWindowsErr(GetLastError());
6428
6429 pe.dwSize = sizeof(pe);
6430 have_record = Process32First(snapshot, &pe);
6431 while (have_record) {
6432 if (mypid == (pid_t)pe.th32ProcessID) {
6433 /* We could cache the ulong value in a static variable. */
6434 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6435 break;
6436 }
6437
6438 have_record = Process32Next(snapshot, &pe);
6439 }
6440
6441 /* If our loop exits and our pid was not found (result will be NULL)
6442 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6443 * error anyway, so let's raise it. */
6444 if (!result)
6445 result = PyErr_SetFromWindowsErr(GetLastError());
6446
6447 CloseHandle(snapshot);
6448
6449 return result;
6450}
6451#endif /*MS_WINDOWS*/
6452
Larry Hastings2f936352014-08-05 14:04:04 +10006453
6454/*[clinic input]
6455os.getppid
6456
6457Return the parent's process id.
6458
6459If the parent process has already exited, Windows machines will still
6460return its id; others systems will return the id of the 'init' process (1).
6461[clinic start generated code]*/
6462
Larry Hastings2f936352014-08-05 14:04:04 +10006463static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006464os_getppid_impl(PyObject *module)
6465/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006466{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006467#ifdef MS_WINDOWS
6468 return win32_getppid();
6469#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006470 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006471#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006472}
6473#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006474
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006475
Fred Drake12c6e2d1999-12-14 21:25:03 +00006476#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006477/*[clinic input]
6478os.getlogin
6479
6480Return the actual login name.
6481[clinic start generated code]*/
6482
Larry Hastings2f936352014-08-05 14:04:04 +10006483static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006484os_getlogin_impl(PyObject *module)
6485/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006486{
Victor Stinner8c62be82010-05-06 00:08:46 +00006487 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006488#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006489 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006490 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006491
6492 if (GetUserNameW(user_name, &num_chars)) {
6493 /* num_chars is the number of unicode chars plus null terminator */
6494 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006495 }
6496 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006497 result = PyErr_SetFromWindowsErr(GetLastError());
6498#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006499 char *name;
6500 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006501
Victor Stinner8c62be82010-05-06 00:08:46 +00006502 errno = 0;
6503 name = getlogin();
6504 if (name == NULL) {
6505 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006506 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006507 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006508 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006509 }
6510 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006511 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006512 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006513#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006514 return result;
6515}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006516#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006517
Larry Hastings2f936352014-08-05 14:04:04 +10006518
Guido van Rossumad0ee831995-03-01 10:34:45 +00006519#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006520/*[clinic input]
6521os.getuid
6522
6523Return the current process's user id.
6524[clinic start generated code]*/
6525
Larry Hastings2f936352014-08-05 14:04:04 +10006526static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006527os_getuid_impl(PyObject *module)
6528/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006529{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006530 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006531}
Larry Hastings2f936352014-08-05 14:04:04 +10006532#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006533
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006534
Brian Curtineb24d742010-04-12 17:16:38 +00006535#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006536#define HAVE_KILL
6537#endif /* MS_WINDOWS */
6538
6539#ifdef HAVE_KILL
6540/*[clinic input]
6541os.kill
6542
6543 pid: pid_t
6544 signal: Py_ssize_t
6545 /
6546
6547Kill a process with a signal.
6548[clinic start generated code]*/
6549
Larry Hastings2f936352014-08-05 14:04:04 +10006550static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006551os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6552/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006553#ifndef MS_WINDOWS
6554{
6555 if (kill(pid, (int)signal) == -1)
6556 return posix_error();
6557 Py_RETURN_NONE;
6558}
6559#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006560{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006561 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006562 DWORD sig = (DWORD)signal;
6563 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006564 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006565
Victor Stinner8c62be82010-05-06 00:08:46 +00006566 /* Console processes which share a common console can be sent CTRL+C or
6567 CTRL+BREAK events, provided they handle said events. */
6568 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006569 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 err = GetLastError();
6571 PyErr_SetFromWindowsErr(err);
6572 }
6573 else
6574 Py_RETURN_NONE;
6575 }
Brian Curtineb24d742010-04-12 17:16:38 +00006576
Victor Stinner8c62be82010-05-06 00:08:46 +00006577 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6578 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006579 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006580 if (handle == NULL) {
6581 err = GetLastError();
6582 return PyErr_SetFromWindowsErr(err);
6583 }
Brian Curtineb24d742010-04-12 17:16:38 +00006584
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 if (TerminateProcess(handle, sig) == 0) {
6586 err = GetLastError();
6587 result = PyErr_SetFromWindowsErr(err);
6588 } else {
6589 Py_INCREF(Py_None);
6590 result = Py_None;
6591 }
Brian Curtineb24d742010-04-12 17:16:38 +00006592
Victor Stinner8c62be82010-05-06 00:08:46 +00006593 CloseHandle(handle);
6594 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006595}
Larry Hastings2f936352014-08-05 14:04:04 +10006596#endif /* !MS_WINDOWS */
6597#endif /* HAVE_KILL */
6598
6599
6600#ifdef HAVE_KILLPG
6601/*[clinic input]
6602os.killpg
6603
6604 pgid: pid_t
6605 signal: int
6606 /
6607
6608Kill a process group with a signal.
6609[clinic start generated code]*/
6610
Larry Hastings2f936352014-08-05 14:04:04 +10006611static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006612os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6613/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006614{
6615 /* XXX some man pages make the `pgid` parameter an int, others
6616 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6617 take the same type. Moreover, pid_t is always at least as wide as
6618 int (else compilation of this module fails), which is safe. */
6619 if (killpg(pgid, signal) == -1)
6620 return posix_error();
6621 Py_RETURN_NONE;
6622}
6623#endif /* HAVE_KILLPG */
6624
Brian Curtineb24d742010-04-12 17:16:38 +00006625
Guido van Rossumc0125471996-06-28 18:55:32 +00006626#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006627#ifdef HAVE_SYS_LOCK_H
6628#include <sys/lock.h>
6629#endif
6630
Larry Hastings2f936352014-08-05 14:04:04 +10006631/*[clinic input]
6632os.plock
6633 op: int
6634 /
6635
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006636Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006637[clinic start generated code]*/
6638
Larry Hastings2f936352014-08-05 14:04:04 +10006639static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006640os_plock_impl(PyObject *module, int op)
6641/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006642{
Victor Stinner8c62be82010-05-06 00:08:46 +00006643 if (plock(op) == -1)
6644 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006645 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006646}
Larry Hastings2f936352014-08-05 14:04:04 +10006647#endif /* HAVE_PLOCK */
6648
Guido van Rossumc0125471996-06-28 18:55:32 +00006649
Guido van Rossumb6775db1994-08-01 11:34:53 +00006650#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006651/*[clinic input]
6652os.setuid
6653
6654 uid: uid_t
6655 /
6656
6657Set the current process's user id.
6658[clinic start generated code]*/
6659
Larry Hastings2f936352014-08-05 14:04:04 +10006660static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006661os_setuid_impl(PyObject *module, uid_t uid)
6662/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006663{
Victor Stinner8c62be82010-05-06 00:08:46 +00006664 if (setuid(uid) < 0)
6665 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006666 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006667}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006668#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006669
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006670
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006671#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006672/*[clinic input]
6673os.seteuid
6674
6675 euid: uid_t
6676 /
6677
6678Set the current process's effective user id.
6679[clinic start generated code]*/
6680
Larry Hastings2f936352014-08-05 14:04:04 +10006681static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006682os_seteuid_impl(PyObject *module, uid_t euid)
6683/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006684{
6685 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006687 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006688}
6689#endif /* HAVE_SETEUID */
6690
Larry Hastings2f936352014-08-05 14:04:04 +10006691
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006692#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006693/*[clinic input]
6694os.setegid
6695
6696 egid: gid_t
6697 /
6698
6699Set the current process's effective group id.
6700[clinic start generated code]*/
6701
Larry Hastings2f936352014-08-05 14:04:04 +10006702static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006703os_setegid_impl(PyObject *module, gid_t egid)
6704/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006705{
6706 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006707 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006708 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006709}
6710#endif /* HAVE_SETEGID */
6711
Larry Hastings2f936352014-08-05 14:04:04 +10006712
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006713#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006714/*[clinic input]
6715os.setreuid
6716
6717 ruid: uid_t
6718 euid: uid_t
6719 /
6720
6721Set the current process's real and effective user ids.
6722[clinic start generated code]*/
6723
Larry Hastings2f936352014-08-05 14:04:04 +10006724static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006725os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6726/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006727{
Victor Stinner8c62be82010-05-06 00:08:46 +00006728 if (setreuid(ruid, euid) < 0) {
6729 return posix_error();
6730 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006731 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006732 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006733}
6734#endif /* HAVE_SETREUID */
6735
Larry Hastings2f936352014-08-05 14:04:04 +10006736
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006737#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006738/*[clinic input]
6739os.setregid
6740
6741 rgid: gid_t
6742 egid: gid_t
6743 /
6744
6745Set the current process's real and effective group ids.
6746[clinic start generated code]*/
6747
Larry Hastings2f936352014-08-05 14:04:04 +10006748static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006749os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6750/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006751{
6752 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006753 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006754 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006755}
6756#endif /* HAVE_SETREGID */
6757
Larry Hastings2f936352014-08-05 14:04:04 +10006758
Guido van Rossumb6775db1994-08-01 11:34:53 +00006759#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006760/*[clinic input]
6761os.setgid
6762 gid: gid_t
6763 /
6764
6765Set the current process's group id.
6766[clinic start generated code]*/
6767
Larry Hastings2f936352014-08-05 14:04:04 +10006768static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006769os_setgid_impl(PyObject *module, gid_t gid)
6770/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006771{
Victor Stinner8c62be82010-05-06 00:08:46 +00006772 if (setgid(gid) < 0)
6773 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006774 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006775}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006776#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006777
Larry Hastings2f936352014-08-05 14:04:04 +10006778
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006779#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006780/*[clinic input]
6781os.setgroups
6782
6783 groups: object
6784 /
6785
6786Set the groups of the current process to list.
6787[clinic start generated code]*/
6788
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006789static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006790os_setgroups(PyObject *module, PyObject *groups)
6791/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006792{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006793 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006795
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 if (!PySequence_Check(groups)) {
6797 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6798 return NULL;
6799 }
6800 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006801 if (len < 0) {
6802 return NULL;
6803 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 if (len > MAX_GROUPS) {
6805 PyErr_SetString(PyExc_ValueError, "too many groups");
6806 return NULL;
6807 }
6808 for(i = 0; i < len; i++) {
6809 PyObject *elem;
6810 elem = PySequence_GetItem(groups, i);
6811 if (!elem)
6812 return NULL;
6813 if (!PyLong_Check(elem)) {
6814 PyErr_SetString(PyExc_TypeError,
6815 "groups must be integers");
6816 Py_DECREF(elem);
6817 return NULL;
6818 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006819 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 Py_DECREF(elem);
6821 return NULL;
6822 }
6823 }
6824 Py_DECREF(elem);
6825 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006826
Victor Stinner8c62be82010-05-06 00:08:46 +00006827 if (setgroups(len, grouplist) < 0)
6828 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006829 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006830}
6831#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006832
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006833#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6834static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006835wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006836{
Victor Stinner8c62be82010-05-06 00:08:46 +00006837 PyObject *result;
6838 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006839 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006840
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 if (pid == -1)
6842 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006843
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 if (struct_rusage == NULL) {
6845 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6846 if (m == NULL)
6847 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006848 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006849 Py_DECREF(m);
6850 if (struct_rusage == NULL)
6851 return NULL;
6852 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006853
Victor Stinner8c62be82010-05-06 00:08:46 +00006854 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6855 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6856 if (!result)
6857 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006858
6859#ifndef doubletime
6860#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6861#endif
6862
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006864 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006866 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006867#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6869 SET_INT(result, 2, ru->ru_maxrss);
6870 SET_INT(result, 3, ru->ru_ixrss);
6871 SET_INT(result, 4, ru->ru_idrss);
6872 SET_INT(result, 5, ru->ru_isrss);
6873 SET_INT(result, 6, ru->ru_minflt);
6874 SET_INT(result, 7, ru->ru_majflt);
6875 SET_INT(result, 8, ru->ru_nswap);
6876 SET_INT(result, 9, ru->ru_inblock);
6877 SET_INT(result, 10, ru->ru_oublock);
6878 SET_INT(result, 11, ru->ru_msgsnd);
6879 SET_INT(result, 12, ru->ru_msgrcv);
6880 SET_INT(result, 13, ru->ru_nsignals);
6881 SET_INT(result, 14, ru->ru_nvcsw);
6882 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006883#undef SET_INT
6884
Victor Stinner8c62be82010-05-06 00:08:46 +00006885 if (PyErr_Occurred()) {
6886 Py_DECREF(result);
6887 return NULL;
6888 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006889
Victor Stinner8c62be82010-05-06 00:08:46 +00006890 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006891}
6892#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6893
Larry Hastings2f936352014-08-05 14:04:04 +10006894
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006895#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006896/*[clinic input]
6897os.wait3
6898
6899 options: int
6900Wait for completion of a child process.
6901
6902Returns a tuple of information about the child process:
6903 (pid, status, rusage)
6904[clinic start generated code]*/
6905
Larry Hastings2f936352014-08-05 14:04:04 +10006906static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006907os_wait3_impl(PyObject *module, int options)
6908/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006909{
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006912 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 WAIT_TYPE status;
6914 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006915
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006916 do {
6917 Py_BEGIN_ALLOW_THREADS
6918 pid = wait3(&status, options, &ru);
6919 Py_END_ALLOW_THREADS
6920 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6921 if (pid < 0)
6922 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006923
Victor Stinner4195b5c2012-02-08 23:03:19 +01006924 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006925}
6926#endif /* HAVE_WAIT3 */
6927
Larry Hastings2f936352014-08-05 14:04:04 +10006928
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006929#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006930/*[clinic input]
6931
6932os.wait4
6933
6934 pid: pid_t
6935 options: int
6936
6937Wait for completion of a specific child process.
6938
6939Returns a tuple of information about the child process:
6940 (pid, status, rusage)
6941[clinic start generated code]*/
6942
Larry Hastings2f936352014-08-05 14:04:04 +10006943static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006944os_wait4_impl(PyObject *module, pid_t pid, int options)
6945/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006946{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006947 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006948 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006949 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006950 WAIT_TYPE status;
6951 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006952
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006953 do {
6954 Py_BEGIN_ALLOW_THREADS
6955 res = wait4(pid, &status, options, &ru);
6956 Py_END_ALLOW_THREADS
6957 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6958 if (res < 0)
6959 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006960
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006961 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006962}
6963#endif /* HAVE_WAIT4 */
6964
Larry Hastings2f936352014-08-05 14:04:04 +10006965
Ross Lagerwall7807c352011-03-17 20:20:30 +02006966#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006967/*[clinic input]
6968os.waitid
6969
6970 idtype: idtype_t
6971 Must be one of be P_PID, P_PGID or P_ALL.
6972 id: id_t
6973 The id to wait on.
6974 options: int
6975 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6976 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6977 /
6978
6979Returns the result of waiting for a process or processes.
6980
6981Returns either waitid_result or None if WNOHANG is specified and there are
6982no children in a waitable state.
6983[clinic start generated code]*/
6984
Larry Hastings2f936352014-08-05 14:04:04 +10006985static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006986os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6987/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006988{
6989 PyObject *result;
6990 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006991 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006992 siginfo_t si;
6993 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006994
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006995 do {
6996 Py_BEGIN_ALLOW_THREADS
6997 res = waitid(idtype, id, &si, options);
6998 Py_END_ALLOW_THREADS
6999 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7000 if (res < 0)
7001 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007002
7003 if (si.si_pid == 0)
7004 Py_RETURN_NONE;
7005
7006 result = PyStructSequence_New(&WaitidResultType);
7007 if (!result)
7008 return NULL;
7009
7010 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007011 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007012 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7013 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7014 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7015 if (PyErr_Occurred()) {
7016 Py_DECREF(result);
7017 return NULL;
7018 }
7019
7020 return result;
7021}
Larry Hastings2f936352014-08-05 14:04:04 +10007022#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007023
Larry Hastings2f936352014-08-05 14:04:04 +10007024
7025#if defined(HAVE_WAITPID)
7026/*[clinic input]
7027os.waitpid
7028 pid: pid_t
7029 options: int
7030 /
7031
7032Wait for completion of a given child process.
7033
7034Returns a tuple of information regarding the child process:
7035 (pid, status)
7036
7037The options argument is ignored on Windows.
7038[clinic start generated code]*/
7039
Larry Hastings2f936352014-08-05 14:04:04 +10007040static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007041os_waitpid_impl(PyObject *module, pid_t pid, int options)
7042/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007043{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007044 pid_t res;
7045 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 WAIT_TYPE status;
7047 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007048
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007049 do {
7050 Py_BEGIN_ALLOW_THREADS
7051 res = waitpid(pid, &status, options);
7052 Py_END_ALLOW_THREADS
7053 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7054 if (res < 0)
7055 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007056
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007057 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007058}
Tim Petersab034fa2002-02-01 11:27:43 +00007059#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007060/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007061/*[clinic input]
7062os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007063 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007064 options: int
7065 /
7066
7067Wait for completion of a given process.
7068
7069Returns a tuple of information regarding the process:
7070 (pid, status << 8)
7071
7072The options argument is ignored on Windows.
7073[clinic start generated code]*/
7074
Larry Hastings2f936352014-08-05 14:04:04 +10007075static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007076os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007077/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007078{
7079 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007080 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007081 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007082
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007083 do {
7084 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007085 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007086 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007087 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007088 Py_END_ALLOW_THREADS
7089 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007090 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007091 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007092
Victor Stinner8c62be82010-05-06 00:08:46 +00007093 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007094 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007095}
Larry Hastings2f936352014-08-05 14:04:04 +10007096#endif
7097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007098
Guido van Rossumad0ee831995-03-01 10:34:45 +00007099#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007100/*[clinic input]
7101os.wait
7102
7103Wait for completion of a child process.
7104
7105Returns a tuple of information about the child process:
7106 (pid, status)
7107[clinic start generated code]*/
7108
Larry Hastings2f936352014-08-05 14:04:04 +10007109static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007110os_wait_impl(PyObject *module)
7111/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007112{
Victor Stinner8c62be82010-05-06 00:08:46 +00007113 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007114 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007115 WAIT_TYPE status;
7116 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007117
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007118 do {
7119 Py_BEGIN_ALLOW_THREADS
7120 pid = wait(&status);
7121 Py_END_ALLOW_THREADS
7122 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7123 if (pid < 0)
7124 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007125
Victor Stinner8c62be82010-05-06 00:08:46 +00007126 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007127}
Larry Hastings2f936352014-08-05 14:04:04 +10007128#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007129
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007130
Larry Hastings9cf065c2012-06-22 16:30:09 -07007131#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7132PyDoc_STRVAR(readlink__doc__,
7133"readlink(path, *, dir_fd=None) -> path\n\n\
7134Return a string representing the path to which the symbolic link points.\n\
7135\n\
7136If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7137 and path should be relative; path will then be relative to that directory.\n\
7138dir_fd may not be implemented on your platform.\n\
7139 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007140#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007141
Guido van Rossumb6775db1994-08-01 11:34:53 +00007142#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007143
Larry Hastings2f936352014-08-05 14:04:04 +10007144/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007145static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007146posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007147{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007148 path_t path;
7149 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007150 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007151 ssize_t length;
7152 PyObject *return_value = NULL;
7153 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007154
Larry Hastings9cf065c2012-06-22 16:30:09 -07007155 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007156 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007157 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7158 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007159 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007160 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007161
Victor Stinner8c62be82010-05-06 00:08:46 +00007162 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007163#ifdef HAVE_READLINKAT
7164 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007165 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007166 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007167#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007168 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007169 Py_END_ALLOW_THREADS
7170
7171 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007172 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007173 goto exit;
7174 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007175 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007176
7177 if (PyUnicode_Check(path.object))
7178 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7179 else
7180 return_value = PyBytes_FromStringAndSize(buffer, length);
7181exit:
7182 path_cleanup(&path);
7183 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007184}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007185
Guido van Rossumb6775db1994-08-01 11:34:53 +00007186#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007187
Larry Hastings2f936352014-08-05 14:04:04 +10007188#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7189
7190static PyObject *
7191win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7192{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007193 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007194 DWORD n_bytes_returned;
7195 DWORD io_result;
7196 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007197 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007198 HANDLE reparse_point_handle;
7199
Martin Panter70214ad2016-08-04 02:38:59 +00007200 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7201 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007202 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007203
7204 static char *keywords[] = {"path", "dir_fd", NULL};
7205
7206 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7207 &po,
7208 dir_fd_unavailable, &dir_fd
7209 ))
7210 return NULL;
7211
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007212 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007213 if (path == NULL)
7214 return NULL;
7215
7216 /* First get a handle to the reparse point */
7217 Py_BEGIN_ALLOW_THREADS
7218 reparse_point_handle = CreateFileW(
7219 path,
7220 0,
7221 0,
7222 0,
7223 OPEN_EXISTING,
7224 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7225 0);
7226 Py_END_ALLOW_THREADS
7227
7228 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7229 return win32_error_object("readlink", po);
7230
7231 Py_BEGIN_ALLOW_THREADS
7232 /* New call DeviceIoControl to read the reparse point */
7233 io_result = DeviceIoControl(
7234 reparse_point_handle,
7235 FSCTL_GET_REPARSE_POINT,
7236 0, 0, /* in buffer */
7237 target_buffer, sizeof(target_buffer),
7238 &n_bytes_returned,
7239 0 /* we're not using OVERLAPPED_IO */
7240 );
7241 CloseHandle(reparse_point_handle);
7242 Py_END_ALLOW_THREADS
7243
7244 if (io_result==0)
7245 return win32_error_object("readlink", po);
7246
7247 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7248 {
7249 PyErr_SetString(PyExc_ValueError,
7250 "not a symbolic link");
7251 return NULL;
7252 }
7253 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7254 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7255
7256 result = PyUnicode_FromWideChar(print_name,
7257 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7258 return result;
7259}
7260
7261#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7262
7263
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007264
Larry Hastings9cf065c2012-06-22 16:30:09 -07007265#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007266
7267#if defined(MS_WINDOWS)
7268
7269/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007270static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007271
Larry Hastings9cf065c2012-06-22 16:30:09 -07007272static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007273check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007274{
7275 HINSTANCE hKernel32;
7276 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007277 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007278 return 1;
7279 hKernel32 = GetModuleHandleW(L"KERNEL32");
7280 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7281 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007282 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007283}
7284
Victor Stinner31b3b922013-06-05 01:49:17 +02007285/* Remove the last portion of the path */
7286static void
7287_dirnameW(WCHAR *path)
7288{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007289 WCHAR *ptr;
7290
7291 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007292 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007293 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007294 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007295 }
7296 *ptr = 0;
7297}
7298
Victor Stinner31b3b922013-06-05 01:49:17 +02007299/* Is this path absolute? */
7300static int
7301_is_absW(const WCHAR *path)
7302{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007303 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7304
7305}
7306
Victor Stinner31b3b922013-06-05 01:49:17 +02007307/* join root and rest with a backslash */
7308static void
7309_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7310{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007311 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007312
Victor Stinner31b3b922013-06-05 01:49:17 +02007313 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007314 wcscpy(dest_path, rest);
7315 return;
7316 }
7317
7318 root_len = wcslen(root);
7319
7320 wcscpy(dest_path, root);
7321 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007322 dest_path[root_len] = L'\\';
7323 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007324 }
7325 wcscpy(dest_path+root_len, rest);
7326}
7327
Victor Stinner31b3b922013-06-05 01:49:17 +02007328/* Return True if the path at src relative to dest is a directory */
7329static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007330_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007331{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007332 WIN32_FILE_ATTRIBUTE_DATA src_info;
7333 WCHAR dest_parent[MAX_PATH];
7334 WCHAR src_resolved[MAX_PATH] = L"";
7335
7336 /* dest_parent = os.path.dirname(dest) */
7337 wcscpy(dest_parent, dest);
7338 _dirnameW(dest_parent);
7339 /* src_resolved = os.path.join(dest_parent, src) */
7340 _joinW(src_resolved, dest_parent, src);
7341 return (
7342 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7343 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7344 );
7345}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007346#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007347
Larry Hastings2f936352014-08-05 14:04:04 +10007348
7349/*[clinic input]
7350os.symlink
7351 src: path_t
7352 dst: path_t
7353 target_is_directory: bool = False
7354 *
7355 dir_fd: dir_fd(requires='symlinkat')=None
7356
7357# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7358
7359Create a symbolic link pointing to src named dst.
7360
7361target_is_directory is required on Windows if the target is to be
7362 interpreted as a directory. (On Windows, symlink requires
7363 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7364 target_is_directory is ignored on non-Windows platforms.
7365
7366If dir_fd is not None, it should be a file descriptor open to a directory,
7367 and path should be relative; path will then be relative to that directory.
7368dir_fd may not be implemented on your platform.
7369 If it is unavailable, using it will raise a NotImplementedError.
7370
7371[clinic start generated code]*/
7372
Larry Hastings2f936352014-08-05 14:04:04 +10007373static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007374os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007375 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007376/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007377{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007378#ifdef MS_WINDOWS
7379 DWORD result;
7380#else
7381 int result;
7382#endif
7383
Larry Hastings9cf065c2012-06-22 16:30:09 -07007384#ifdef MS_WINDOWS
7385 if (!check_CreateSymbolicLink()) {
7386 PyErr_SetString(PyExc_NotImplementedError,
7387 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007388 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007389 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007390 if (!win32_can_symlink) {
7391 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007392 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007393 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007394#endif
7395
Larry Hastings2f936352014-08-05 14:04:04 +10007396 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007397 PyErr_SetString(PyExc_ValueError,
7398 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007399 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007400 }
7401
7402#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007403
Larry Hastings9cf065c2012-06-22 16:30:09 -07007404 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007405 /* if src is a directory, ensure target_is_directory==1 */
7406 target_is_directory |= _check_dirW(src->wide, dst->wide);
7407 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7408 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007409 Py_END_ALLOW_THREADS
7410
Larry Hastings2f936352014-08-05 14:04:04 +10007411 if (!result)
7412 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007413
7414#else
7415
7416 Py_BEGIN_ALLOW_THREADS
7417#if HAVE_SYMLINKAT
7418 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007419 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007420 else
7421#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007422 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007423 Py_END_ALLOW_THREADS
7424
Larry Hastings2f936352014-08-05 14:04:04 +10007425 if (result)
7426 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007427#endif
7428
Larry Hastings2f936352014-08-05 14:04:04 +10007429 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007430}
7431#endif /* HAVE_SYMLINK */
7432
Larry Hastings9cf065c2012-06-22 16:30:09 -07007433
Brian Curtind40e6f72010-07-08 21:39:08 +00007434
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007435
Larry Hastings605a62d2012-06-24 04:33:36 -07007436static PyStructSequence_Field times_result_fields[] = {
7437 {"user", "user time"},
7438 {"system", "system time"},
7439 {"children_user", "user time of children"},
7440 {"children_system", "system time of children"},
7441 {"elapsed", "elapsed time since an arbitrary point in the past"},
7442 {NULL}
7443};
7444
7445PyDoc_STRVAR(times_result__doc__,
7446"times_result: Result from os.times().\n\n\
7447This object may be accessed either as a tuple of\n\
7448 (user, system, children_user, children_system, elapsed),\n\
7449or via the attributes user, system, children_user, children_system,\n\
7450and elapsed.\n\
7451\n\
7452See os.times for more information.");
7453
7454static PyStructSequence_Desc times_result_desc = {
7455 "times_result", /* name */
7456 times_result__doc__, /* doc */
7457 times_result_fields,
7458 5
7459};
7460
7461static PyTypeObject TimesResultType;
7462
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007463#ifdef MS_WINDOWS
7464#define HAVE_TIMES /* mandatory, for the method table */
7465#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007466
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007467#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007468
7469static PyObject *
7470build_times_result(double user, double system,
7471 double children_user, double children_system,
7472 double elapsed)
7473{
7474 PyObject *value = PyStructSequence_New(&TimesResultType);
7475 if (value == NULL)
7476 return NULL;
7477
7478#define SET(i, field) \
7479 { \
7480 PyObject *o = PyFloat_FromDouble(field); \
7481 if (!o) { \
7482 Py_DECREF(value); \
7483 return NULL; \
7484 } \
7485 PyStructSequence_SET_ITEM(value, i, o); \
7486 } \
7487
7488 SET(0, user);
7489 SET(1, system);
7490 SET(2, children_user);
7491 SET(3, children_system);
7492 SET(4, elapsed);
7493
7494#undef SET
7495
7496 return value;
7497}
7498
Larry Hastings605a62d2012-06-24 04:33:36 -07007499
Larry Hastings2f936352014-08-05 14:04:04 +10007500#ifndef MS_WINDOWS
7501#define NEED_TICKS_PER_SECOND
7502static long ticks_per_second = -1;
7503#endif /* MS_WINDOWS */
7504
7505/*[clinic input]
7506os.times
7507
7508Return a collection containing process timing information.
7509
7510The object returned behaves like a named tuple with these fields:
7511 (utime, stime, cutime, cstime, elapsed_time)
7512All fields are floating point numbers.
7513[clinic start generated code]*/
7514
Larry Hastings2f936352014-08-05 14:04:04 +10007515static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007516os_times_impl(PyObject *module)
7517/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007518#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007519{
Victor Stinner8c62be82010-05-06 00:08:46 +00007520 FILETIME create, exit, kernel, user;
7521 HANDLE hProc;
7522 hProc = GetCurrentProcess();
7523 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7524 /* The fields of a FILETIME structure are the hi and lo part
7525 of a 64-bit value expressed in 100 nanosecond units.
7526 1e7 is one second in such units; 1e-7 the inverse.
7527 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7528 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007529 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007530 (double)(user.dwHighDateTime*429.4967296 +
7531 user.dwLowDateTime*1e-7),
7532 (double)(kernel.dwHighDateTime*429.4967296 +
7533 kernel.dwLowDateTime*1e-7),
7534 (double)0,
7535 (double)0,
7536 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007537}
Larry Hastings2f936352014-08-05 14:04:04 +10007538#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007539{
Larry Hastings2f936352014-08-05 14:04:04 +10007540
7541
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007542 struct tms t;
7543 clock_t c;
7544 errno = 0;
7545 c = times(&t);
7546 if (c == (clock_t) -1)
7547 return posix_error();
7548 return build_times_result(
7549 (double)t.tms_utime / ticks_per_second,
7550 (double)t.tms_stime / ticks_per_second,
7551 (double)t.tms_cutime / ticks_per_second,
7552 (double)t.tms_cstime / ticks_per_second,
7553 (double)c / ticks_per_second);
7554}
Larry Hastings2f936352014-08-05 14:04:04 +10007555#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007556#endif /* HAVE_TIMES */
7557
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007558
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007559#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007560/*[clinic input]
7561os.getsid
7562
7563 pid: pid_t
7564 /
7565
7566Call the system call getsid(pid) and return the result.
7567[clinic start generated code]*/
7568
Larry Hastings2f936352014-08-05 14:04:04 +10007569static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007570os_getsid_impl(PyObject *module, pid_t pid)
7571/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007572{
Victor Stinner8c62be82010-05-06 00:08:46 +00007573 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007574 sid = getsid(pid);
7575 if (sid < 0)
7576 return posix_error();
7577 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007578}
7579#endif /* HAVE_GETSID */
7580
7581
Guido van Rossumb6775db1994-08-01 11:34:53 +00007582#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007583/*[clinic input]
7584os.setsid
7585
7586Call the system call setsid().
7587[clinic start generated code]*/
7588
Larry Hastings2f936352014-08-05 14:04:04 +10007589static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007590os_setsid_impl(PyObject *module)
7591/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007592{
Victor Stinner8c62be82010-05-06 00:08:46 +00007593 if (setsid() < 0)
7594 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007595 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007596}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007597#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007598
Larry Hastings2f936352014-08-05 14:04:04 +10007599
Guido van Rossumb6775db1994-08-01 11:34:53 +00007600#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007601/*[clinic input]
7602os.setpgid
7603
7604 pid: pid_t
7605 pgrp: pid_t
7606 /
7607
7608Call the system call setpgid(pid, pgrp).
7609[clinic start generated code]*/
7610
Larry Hastings2f936352014-08-05 14:04:04 +10007611static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007612os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7613/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007614{
Victor Stinner8c62be82010-05-06 00:08:46 +00007615 if (setpgid(pid, pgrp) < 0)
7616 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007617 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007618}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007619#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007620
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007621
Guido van Rossumb6775db1994-08-01 11:34:53 +00007622#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007623/*[clinic input]
7624os.tcgetpgrp
7625
7626 fd: int
7627 /
7628
7629Return the process group associated with the terminal specified by fd.
7630[clinic start generated code]*/
7631
Larry Hastings2f936352014-08-05 14:04:04 +10007632static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007633os_tcgetpgrp_impl(PyObject *module, int fd)
7634/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007635{
7636 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007637 if (pgid < 0)
7638 return posix_error();
7639 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007640}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007641#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007642
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007643
Guido van Rossumb6775db1994-08-01 11:34:53 +00007644#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007645/*[clinic input]
7646os.tcsetpgrp
7647
7648 fd: int
7649 pgid: pid_t
7650 /
7651
7652Set the process group associated with the terminal specified by fd.
7653[clinic start generated code]*/
7654
Larry Hastings2f936352014-08-05 14:04:04 +10007655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007656os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7657/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007658{
Victor Stinner8c62be82010-05-06 00:08:46 +00007659 if (tcsetpgrp(fd, pgid) < 0)
7660 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007661 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007662}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007663#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007664
Guido van Rossum687dd131993-05-17 08:34:16 +00007665/* Functions acting on file descriptors */
7666
Victor Stinnerdaf45552013-08-28 00:53:59 +02007667#ifdef O_CLOEXEC
7668extern int _Py_open_cloexec_works;
7669#endif
7670
Larry Hastings2f936352014-08-05 14:04:04 +10007671
7672/*[clinic input]
7673os.open -> int
7674 path: path_t
7675 flags: int
7676 mode: int = 0o777
7677 *
7678 dir_fd: dir_fd(requires='openat') = None
7679
7680# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7681
7682Open a file for low level IO. Returns a file descriptor (integer).
7683
7684If dir_fd is not None, it should be a file descriptor open to a directory,
7685 and path should be relative; path will then be relative to that directory.
7686dir_fd may not be implemented on your platform.
7687 If it is unavailable, using it will raise a NotImplementedError.
7688[clinic start generated code]*/
7689
Larry Hastings2f936352014-08-05 14:04:04 +10007690static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007691os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7692/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007693{
7694 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007695 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007696
Victor Stinnerdaf45552013-08-28 00:53:59 +02007697#ifdef O_CLOEXEC
7698 int *atomic_flag_works = &_Py_open_cloexec_works;
7699#elif !defined(MS_WINDOWS)
7700 int *atomic_flag_works = NULL;
7701#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007702
Victor Stinnerdaf45552013-08-28 00:53:59 +02007703#ifdef MS_WINDOWS
7704 flags |= O_NOINHERIT;
7705#elif defined(O_CLOEXEC)
7706 flags |= O_CLOEXEC;
7707#endif
7708
Steve Dower8fc89802015-04-12 00:26:27 -04007709 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007710 do {
7711 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007712#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007713 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007714#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007715#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007716 if (dir_fd != DEFAULT_DIR_FD)
7717 fd = openat(dir_fd, path->narrow, flags, mode);
7718 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007719#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007720 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007721#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007722 Py_END_ALLOW_THREADS
7723 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007724 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007725
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007726 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007727 if (!async_err)
7728 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007729 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007730 }
7731
Victor Stinnerdaf45552013-08-28 00:53:59 +02007732#ifndef MS_WINDOWS
7733 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7734 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007735 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007736 }
7737#endif
7738
Larry Hastings2f936352014-08-05 14:04:04 +10007739 return fd;
7740}
7741
7742
7743/*[clinic input]
7744os.close
7745
7746 fd: int
7747
7748Close a file descriptor.
7749[clinic start generated code]*/
7750
Barry Warsaw53699e91996-12-10 23:23:01 +00007751static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007752os_close_impl(PyObject *module, int fd)
7753/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007754{
Larry Hastings2f936352014-08-05 14:04:04 +10007755 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007756 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7757 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7758 * for more details.
7759 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007760 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007761 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007762 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007763 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007764 Py_END_ALLOW_THREADS
7765 if (res < 0)
7766 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007767 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007768}
7769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007770
Larry Hastings2f936352014-08-05 14:04:04 +10007771/*[clinic input]
7772os.closerange
7773
7774 fd_low: int
7775 fd_high: int
7776 /
7777
7778Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7779[clinic start generated code]*/
7780
Larry Hastings2f936352014-08-05 14:04:04 +10007781static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007782os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7783/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007784{
7785 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007786 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007787 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007788 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007789 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007790 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 Py_END_ALLOW_THREADS
7792 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007793}
7794
7795
Larry Hastings2f936352014-08-05 14:04:04 +10007796/*[clinic input]
7797os.dup -> int
7798
7799 fd: int
7800 /
7801
7802Return a duplicate of a file descriptor.
7803[clinic start generated code]*/
7804
Larry Hastings2f936352014-08-05 14:04:04 +10007805static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007806os_dup_impl(PyObject *module, int fd)
7807/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007808{
7809 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007810}
7811
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007812
Larry Hastings2f936352014-08-05 14:04:04 +10007813/*[clinic input]
7814os.dup2
7815 fd: int
7816 fd2: int
7817 inheritable: bool=True
7818
7819Duplicate file descriptor.
7820[clinic start generated code]*/
7821
Larry Hastings2f936352014-08-05 14:04:04 +10007822static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007823os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7824/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007825{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007826 int res;
7827#if defined(HAVE_DUP3) && \
7828 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7829 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7830 int dup3_works = -1;
7831#endif
7832
Steve Dower940f33a2016-09-08 11:21:54 -07007833 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007834 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007835
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007836 /* dup2() can fail with EINTR if the target FD is already open, because it
7837 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7838 * upon close(), and therefore below.
7839 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007840#ifdef MS_WINDOWS
7841 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007842 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007843 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007844 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007845 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007846 if (res < 0)
7847 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007848
7849 /* Character files like console cannot be make non-inheritable */
7850 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7851 close(fd2);
7852 return NULL;
7853 }
7854
7855#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7856 Py_BEGIN_ALLOW_THREADS
7857 if (!inheritable)
7858 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7859 else
7860 res = dup2(fd, fd2);
7861 Py_END_ALLOW_THREADS
7862 if (res < 0)
7863 return posix_error();
7864
7865#else
7866
7867#ifdef HAVE_DUP3
7868 if (!inheritable && dup3_works != 0) {
7869 Py_BEGIN_ALLOW_THREADS
7870 res = dup3(fd, fd2, O_CLOEXEC);
7871 Py_END_ALLOW_THREADS
7872 if (res < 0) {
7873 if (dup3_works == -1)
7874 dup3_works = (errno != ENOSYS);
7875 if (dup3_works)
7876 return posix_error();
7877 }
7878 }
7879
7880 if (inheritable || dup3_works == 0)
7881 {
7882#endif
7883 Py_BEGIN_ALLOW_THREADS
7884 res = dup2(fd, fd2);
7885 Py_END_ALLOW_THREADS
7886 if (res < 0)
7887 return posix_error();
7888
7889 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7890 close(fd2);
7891 return NULL;
7892 }
7893#ifdef HAVE_DUP3
7894 }
7895#endif
7896
7897#endif
7898
Larry Hastings2f936352014-08-05 14:04:04 +10007899 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007900}
7901
Larry Hastings2f936352014-08-05 14:04:04 +10007902
Ross Lagerwall7807c352011-03-17 20:20:30 +02007903#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007904/*[clinic input]
7905os.lockf
7906
7907 fd: int
7908 An open file descriptor.
7909 command: int
7910 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7911 length: Py_off_t
7912 The number of bytes to lock, starting at the current position.
7913 /
7914
7915Apply, test or remove a POSIX lock on an open file descriptor.
7916
7917[clinic start generated code]*/
7918
Larry Hastings2f936352014-08-05 14:04:04 +10007919static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007920os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7921/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007922{
7923 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007924
7925 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007926 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007927 Py_END_ALLOW_THREADS
7928
7929 if (res < 0)
7930 return posix_error();
7931
7932 Py_RETURN_NONE;
7933}
Larry Hastings2f936352014-08-05 14:04:04 +10007934#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007935
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007936
Larry Hastings2f936352014-08-05 14:04:04 +10007937/*[clinic input]
7938os.lseek -> Py_off_t
7939
7940 fd: int
7941 position: Py_off_t
7942 how: int
7943 /
7944
7945Set the position of a file descriptor. Return the new position.
7946
7947Return the new cursor position in number of bytes
7948relative to the beginning of the file.
7949[clinic start generated code]*/
7950
Larry Hastings2f936352014-08-05 14:04:04 +10007951static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007952os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7953/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007954{
7955 Py_off_t result;
7956
Guido van Rossum687dd131993-05-17 08:34:16 +00007957#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007958 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7959 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007960 case 0: how = SEEK_SET; break;
7961 case 1: how = SEEK_CUR; break;
7962 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007964#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007965
Victor Stinner8c62be82010-05-06 00:08:46 +00007966 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007967 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007968
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007970 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007971#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007972 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007973#else
Larry Hastings2f936352014-08-05 14:04:04 +10007974 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007975#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007976 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007977 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007978 if (result < 0)
7979 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007980
Larry Hastings2f936352014-08-05 14:04:04 +10007981 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007982}
7983
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007984
Larry Hastings2f936352014-08-05 14:04:04 +10007985/*[clinic input]
7986os.read
7987 fd: int
7988 length: Py_ssize_t
7989 /
7990
7991Read from a file descriptor. Returns a bytes object.
7992[clinic start generated code]*/
7993
Larry Hastings2f936352014-08-05 14:04:04 +10007994static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007995os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7996/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007997{
Victor Stinner8c62be82010-05-06 00:08:46 +00007998 Py_ssize_t n;
7999 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008000
8001 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 errno = EINVAL;
8003 return posix_error();
8004 }
Larry Hastings2f936352014-08-05 14:04:04 +10008005
8006#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008007 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008008 if (length > INT_MAX)
8009 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008010#endif
8011
8012 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008013 if (buffer == NULL)
8014 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008015
Victor Stinner66aab0c2015-03-19 22:53:20 +01008016 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8017 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008019 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008020 }
Larry Hastings2f936352014-08-05 14:04:04 +10008021
8022 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008023 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008024
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008026}
8027
Ross Lagerwall7807c352011-03-17 20:20:30 +02008028#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8029 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008030static Py_ssize_t
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008031iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008032{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008033 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008034 Py_ssize_t blen, total = 0;
8035
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008036 *iov = PyMem_New(struct iovec, cnt);
8037 if (*iov == NULL) {
8038 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008039 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008040 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008041
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008042 *buf = PyMem_New(Py_buffer, cnt);
8043 if (*buf == NULL) {
8044 PyMem_Del(*iov);
8045 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008046 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008047 }
8048
8049 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008050 PyObject *item = PySequence_GetItem(seq, i);
8051 if (item == NULL)
8052 goto fail;
8053 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8054 Py_DECREF(item);
8055 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008056 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008057 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008058 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008059 blen = (*buf)[i].len;
8060 (*iov)[i].iov_len = blen;
8061 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008062 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008063 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008064
8065fail:
8066 PyMem_Del(*iov);
8067 for (j = 0; j < i; j++) {
8068 PyBuffer_Release(&(*buf)[j]);
8069 }
8070 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008071 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008072}
8073
8074static void
8075iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8076{
8077 int i;
8078 PyMem_Del(iov);
8079 for (i = 0; i < cnt; i++) {
8080 PyBuffer_Release(&buf[i]);
8081 }
8082 PyMem_Del(buf);
8083}
8084#endif
8085
Larry Hastings2f936352014-08-05 14:04:04 +10008086
Ross Lagerwall7807c352011-03-17 20:20:30 +02008087#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008088/*[clinic input]
8089os.readv -> Py_ssize_t
8090
8091 fd: int
8092 buffers: object
8093 /
8094
8095Read from a file descriptor fd into an iterable of buffers.
8096
8097The buffers should be mutable buffers accepting bytes.
8098readv will transfer data into each buffer until it is full
8099and then move on to the next buffer in the sequence to hold
8100the rest of the data.
8101
8102readv returns the total number of bytes read,
8103which may be less than the total capacity of all the buffers.
8104[clinic start generated code]*/
8105
Larry Hastings2f936352014-08-05 14:04:04 +10008106static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008107os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8108/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008109{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008110 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008111 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008112 struct iovec *iov;
8113 Py_buffer *buf;
8114
Larry Hastings2f936352014-08-05 14:04:04 +10008115 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008116 PyErr_SetString(PyExc_TypeError,
8117 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008118 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008119 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008120
Larry Hastings2f936352014-08-05 14:04:04 +10008121 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008122 if (cnt < 0)
8123 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008124
8125 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8126 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008127
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008128 do {
8129 Py_BEGIN_ALLOW_THREADS
8130 n = readv(fd, iov, cnt);
8131 Py_END_ALLOW_THREADS
8132 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008133
8134 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008135 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008136 if (!async_err)
8137 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008138 return -1;
8139 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008140
Larry Hastings2f936352014-08-05 14:04:04 +10008141 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008142}
Larry Hastings2f936352014-08-05 14:04:04 +10008143#endif /* HAVE_READV */
8144
Ross Lagerwall7807c352011-03-17 20:20:30 +02008145
8146#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008147/*[clinic input]
8148# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8149os.pread
8150
8151 fd: int
8152 length: int
8153 offset: Py_off_t
8154 /
8155
8156Read a number of bytes from a file descriptor starting at a particular offset.
8157
8158Read length bytes from file descriptor fd, starting at offset bytes from
8159the beginning of the file. The file offset remains unchanged.
8160[clinic start generated code]*/
8161
Larry Hastings2f936352014-08-05 14:04:04 +10008162static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008163os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8164/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008165{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008166 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008167 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008168 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008169
Larry Hastings2f936352014-08-05 14:04:04 +10008170 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008171 errno = EINVAL;
8172 return posix_error();
8173 }
Larry Hastings2f936352014-08-05 14:04:04 +10008174 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008175 if (buffer == NULL)
8176 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008177
8178 do {
8179 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008180 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008181 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008182 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008183 Py_END_ALLOW_THREADS
8184 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8185
Ross Lagerwall7807c352011-03-17 20:20:30 +02008186 if (n < 0) {
8187 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008188 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008189 }
Larry Hastings2f936352014-08-05 14:04:04 +10008190 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008191 _PyBytes_Resize(&buffer, n);
8192 return buffer;
8193}
Larry Hastings2f936352014-08-05 14:04:04 +10008194#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008195
Larry Hastings2f936352014-08-05 14:04:04 +10008196
8197/*[clinic input]
8198os.write -> Py_ssize_t
8199
8200 fd: int
8201 data: Py_buffer
8202 /
8203
8204Write a bytes object to a file descriptor.
8205[clinic start generated code]*/
8206
Larry Hastings2f936352014-08-05 14:04:04 +10008207static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008208os_write_impl(PyObject *module, int fd, Py_buffer *data)
8209/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008210{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008211 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008212}
8213
8214#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008215PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008216"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008217sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008218 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008219Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008220
Larry Hastings2f936352014-08-05 14:04:04 +10008221/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008222static PyObject *
8223posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8224{
8225 int in, out;
8226 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008227 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008228 off_t offset;
8229
8230#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8231#ifndef __APPLE__
8232 Py_ssize_t len;
8233#endif
8234 PyObject *headers = NULL, *trailers = NULL;
8235 Py_buffer *hbuf, *tbuf;
8236 off_t sbytes;
8237 struct sf_hdtr sf;
8238 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008239 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008240 static char *keywords[] = {"out", "in",
8241 "offset", "count",
8242 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008243
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008244 sf.headers = NULL;
8245 sf.trailers = NULL;
8246
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008247#ifdef __APPLE__
8248 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008249 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008250#else
8251 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008252 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008253#endif
8254 &headers, &trailers, &flags))
8255 return NULL;
8256 if (headers != NULL) {
8257 if (!PySequence_Check(headers)) {
8258 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008259 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008260 return NULL;
8261 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008262 Py_ssize_t i = PySequence_Size(headers);
8263 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008264 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008265 if (i > INT_MAX) {
8266 PyErr_SetString(PyExc_OverflowError,
8267 "sendfile() header is too large");
8268 return NULL;
8269 }
8270 if (i > 0) {
8271 sf.hdr_cnt = (int)i;
8272 i = iov_setup(&(sf.headers), &hbuf,
8273 headers, sf.hdr_cnt, PyBUF_SIMPLE);
8274 if (i < 0)
8275 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008276#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008277 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008278#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008279 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008280 }
8281 }
8282 if (trailers != NULL) {
8283 if (!PySequence_Check(trailers)) {
8284 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008285 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008286 return NULL;
8287 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008288 Py_ssize_t i = PySequence_Size(trailers);
8289 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008290 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008291 if (i > INT_MAX) {
8292 PyErr_SetString(PyExc_OverflowError,
8293 "sendfile() trailer is too large");
8294 return NULL;
8295 }
8296 if (i > 0) {
8297 sf.trl_cnt = (int)i;
8298 i = iov_setup(&(sf.trailers), &tbuf,
8299 trailers, sf.trl_cnt, PyBUF_SIMPLE);
8300 if (i < 0)
8301 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008302#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008303 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008304#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008305 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008306 }
8307 }
8308
Steve Dower8fc89802015-04-12 00:26:27 -04008309 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008310 do {
8311 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008312#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008313 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008314#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008315 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008316#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008317 Py_END_ALLOW_THREADS
8318 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008319 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008320
8321 if (sf.headers != NULL)
8322 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8323 if (sf.trailers != NULL)
8324 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8325
8326 if (ret < 0) {
8327 if ((errno == EAGAIN) || (errno == EBUSY)) {
8328 if (sbytes != 0) {
8329 // some data has been sent
8330 goto done;
8331 }
8332 else {
8333 // no data has been sent; upper application is supposed
8334 // to retry on EAGAIN or EBUSY
8335 return posix_error();
8336 }
8337 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008338 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008339 }
8340 goto done;
8341
8342done:
8343 #if !defined(HAVE_LARGEFILE_SUPPORT)
8344 return Py_BuildValue("l", sbytes);
8345 #else
8346 return Py_BuildValue("L", sbytes);
8347 #endif
8348
8349#else
8350 Py_ssize_t count;
8351 PyObject *offobj;
8352 static char *keywords[] = {"out", "in",
8353 "offset", "count", NULL};
8354 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8355 keywords, &out, &in, &offobj, &count))
8356 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008357#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008358 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008359 do {
8360 Py_BEGIN_ALLOW_THREADS
8361 ret = sendfile(out, in, NULL, count);
8362 Py_END_ALLOW_THREADS
8363 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008364 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008365 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008366 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008367 }
8368#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008369 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008370 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008371
8372 do {
8373 Py_BEGIN_ALLOW_THREADS
8374 ret = sendfile(out, in, &offset, count);
8375 Py_END_ALLOW_THREADS
8376 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008377 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008378 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008379 return Py_BuildValue("n", ret);
8380#endif
8381}
Larry Hastings2f936352014-08-05 14:04:04 +10008382#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008383
Larry Hastings2f936352014-08-05 14:04:04 +10008384
8385/*[clinic input]
8386os.fstat
8387
8388 fd : int
8389
8390Perform a stat system call on the given file descriptor.
8391
8392Like stat(), but for an open file descriptor.
8393Equivalent to os.stat(fd).
8394[clinic start generated code]*/
8395
Larry Hastings2f936352014-08-05 14:04:04 +10008396static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008397os_fstat_impl(PyObject *module, int fd)
8398/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008399{
Victor Stinner8c62be82010-05-06 00:08:46 +00008400 STRUCT_STAT st;
8401 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008402 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008403
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008404 do {
8405 Py_BEGIN_ALLOW_THREADS
8406 res = FSTAT(fd, &st);
8407 Py_END_ALLOW_THREADS
8408 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008410#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008411 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008412#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008413 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008414#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008415 }
Tim Peters5aa91602002-01-30 05:46:57 +00008416
Victor Stinner4195b5c2012-02-08 23:03:19 +01008417 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008418}
8419
Larry Hastings2f936352014-08-05 14:04:04 +10008420
8421/*[clinic input]
8422os.isatty -> bool
8423 fd: int
8424 /
8425
8426Return True if the fd is connected to a terminal.
8427
8428Return True if the file descriptor is an open file descriptor
8429connected to the slave end of a terminal.
8430[clinic start generated code]*/
8431
Larry Hastings2f936352014-08-05 14:04:04 +10008432static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008433os_isatty_impl(PyObject *module, int fd)
8434/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008435{
Steve Dower8fc89802015-04-12 00:26:27 -04008436 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008437 _Py_BEGIN_SUPPRESS_IPH
8438 return_value = isatty(fd);
8439 _Py_END_SUPPRESS_IPH
8440 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008441}
8442
8443
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008444#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008445/*[clinic input]
8446os.pipe
8447
8448Create a pipe.
8449
8450Returns a tuple of two file descriptors:
8451 (read_fd, write_fd)
8452[clinic start generated code]*/
8453
Larry Hastings2f936352014-08-05 14:04:04 +10008454static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008455os_pipe_impl(PyObject *module)
8456/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008457{
Victor Stinner8c62be82010-05-06 00:08:46 +00008458 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008459#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008460 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008461 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008462 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008463#else
8464 int res;
8465#endif
8466
8467#ifdef MS_WINDOWS
8468 attr.nLength = sizeof(attr);
8469 attr.lpSecurityDescriptor = NULL;
8470 attr.bInheritHandle = FALSE;
8471
8472 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008473 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008474 ok = CreatePipe(&read, &write, &attr, 0);
8475 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008476 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8477 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008478 if (fds[0] == -1 || fds[1] == -1) {
8479 CloseHandle(read);
8480 CloseHandle(write);
8481 ok = 0;
8482 }
8483 }
Steve Dowerc3630612016-11-19 18:41:16 -08008484 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008485 Py_END_ALLOW_THREADS
8486
Victor Stinner8c62be82010-05-06 00:08:46 +00008487 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008488 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008489#else
8490
8491#ifdef HAVE_PIPE2
8492 Py_BEGIN_ALLOW_THREADS
8493 res = pipe2(fds, O_CLOEXEC);
8494 Py_END_ALLOW_THREADS
8495
8496 if (res != 0 && errno == ENOSYS)
8497 {
8498#endif
8499 Py_BEGIN_ALLOW_THREADS
8500 res = pipe(fds);
8501 Py_END_ALLOW_THREADS
8502
8503 if (res == 0) {
8504 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8505 close(fds[0]);
8506 close(fds[1]);
8507 return NULL;
8508 }
8509 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8510 close(fds[0]);
8511 close(fds[1]);
8512 return NULL;
8513 }
8514 }
8515#ifdef HAVE_PIPE2
8516 }
8517#endif
8518
8519 if (res != 0)
8520 return PyErr_SetFromErrno(PyExc_OSError);
8521#endif /* !MS_WINDOWS */
8522 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008523}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008524#endif /* HAVE_PIPE */
8525
Larry Hastings2f936352014-08-05 14:04:04 +10008526
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008527#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008528/*[clinic input]
8529os.pipe2
8530
8531 flags: int
8532 /
8533
8534Create a pipe with flags set atomically.
8535
8536Returns a tuple of two file descriptors:
8537 (read_fd, write_fd)
8538
8539flags can be constructed by ORing together one or more of these values:
8540O_NONBLOCK, O_CLOEXEC.
8541[clinic start generated code]*/
8542
Larry Hastings2f936352014-08-05 14:04:04 +10008543static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008544os_pipe2_impl(PyObject *module, int flags)
8545/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008546{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008547 int fds[2];
8548 int res;
8549
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008550 res = pipe2(fds, flags);
8551 if (res != 0)
8552 return posix_error();
8553 return Py_BuildValue("(ii)", fds[0], fds[1]);
8554}
8555#endif /* HAVE_PIPE2 */
8556
Larry Hastings2f936352014-08-05 14:04:04 +10008557
Ross Lagerwall7807c352011-03-17 20:20:30 +02008558#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008559/*[clinic input]
8560os.writev -> Py_ssize_t
8561 fd: int
8562 buffers: object
8563 /
8564
8565Iterate over buffers, and write the contents of each to a file descriptor.
8566
8567Returns the total number of bytes written.
8568buffers must be a sequence of bytes-like objects.
8569[clinic start generated code]*/
8570
Larry Hastings2f936352014-08-05 14:04:04 +10008571static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008572os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8573/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008574{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008575 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008576 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008577 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008578 struct iovec *iov;
8579 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008580
8581 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008582 PyErr_SetString(PyExc_TypeError,
8583 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008584 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008585 }
Larry Hastings2f936352014-08-05 14:04:04 +10008586 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008587 if (cnt < 0)
8588 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008589
Larry Hastings2f936352014-08-05 14:04:04 +10008590 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8591 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008592 }
8593
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008594 do {
8595 Py_BEGIN_ALLOW_THREADS
8596 result = writev(fd, iov, cnt);
8597 Py_END_ALLOW_THREADS
8598 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008599
8600 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008601 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008602 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008603
Georg Brandl306336b2012-06-24 12:55:33 +02008604 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008605}
Larry Hastings2f936352014-08-05 14:04:04 +10008606#endif /* HAVE_WRITEV */
8607
8608
8609#ifdef HAVE_PWRITE
8610/*[clinic input]
8611os.pwrite -> Py_ssize_t
8612
8613 fd: int
8614 buffer: Py_buffer
8615 offset: Py_off_t
8616 /
8617
8618Write bytes to a file descriptor starting at a particular offset.
8619
8620Write buffer to fd, starting at offset bytes from the beginning of
8621the file. Returns the number of bytes writte. Does not change the
8622current file offset.
8623[clinic start generated code]*/
8624
Larry Hastings2f936352014-08-05 14:04:04 +10008625static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008626os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8627/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008628{
8629 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008630 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008631
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008632 do {
8633 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008634 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008635 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008636 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008637 Py_END_ALLOW_THREADS
8638 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008639
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008640 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008641 posix_error();
8642 return size;
8643}
8644#endif /* HAVE_PWRITE */
8645
8646
8647#ifdef HAVE_MKFIFO
8648/*[clinic input]
8649os.mkfifo
8650
8651 path: path_t
8652 mode: int=0o666
8653 *
8654 dir_fd: dir_fd(requires='mkfifoat')=None
8655
8656Create a "fifo" (a POSIX named pipe).
8657
8658If dir_fd is not None, it should be a file descriptor open to a directory,
8659 and path should be relative; path will then be relative to that directory.
8660dir_fd may not be implemented on your platform.
8661 If it is unavailable, using it will raise a NotImplementedError.
8662[clinic start generated code]*/
8663
Larry Hastings2f936352014-08-05 14:04:04 +10008664static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008665os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8666/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008667{
8668 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008669 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008670
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008671 do {
8672 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008673#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008674 if (dir_fd != DEFAULT_DIR_FD)
8675 result = mkfifoat(dir_fd, path->narrow, mode);
8676 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008677#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008678 result = mkfifo(path->narrow, mode);
8679 Py_END_ALLOW_THREADS
8680 } while (result != 0 && errno == EINTR &&
8681 !(async_err = PyErr_CheckSignals()));
8682 if (result != 0)
8683 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008684
8685 Py_RETURN_NONE;
8686}
8687#endif /* HAVE_MKFIFO */
8688
8689
8690#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8691/*[clinic input]
8692os.mknod
8693
8694 path: path_t
8695 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008696 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008697 *
8698 dir_fd: dir_fd(requires='mknodat')=None
8699
8700Create a node in the file system.
8701
8702Create a node in the file system (file, device special file or named pipe)
8703at path. mode specifies both the permissions to use and the
8704type of node to be created, being combined (bitwise OR) with one of
8705S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8706device defines the newly created device special file (probably using
8707os.makedev()). Otherwise device is ignored.
8708
8709If dir_fd is not None, it should be a file descriptor open to a directory,
8710 and path should be relative; path will then be relative to that directory.
8711dir_fd may not be implemented on your platform.
8712 If it is unavailable, using it will raise a NotImplementedError.
8713[clinic start generated code]*/
8714
Larry Hastings2f936352014-08-05 14:04:04 +10008715static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008716os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008717 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008718/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008719{
8720 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008721 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008722
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008723 do {
8724 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008725#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008726 if (dir_fd != DEFAULT_DIR_FD)
8727 result = mknodat(dir_fd, path->narrow, mode, device);
8728 else
Larry Hastings2f936352014-08-05 14:04:04 +10008729#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008730 result = mknod(path->narrow, mode, device);
8731 Py_END_ALLOW_THREADS
8732 } while (result != 0 && errno == EINTR &&
8733 !(async_err = PyErr_CheckSignals()));
8734 if (result != 0)
8735 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008736
8737 Py_RETURN_NONE;
8738}
8739#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8740
8741
8742#ifdef HAVE_DEVICE_MACROS
8743/*[clinic input]
8744os.major -> unsigned_int
8745
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008746 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008747 /
8748
8749Extracts a device major number from a raw device number.
8750[clinic start generated code]*/
8751
Larry Hastings2f936352014-08-05 14:04:04 +10008752static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008753os_major_impl(PyObject *module, dev_t device)
8754/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008755{
8756 return major(device);
8757}
8758
8759
8760/*[clinic input]
8761os.minor -> unsigned_int
8762
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008763 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008764 /
8765
8766Extracts a device minor number from a raw device number.
8767[clinic start generated code]*/
8768
Larry Hastings2f936352014-08-05 14:04:04 +10008769static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008770os_minor_impl(PyObject *module, dev_t device)
8771/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008772{
8773 return minor(device);
8774}
8775
8776
8777/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008778os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008779
8780 major: int
8781 minor: int
8782 /
8783
8784Composes a raw device number from the major and minor device numbers.
8785[clinic start generated code]*/
8786
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008787static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008788os_makedev_impl(PyObject *module, int major, int minor)
8789/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008790{
8791 return makedev(major, minor);
8792}
8793#endif /* HAVE_DEVICE_MACROS */
8794
8795
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008796#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008797/*[clinic input]
8798os.ftruncate
8799
8800 fd: int
8801 length: Py_off_t
8802 /
8803
8804Truncate a file, specified by file descriptor, to a specific length.
8805[clinic start generated code]*/
8806
Larry Hastings2f936352014-08-05 14:04:04 +10008807static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008808os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8809/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008810{
8811 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008812 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008813
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008814 do {
8815 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008816 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008817#ifdef MS_WINDOWS
8818 result = _chsize_s(fd, length);
8819#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008820 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008821#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008822 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008823 Py_END_ALLOW_THREADS
8824 } while (result != 0 && errno == EINTR &&
8825 !(async_err = PyErr_CheckSignals()));
8826 if (result != 0)
8827 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008828 Py_RETURN_NONE;
8829}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008830#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008831
8832
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008833#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008834/*[clinic input]
8835os.truncate
8836 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8837 length: Py_off_t
8838
8839Truncate a file, specified by path, to a specific length.
8840
8841On some platforms, path may also be specified as an open file descriptor.
8842 If this functionality is unavailable, using it raises an exception.
8843[clinic start generated code]*/
8844
Larry Hastings2f936352014-08-05 14:04:04 +10008845static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008846os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8847/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008848{
8849 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008850#ifdef MS_WINDOWS
8851 int fd;
8852#endif
8853
8854 if (path->fd != -1)
8855 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008856
8857 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008858 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008859#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008860 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008861 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008862 result = -1;
8863 else {
8864 result = _chsize_s(fd, length);
8865 close(fd);
8866 if (result < 0)
8867 errno = result;
8868 }
8869#else
8870 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008871#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008872 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008873 Py_END_ALLOW_THREADS
8874 if (result < 0)
8875 return path_error(path);
8876
8877 Py_RETURN_NONE;
8878}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008879#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008880
Ross Lagerwall7807c352011-03-17 20:20:30 +02008881
Victor Stinnerd6b17692014-09-30 12:20:05 +02008882/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8883 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8884 defined, which is the case in Python on AIX. AIX bug report:
8885 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8886#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8887# define POSIX_FADVISE_AIX_BUG
8888#endif
8889
Victor Stinnerec39e262014-09-30 12:35:58 +02008890
Victor Stinnerd6b17692014-09-30 12:20:05 +02008891#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008892/*[clinic input]
8893os.posix_fallocate
8894
8895 fd: int
8896 offset: Py_off_t
8897 length: Py_off_t
8898 /
8899
8900Ensure a file has allocated at least a particular number of bytes on disk.
8901
8902Ensure that the file specified by fd encompasses a range of bytes
8903starting at offset bytes from the beginning and continuing for length bytes.
8904[clinic start generated code]*/
8905
Larry Hastings2f936352014-08-05 14:04:04 +10008906static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008907os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008908 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008909/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008910{
8911 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008912 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008913
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008914 do {
8915 Py_BEGIN_ALLOW_THREADS
8916 result = posix_fallocate(fd, offset, length);
8917 Py_END_ALLOW_THREADS
8918 } while (result != 0 && errno == EINTR &&
8919 !(async_err = PyErr_CheckSignals()));
8920 if (result != 0)
8921 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008922 Py_RETURN_NONE;
8923}
Victor Stinnerec39e262014-09-30 12:35:58 +02008924#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008925
Ross Lagerwall7807c352011-03-17 20:20:30 +02008926
Victor Stinnerd6b17692014-09-30 12:20:05 +02008927#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008928/*[clinic input]
8929os.posix_fadvise
8930
8931 fd: int
8932 offset: Py_off_t
8933 length: Py_off_t
8934 advice: int
8935 /
8936
8937Announce an intention to access data in a specific pattern.
8938
8939Announce an intention to access data in a specific pattern, thus allowing
8940the kernel to make optimizations.
8941The advice applies to the region of the file specified by fd starting at
8942offset and continuing for length bytes.
8943advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8944POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8945POSIX_FADV_DONTNEED.
8946[clinic start generated code]*/
8947
Larry Hastings2f936352014-08-05 14:04:04 +10008948static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008949os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008950 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008951/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008952{
8953 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008954 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008955
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008956 do {
8957 Py_BEGIN_ALLOW_THREADS
8958 result = posix_fadvise(fd, offset, length, advice);
8959 Py_END_ALLOW_THREADS
8960 } while (result != 0 && errno == EINTR &&
8961 !(async_err = PyErr_CheckSignals()));
8962 if (result != 0)
8963 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008964 Py_RETURN_NONE;
8965}
Victor Stinnerec39e262014-09-30 12:35:58 +02008966#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008967
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008968#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008969
Fred Drake762e2061999-08-26 17:23:54 +00008970/* Save putenv() parameters as values here, so we can collect them when they
8971 * get re-set with another call for the same key. */
8972static PyObject *posix_putenv_garbage;
8973
Larry Hastings2f936352014-08-05 14:04:04 +10008974static void
8975posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008976{
Larry Hastings2f936352014-08-05 14:04:04 +10008977 /* Install the first arg and newstr in posix_putenv_garbage;
8978 * this will cause previous value to be collected. This has to
8979 * happen after the real putenv() call because the old value
8980 * was still accessible until then. */
8981 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8982 /* really not much we can do; just leak */
8983 PyErr_Clear();
8984 else
8985 Py_DECREF(value);
8986}
8987
8988
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008989#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008990/*[clinic input]
8991os.putenv
8992
8993 name: unicode
8994 value: unicode
8995 /
8996
8997Change or add an environment variable.
8998[clinic start generated code]*/
8999
Larry Hastings2f936352014-08-05 14:04:04 +10009000static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009001os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9002/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009003{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009004 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009005 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009006
Serhiy Storchaka77703942017-06-25 07:33:01 +03009007 /* Search from index 1 because on Windows starting '=' is allowed for
9008 defining hidden environment variables. */
9009 if (PyUnicode_GET_LENGTH(name) == 0 ||
9010 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9011 {
9012 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9013 return NULL;
9014 }
Larry Hastings2f936352014-08-05 14:04:04 +10009015 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9016 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009017 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009018 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009019
9020 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9021 if (env == NULL)
9022 goto error;
9023 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009024 PyErr_Format(PyExc_ValueError,
9025 "the environment variable is longer than %u characters",
9026 _MAX_ENV);
9027 goto error;
9028 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009029 if (wcslen(env) != (size_t)size) {
9030 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009031 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009032 }
9033
Larry Hastings2f936352014-08-05 14:04:04 +10009034 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009035 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009036 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009037 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009038
Larry Hastings2f936352014-08-05 14:04:04 +10009039 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009040 Py_RETURN_NONE;
9041
9042error:
Larry Hastings2f936352014-08-05 14:04:04 +10009043 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009044 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009045}
Larry Hastings2f936352014-08-05 14:04:04 +10009046#else /* MS_WINDOWS */
9047/*[clinic input]
9048os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009049
Larry Hastings2f936352014-08-05 14:04:04 +10009050 name: FSConverter
9051 value: FSConverter
9052 /
9053
9054Change or add an environment variable.
9055[clinic start generated code]*/
9056
Larry Hastings2f936352014-08-05 14:04:04 +10009057static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009058os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9059/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009060{
9061 PyObject *bytes = NULL;
9062 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009063 const char *name_string = PyBytes_AS_STRING(name);
9064 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009065
Serhiy Storchaka77703942017-06-25 07:33:01 +03009066 if (strchr(name_string, '=') != NULL) {
9067 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9068 return NULL;
9069 }
Larry Hastings2f936352014-08-05 14:04:04 +10009070 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9071 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009072 return NULL;
9073 }
9074
9075 env = PyBytes_AS_STRING(bytes);
9076 if (putenv(env)) {
9077 Py_DECREF(bytes);
9078 return posix_error();
9079 }
9080
9081 posix_putenv_garbage_setitem(name, bytes);
9082 Py_RETURN_NONE;
9083}
9084#endif /* MS_WINDOWS */
9085#endif /* HAVE_PUTENV */
9086
9087
9088#ifdef HAVE_UNSETENV
9089/*[clinic input]
9090os.unsetenv
9091 name: FSConverter
9092 /
9093
9094Delete an environment variable.
9095[clinic start generated code]*/
9096
Larry Hastings2f936352014-08-05 14:04:04 +10009097static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009098os_unsetenv_impl(PyObject *module, PyObject *name)
9099/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009100{
Victor Stinner984890f2011-11-24 13:53:38 +01009101#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009102 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009103#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009104
Victor Stinner984890f2011-11-24 13:53:38 +01009105#ifdef HAVE_BROKEN_UNSETENV
9106 unsetenv(PyBytes_AS_STRING(name));
9107#else
Victor Stinner65170952011-11-22 22:16:17 +01009108 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009109 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009110 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009111#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009112
Victor Stinner8c62be82010-05-06 00:08:46 +00009113 /* Remove the key from posix_putenv_garbage;
9114 * this will cause it to be collected. This has to
9115 * happen after the real unsetenv() call because the
9116 * old value was still accessible until then.
9117 */
Victor Stinner65170952011-11-22 22:16:17 +01009118 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009119 /* really not much we can do; just leak */
9120 PyErr_Clear();
9121 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009122 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009123}
Larry Hastings2f936352014-08-05 14:04:04 +10009124#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009125
Larry Hastings2f936352014-08-05 14:04:04 +10009126
9127/*[clinic input]
9128os.strerror
9129
9130 code: int
9131 /
9132
9133Translate an error code to a message string.
9134[clinic start generated code]*/
9135
Larry Hastings2f936352014-08-05 14:04:04 +10009136static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009137os_strerror_impl(PyObject *module, int code)
9138/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009139{
9140 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 if (message == NULL) {
9142 PyErr_SetString(PyExc_ValueError,
9143 "strerror() argument out of range");
9144 return NULL;
9145 }
Victor Stinner1b579672011-12-17 05:47:23 +01009146 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009147}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009148
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009149
Guido van Rossumc9641791998-08-04 15:26:23 +00009150#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009151#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009152/*[clinic input]
9153os.WCOREDUMP -> bool
9154
9155 status: int
9156 /
9157
9158Return True if the process returning status was dumped to a core file.
9159[clinic start generated code]*/
9160
Larry Hastings2f936352014-08-05 14:04:04 +10009161static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009162os_WCOREDUMP_impl(PyObject *module, int status)
9163/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009164{
9165 WAIT_TYPE wait_status;
9166 WAIT_STATUS_INT(wait_status) = status;
9167 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009168}
9169#endif /* WCOREDUMP */
9170
Larry Hastings2f936352014-08-05 14:04:04 +10009171
Fred Drake106c1a02002-04-23 15:58:02 +00009172#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009173/*[clinic input]
9174os.WIFCONTINUED -> bool
9175
9176 status: int
9177
9178Return True if a particular process was continued from a job control stop.
9179
9180Return True if the process returning status was continued from a
9181job control stop.
9182[clinic start generated code]*/
9183
Larry Hastings2f936352014-08-05 14:04:04 +10009184static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009185os_WIFCONTINUED_impl(PyObject *module, int status)
9186/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009187{
9188 WAIT_TYPE wait_status;
9189 WAIT_STATUS_INT(wait_status) = status;
9190 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009191}
9192#endif /* WIFCONTINUED */
9193
Larry Hastings2f936352014-08-05 14:04:04 +10009194
Guido van Rossumc9641791998-08-04 15:26:23 +00009195#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009196/*[clinic input]
9197os.WIFSTOPPED -> bool
9198
9199 status: int
9200
9201Return True if the process returning status was stopped.
9202[clinic start generated code]*/
9203
Larry Hastings2f936352014-08-05 14:04:04 +10009204static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009205os_WIFSTOPPED_impl(PyObject *module, int status)
9206/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009207{
9208 WAIT_TYPE wait_status;
9209 WAIT_STATUS_INT(wait_status) = status;
9210 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009211}
9212#endif /* WIFSTOPPED */
9213
Larry Hastings2f936352014-08-05 14:04:04 +10009214
Guido van Rossumc9641791998-08-04 15:26:23 +00009215#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009216/*[clinic input]
9217os.WIFSIGNALED -> bool
9218
9219 status: int
9220
9221Return True if the process returning status was terminated by a signal.
9222[clinic start generated code]*/
9223
Larry Hastings2f936352014-08-05 14:04:04 +10009224static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009225os_WIFSIGNALED_impl(PyObject *module, int status)
9226/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009227{
9228 WAIT_TYPE wait_status;
9229 WAIT_STATUS_INT(wait_status) = status;
9230 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009231}
9232#endif /* WIFSIGNALED */
9233
Larry Hastings2f936352014-08-05 14:04:04 +10009234
Guido van Rossumc9641791998-08-04 15:26:23 +00009235#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009236/*[clinic input]
9237os.WIFEXITED -> bool
9238
9239 status: int
9240
9241Return True if the process returning status exited via the exit() system call.
9242[clinic start generated code]*/
9243
Larry Hastings2f936352014-08-05 14:04:04 +10009244static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009245os_WIFEXITED_impl(PyObject *module, int status)
9246/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009247{
9248 WAIT_TYPE wait_status;
9249 WAIT_STATUS_INT(wait_status) = status;
9250 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009251}
9252#endif /* WIFEXITED */
9253
Larry Hastings2f936352014-08-05 14:04:04 +10009254
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009255#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009256/*[clinic input]
9257os.WEXITSTATUS -> int
9258
9259 status: int
9260
9261Return the process return code from status.
9262[clinic start generated code]*/
9263
Larry Hastings2f936352014-08-05 14:04:04 +10009264static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009265os_WEXITSTATUS_impl(PyObject *module, int status)
9266/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009267{
9268 WAIT_TYPE wait_status;
9269 WAIT_STATUS_INT(wait_status) = status;
9270 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009271}
9272#endif /* WEXITSTATUS */
9273
Larry Hastings2f936352014-08-05 14:04:04 +10009274
Guido van Rossumc9641791998-08-04 15:26:23 +00009275#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009276/*[clinic input]
9277os.WTERMSIG -> int
9278
9279 status: int
9280
9281Return the signal that terminated the process that provided the status value.
9282[clinic start generated code]*/
9283
Larry Hastings2f936352014-08-05 14:04:04 +10009284static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009285os_WTERMSIG_impl(PyObject *module, int status)
9286/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009287{
9288 WAIT_TYPE wait_status;
9289 WAIT_STATUS_INT(wait_status) = status;
9290 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009291}
9292#endif /* WTERMSIG */
9293
Larry Hastings2f936352014-08-05 14:04:04 +10009294
Guido van Rossumc9641791998-08-04 15:26:23 +00009295#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009296/*[clinic input]
9297os.WSTOPSIG -> int
9298
9299 status: int
9300
9301Return the signal that stopped the process that provided the status value.
9302[clinic start generated code]*/
9303
Larry Hastings2f936352014-08-05 14:04:04 +10009304static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009305os_WSTOPSIG_impl(PyObject *module, int status)
9306/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009307{
9308 WAIT_TYPE wait_status;
9309 WAIT_STATUS_INT(wait_status) = status;
9310 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009311}
9312#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009313#endif /* HAVE_SYS_WAIT_H */
9314
9315
Thomas Wouters477c8d52006-05-27 19:21:47 +00009316#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009317#ifdef _SCO_DS
9318/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9319 needed definitions in sys/statvfs.h */
9320#define _SVID3
9321#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009322#include <sys/statvfs.h>
9323
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009324static PyObject*
9325_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009326 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9327 if (v == NULL)
9328 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009329
9330#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9332 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9333 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9334 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9335 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9336 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9337 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9338 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9339 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9340 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009341#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009342 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9343 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9344 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009345 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009346 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009347 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009348 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009349 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009351 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009353 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009354 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009355 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9357 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009358#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009359 if (PyErr_Occurred()) {
9360 Py_DECREF(v);
9361 return NULL;
9362 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009363
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009365}
9366
Larry Hastings2f936352014-08-05 14:04:04 +10009367
9368/*[clinic input]
9369os.fstatvfs
9370 fd: int
9371 /
9372
9373Perform an fstatvfs system call on the given fd.
9374
9375Equivalent to statvfs(fd).
9376[clinic start generated code]*/
9377
Larry Hastings2f936352014-08-05 14:04:04 +10009378static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009379os_fstatvfs_impl(PyObject *module, int fd)
9380/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009381{
9382 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009383 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009385
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009386 do {
9387 Py_BEGIN_ALLOW_THREADS
9388 result = fstatvfs(fd, &st);
9389 Py_END_ALLOW_THREADS
9390 } while (result != 0 && errno == EINTR &&
9391 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009392 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009393 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009394
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009396}
Larry Hastings2f936352014-08-05 14:04:04 +10009397#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009398
9399
Thomas Wouters477c8d52006-05-27 19:21:47 +00009400#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009401#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009402/*[clinic input]
9403os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009404
Larry Hastings2f936352014-08-05 14:04:04 +10009405 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9406
9407Perform a statvfs system call on the given path.
9408
9409path may always be specified as a string.
9410On some platforms, path may also be specified as an open file descriptor.
9411 If this functionality is unavailable, using it raises an exception.
9412[clinic start generated code]*/
9413
Larry Hastings2f936352014-08-05 14:04:04 +10009414static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009415os_statvfs_impl(PyObject *module, path_t *path)
9416/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009417{
9418 int result;
9419 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009420
9421 Py_BEGIN_ALLOW_THREADS
9422#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009423 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009424#ifdef __APPLE__
9425 /* handle weak-linking on Mac OS X 10.3 */
9426 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009427 fd_specified("statvfs", path->fd);
9428 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009429 }
9430#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009431 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009432 }
9433 else
9434#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009435 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009436 Py_END_ALLOW_THREADS
9437
9438 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009439 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009440 }
9441
Larry Hastings2f936352014-08-05 14:04:04 +10009442 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009443}
Larry Hastings2f936352014-08-05 14:04:04 +10009444#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9445
Guido van Rossum94f6f721999-01-06 18:42:14 +00009446
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009447#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009448/*[clinic input]
9449os._getdiskusage
9450
9451 path: Py_UNICODE
9452
9453Return disk usage statistics about the given path as a (total, free) tuple.
9454[clinic start generated code]*/
9455
Larry Hastings2f936352014-08-05 14:04:04 +10009456static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009457os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9458/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009459{
9460 BOOL retval;
9461 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009462
9463 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009464 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009465 Py_END_ALLOW_THREADS
9466 if (retval == 0)
9467 return PyErr_SetFromWindowsErr(0);
9468
9469 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9470}
Larry Hastings2f936352014-08-05 14:04:04 +10009471#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009472
9473
Fred Drakec9680921999-12-13 16:37:25 +00009474/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9475 * It maps strings representing configuration variable names to
9476 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009477 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009478 * rarely-used constants. There are three separate tables that use
9479 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009480 *
9481 * This code is always included, even if none of the interfaces that
9482 * need it are included. The #if hackery needed to avoid it would be
9483 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009484 */
9485struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009486 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009487 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009488};
9489
Fred Drake12c6e2d1999-12-14 21:25:03 +00009490static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009491conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009492 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009493{
Christian Heimes217cfd12007-12-02 14:31:20 +00009494 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009495 int value = _PyLong_AsInt(arg);
9496 if (value == -1 && PyErr_Occurred())
9497 return 0;
9498 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009499 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009500 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009501 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009502 /* look up the value in the table using a binary search */
9503 size_t lo = 0;
9504 size_t mid;
9505 size_t hi = tablesize;
9506 int cmp;
9507 const char *confname;
9508 if (!PyUnicode_Check(arg)) {
9509 PyErr_SetString(PyExc_TypeError,
9510 "configuration names must be strings or integers");
9511 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009513 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009514 if (confname == NULL)
9515 return 0;
9516 while (lo < hi) {
9517 mid = (lo + hi) / 2;
9518 cmp = strcmp(confname, table[mid].name);
9519 if (cmp < 0)
9520 hi = mid;
9521 else if (cmp > 0)
9522 lo = mid + 1;
9523 else {
9524 *valuep = table[mid].value;
9525 return 1;
9526 }
9527 }
9528 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9529 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009531}
9532
9533
9534#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9535static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009536#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009538#endif
9539#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009541#endif
Fred Drakec9680921999-12-13 16:37:25 +00009542#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009544#endif
9545#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009547#endif
9548#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009550#endif
9551#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009553#endif
9554#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009556#endif
9557#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009559#endif
9560#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009562#endif
9563#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009565#endif
9566#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009568#endif
9569#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009571#endif
9572#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009574#endif
9575#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009577#endif
9578#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009580#endif
9581#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009583#endif
9584#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009586#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009587#ifdef _PC_ACL_ENABLED
9588 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9589#endif
9590#ifdef _PC_MIN_HOLE_SIZE
9591 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9592#endif
9593#ifdef _PC_ALLOC_SIZE_MIN
9594 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9595#endif
9596#ifdef _PC_REC_INCR_XFER_SIZE
9597 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9598#endif
9599#ifdef _PC_REC_MAX_XFER_SIZE
9600 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9601#endif
9602#ifdef _PC_REC_MIN_XFER_SIZE
9603 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9604#endif
9605#ifdef _PC_REC_XFER_ALIGN
9606 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9607#endif
9608#ifdef _PC_SYMLINK_MAX
9609 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9610#endif
9611#ifdef _PC_XATTR_ENABLED
9612 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9613#endif
9614#ifdef _PC_XATTR_EXISTS
9615 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9616#endif
9617#ifdef _PC_TIMESTAMP_RESOLUTION
9618 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9619#endif
Fred Drakec9680921999-12-13 16:37:25 +00009620};
9621
Fred Drakec9680921999-12-13 16:37:25 +00009622static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009623conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009624{
9625 return conv_confname(arg, valuep, posix_constants_pathconf,
9626 sizeof(posix_constants_pathconf)
9627 / sizeof(struct constdef));
9628}
9629#endif
9630
Larry Hastings2f936352014-08-05 14:04:04 +10009631
Fred Drakec9680921999-12-13 16:37:25 +00009632#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009633/*[clinic input]
9634os.fpathconf -> long
9635
9636 fd: int
9637 name: path_confname
9638 /
9639
9640Return the configuration limit name for the file descriptor fd.
9641
9642If there is no limit, return -1.
9643[clinic start generated code]*/
9644
Larry Hastings2f936352014-08-05 14:04:04 +10009645static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009646os_fpathconf_impl(PyObject *module, int fd, int name)
9647/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009648{
9649 long limit;
9650
9651 errno = 0;
9652 limit = fpathconf(fd, name);
9653 if (limit == -1 && errno != 0)
9654 posix_error();
9655
9656 return limit;
9657}
9658#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009659
9660
9661#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009662/*[clinic input]
9663os.pathconf -> long
9664 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9665 name: path_confname
9666
9667Return the configuration limit name for the file or directory path.
9668
9669If there is no limit, return -1.
9670On some platforms, path may also be specified as an open file descriptor.
9671 If this functionality is unavailable, using it raises an exception.
9672[clinic start generated code]*/
9673
Larry Hastings2f936352014-08-05 14:04:04 +10009674static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009675os_pathconf_impl(PyObject *module, path_t *path, int name)
9676/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009677{
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009679
Victor Stinner8c62be82010-05-06 00:08:46 +00009680 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009681#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009682 if (path->fd != -1)
9683 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009684 else
9685#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009686 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 if (limit == -1 && errno != 0) {
9688 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009689 /* could be a path or name problem */
9690 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009691 else
Larry Hastings2f936352014-08-05 14:04:04 +10009692 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 }
Larry Hastings2f936352014-08-05 14:04:04 +10009694
9695 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009696}
Larry Hastings2f936352014-08-05 14:04:04 +10009697#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009698
9699#ifdef HAVE_CONFSTR
9700static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009701#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009703#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009704#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009706#endif
9707#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009709#endif
Fred Draked86ed291999-12-15 15:34:33 +00009710#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009712#endif
9713#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009715#endif
9716#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009718#endif
9719#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009721#endif
Fred Drakec9680921999-12-13 16:37:25 +00009722#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009724#endif
9725#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
Fred Draked86ed291999-12-15 15:34:33 +00009746#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009748#endif
Fred Drakec9680921999-12-13 16:37:25 +00009749#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
Fred Draked86ed291999-12-15 15:34:33 +00009752#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009754#endif
9755#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009757#endif
9758#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009760#endif
9761#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009763#endif
Fred Drakec9680921999-12-13 16:37:25 +00009764#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
Fred Draked86ed291999-12-15 15:34:33 +00009812#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009814#endif
9815#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009817#endif
9818#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009820#endif
9821#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009823#endif
9824#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009826#endif
9827#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009829#endif
9830#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009832#endif
9833#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009835#endif
9836#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009838#endif
9839#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009841#endif
9842#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009844#endif
9845#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009847#endif
9848#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009850#endif
Fred Drakec9680921999-12-13 16:37:25 +00009851};
9852
9853static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009854conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009855{
9856 return conv_confname(arg, valuep, posix_constants_confstr,
9857 sizeof(posix_constants_confstr)
9858 / sizeof(struct constdef));
9859}
9860
Larry Hastings2f936352014-08-05 14:04:04 +10009861
9862/*[clinic input]
9863os.confstr
9864
9865 name: confstr_confname
9866 /
9867
9868Return a string-valued system configuration variable.
9869[clinic start generated code]*/
9870
Larry Hastings2f936352014-08-05 14:04:04 +10009871static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009872os_confstr_impl(PyObject *module, int name)
9873/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009874{
9875 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009876 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009877 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009878
Victor Stinnercb043522010-09-10 23:49:04 +00009879 errno = 0;
9880 len = confstr(name, buffer, sizeof(buffer));
9881 if (len == 0) {
9882 if (errno) {
9883 posix_error();
9884 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009885 }
9886 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009887 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009888 }
9889 }
Victor Stinnercb043522010-09-10 23:49:04 +00009890
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009891 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009892 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009893 char *buf = PyMem_Malloc(len);
9894 if (buf == NULL)
9895 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009896 len2 = confstr(name, buf, len);
9897 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009898 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009899 PyMem_Free(buf);
9900 }
9901 else
9902 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009903 return result;
9904}
Larry Hastings2f936352014-08-05 14:04:04 +10009905#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009906
9907
9908#ifdef HAVE_SYSCONF
9909static struct constdef posix_constants_sysconf[] = {
9910#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009912#endif
9913#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009915#endif
9916#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
9937#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
Fred Draked86ed291999-12-15 15:34:33 +00009940#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009942#endif
9943#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009945#endif
Fred Drakec9680921999-12-13 16:37:25 +00009946#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
Fred Drakec9680921999-12-13 16:37:25 +00009949#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009951#endif
9952#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
9955#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
9961#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
Fred Draked86ed291999-12-15 15:34:33 +00009964#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009966#endif
Fred Drakec9680921999-12-13 16:37:25 +00009967#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009969#endif
9970#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
9979#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009981#endif
Fred Draked86ed291999-12-15 15:34:33 +00009982#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009984#endif
Fred Drakec9680921999-12-13 16:37:25 +00009985#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009987#endif
9988#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
9991#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
9997#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009999#endif
10000#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
10018#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
10021#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010023#endif
10024#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010026#endif
10027#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
10033#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
10036#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
10039#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010041#endif
10042#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010044#endif
10045#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
10048#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
10051#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010053#endif
Fred Draked86ed291999-12-15 15:34:33 +000010054#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010056#endif
Fred Drakec9680921999-12-13 16:37:25 +000010057#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010059#endif
10060#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
10063#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010065#endif
Fred Draked86ed291999-12-15 15:34:33 +000010066#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010068#endif
Fred Drakec9680921999-12-13 16:37:25 +000010069#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010071#endif
Fred Draked86ed291999-12-15 15:34:33 +000010072#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010074#endif
10075#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010077#endif
Fred Drakec9680921999-12-13 16:37:25 +000010078#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010080#endif
10081#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010083#endif
10084#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010086#endif
10087#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010089#endif
Fred Draked86ed291999-12-15 15:34:33 +000010090#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010092#endif
Fred Drakec9680921999-12-13 16:37:25 +000010093#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010095#endif
10096#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
10105#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010107#endif
10108#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
10111#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
Fred Draked86ed291999-12-15 15:34:33 +000010114#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010116#endif
Fred Drakec9680921999-12-13 16:37:25 +000010117#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
10120#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
Fred Draked86ed291999-12-15 15:34:33 +000010123#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010125#endif
Fred Drakec9680921999-12-13 16:37:25 +000010126#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
10129#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
Fred Draked86ed291999-12-15 15:34:33 +000010153#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010155#endif
10156#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010158#endif
Fred Drakec9680921999-12-13 16:37:25 +000010159#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
10162#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
10168#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
10234#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
10258#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010260#endif
10261#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010263#endif
Fred Draked86ed291999-12-15 15:34:33 +000010264#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010266#endif
Fred Drakec9680921999-12-13 16:37:25 +000010267#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010269#endif
10270#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010272#endif
10273#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010275#endif
10276#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010278#endif
10279#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010281#endif
10282#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010284#endif
10285#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010287#endif
10288#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010290#endif
10291#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010293#endif
10294#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010296#endif
10297#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
10303#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010305#endif
10306#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
10309#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
10327#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010329#endif
10330#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
10336#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
10339#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
10342#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010344#endif
10345#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010347#endif
10348#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010350#endif
10351#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010353#endif
10354#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010356#endif
10357#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010359#endif
10360#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010361 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010362#endif
10363#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010365#endif
10366#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010368#endif
10369#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010371#endif
10372#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010374#endif
10375#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010377#endif
10378#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010380#endif
10381#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010383#endif
10384#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010386#endif
10387#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010389#endif
10390#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010392#endif
10393#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010394 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010395#endif
10396#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010397 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010398#endif
10399#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010400 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010401#endif
10402};
10403
10404static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010405conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010406{
10407 return conv_confname(arg, valuep, posix_constants_sysconf,
10408 sizeof(posix_constants_sysconf)
10409 / sizeof(struct constdef));
10410}
10411
Larry Hastings2f936352014-08-05 14:04:04 +100010412
10413/*[clinic input]
10414os.sysconf -> long
10415 name: sysconf_confname
10416 /
10417
10418Return an integer-valued system configuration variable.
10419[clinic start generated code]*/
10420
Larry Hastings2f936352014-08-05 14:04:04 +100010421static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010422os_sysconf_impl(PyObject *module, int name)
10423/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010424{
10425 long value;
10426
10427 errno = 0;
10428 value = sysconf(name);
10429 if (value == -1 && errno != 0)
10430 posix_error();
10431 return value;
10432}
10433#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010434
10435
Fred Drakebec628d1999-12-15 18:31:10 +000010436/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010437 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010438 * the exported dictionaries that are used to publish information about the
10439 * names available on the host platform.
10440 *
10441 * Sorting the table at runtime ensures that the table is properly ordered
10442 * when used, even for platforms we're not able to test on. It also makes
10443 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010444 */
Fred Drakebec628d1999-12-15 18:31:10 +000010445
10446static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010447cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010448{
10449 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010450 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010451 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010452 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010453
10454 return strcmp(c1->name, c2->name);
10455}
10456
10457static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010458setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010459 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010460{
Fred Drakebec628d1999-12-15 18:31:10 +000010461 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010462 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010463
10464 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10465 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010466 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010468
Barry Warsaw3155db32000-04-13 15:20:40 +000010469 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 PyObject *o = PyLong_FromLong(table[i].value);
10471 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10472 Py_XDECREF(o);
10473 Py_DECREF(d);
10474 return -1;
10475 }
10476 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010477 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010478 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010479}
10480
Fred Drakebec628d1999-12-15 18:31:10 +000010481/* Return -1 on failure, 0 on success. */
10482static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010483setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010484{
10485#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010486 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010487 sizeof(posix_constants_pathconf)
10488 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010489 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010490 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010491#endif
10492#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010493 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010494 sizeof(posix_constants_confstr)
10495 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010496 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010497 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010498#endif
10499#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010500 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010501 sizeof(posix_constants_sysconf)
10502 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010503 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010504 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010505#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010506 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010507}
Fred Draked86ed291999-12-15 15:34:33 +000010508
10509
Larry Hastings2f936352014-08-05 14:04:04 +100010510/*[clinic input]
10511os.abort
10512
10513Abort the interpreter immediately.
10514
10515This function 'dumps core' or otherwise fails in the hardest way possible
10516on the hosting operating system. This function never returns.
10517[clinic start generated code]*/
10518
Larry Hastings2f936352014-08-05 14:04:04 +100010519static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010520os_abort_impl(PyObject *module)
10521/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010522{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010523 abort();
10524 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010525#ifndef __clang__
10526 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10527 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10528 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010529 Py_FatalError("abort() called from Python code didn't abort!");
10530 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010531#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010532}
Fred Drakebec628d1999-12-15 18:31:10 +000010533
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010534#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010535/* Grab ShellExecute dynamically from shell32 */
10536static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010537static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10538 LPCWSTR, INT);
10539static int
10540check_ShellExecute()
10541{
10542 HINSTANCE hShell32;
10543
10544 /* only recheck */
10545 if (-1 == has_ShellExecute) {
10546 Py_BEGIN_ALLOW_THREADS
10547 hShell32 = LoadLibraryW(L"SHELL32");
10548 Py_END_ALLOW_THREADS
10549 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010550 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10551 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010552 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010553 } else {
10554 has_ShellExecute = 0;
10555 }
10556 }
10557 return has_ShellExecute;
10558}
10559
10560
Steve Dowercc16be82016-09-08 10:35:16 -070010561/*[clinic input]
10562os.startfile
10563 filepath: path_t
10564 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010565
Steve Dowercc16be82016-09-08 10:35:16 -070010566startfile(filepath [, operation])
10567
10568Start a file with its associated application.
10569
10570When "operation" is not specified or "open", this acts like
10571double-clicking the file in Explorer, or giving the file name as an
10572argument to the DOS "start" command: the file is opened with whatever
10573application (if any) its extension is associated.
10574When another "operation" is given, it specifies what should be done with
10575the file. A typical operation is "print".
10576
10577startfile returns as soon as the associated application is launched.
10578There is no option to wait for the application to close, and no way
10579to retrieve the application's exit status.
10580
10581The filepath is relative to the current directory. If you want to use
10582an absolute path, make sure the first character is not a slash ("/");
10583the underlying Win32 ShellExecute function doesn't work if it is.
10584[clinic start generated code]*/
10585
10586static PyObject *
10587os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10588/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10589{
10590 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010591
10592 if(!check_ShellExecute()) {
10593 /* If the OS doesn't have ShellExecute, return a
10594 NotImplementedError. */
10595 return PyErr_Format(PyExc_NotImplementedError,
10596 "startfile not available on this platform");
10597 }
10598
Victor Stinner8c62be82010-05-06 00:08:46 +000010599 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010600 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010601 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010602 Py_END_ALLOW_THREADS
10603
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010605 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010606 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 }
Steve Dowercc16be82016-09-08 10:35:16 -070010608 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010609}
Larry Hastings2f936352014-08-05 14:04:04 +100010610#endif /* MS_WINDOWS */
10611
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010612
Martin v. Löwis438b5342002-12-27 10:16:42 +000010613#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010614/*[clinic input]
10615os.getloadavg
10616
10617Return average recent system load information.
10618
10619Return the number of processes in the system run queue averaged over
10620the last 1, 5, and 15 minutes as a tuple of three floats.
10621Raises OSError if the load average was unobtainable.
10622[clinic start generated code]*/
10623
Larry Hastings2f936352014-08-05 14:04:04 +100010624static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010625os_getloadavg_impl(PyObject *module)
10626/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010627{
10628 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010629 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010630 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10631 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010632 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010633 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010634}
Larry Hastings2f936352014-08-05 14:04:04 +100010635#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010636
Larry Hastings2f936352014-08-05 14:04:04 +100010637
10638/*[clinic input]
10639os.device_encoding
10640 fd: int
10641
10642Return a string describing the encoding of a terminal's file descriptor.
10643
10644The file descriptor must be attached to a terminal.
10645If the device is not a terminal, return None.
10646[clinic start generated code]*/
10647
Larry Hastings2f936352014-08-05 14:04:04 +100010648static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010649os_device_encoding_impl(PyObject *module, int fd)
10650/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010651{
Brett Cannonefb00c02012-02-29 18:31:31 -050010652 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010653}
10654
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010655
Larry Hastings2f936352014-08-05 14:04:04 +100010656#ifdef HAVE_SETRESUID
10657/*[clinic input]
10658os.setresuid
10659
10660 ruid: uid_t
10661 euid: uid_t
10662 suid: uid_t
10663 /
10664
10665Set the current process's real, effective, and saved user ids.
10666[clinic start generated code]*/
10667
Larry Hastings2f936352014-08-05 14:04:04 +100010668static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010669os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10670/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010671{
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 if (setresuid(ruid, euid, suid) < 0)
10673 return posix_error();
10674 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010675}
Larry Hastings2f936352014-08-05 14:04:04 +100010676#endif /* HAVE_SETRESUID */
10677
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010678
10679#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010680/*[clinic input]
10681os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010682
Larry Hastings2f936352014-08-05 14:04:04 +100010683 rgid: gid_t
10684 egid: gid_t
10685 sgid: gid_t
10686 /
10687
10688Set the current process's real, effective, and saved group ids.
10689[clinic start generated code]*/
10690
Larry Hastings2f936352014-08-05 14:04:04 +100010691static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010692os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10693/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010694{
Victor Stinner8c62be82010-05-06 00:08:46 +000010695 if (setresgid(rgid, egid, sgid) < 0)
10696 return posix_error();
10697 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010698}
Larry Hastings2f936352014-08-05 14:04:04 +100010699#endif /* HAVE_SETRESGID */
10700
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010701
10702#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010703/*[clinic input]
10704os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010705
Larry Hastings2f936352014-08-05 14:04:04 +100010706Return a tuple of the current process's real, effective, and saved user ids.
10707[clinic start generated code]*/
10708
Larry Hastings2f936352014-08-05 14:04:04 +100010709static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010710os_getresuid_impl(PyObject *module)
10711/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010712{
Victor Stinner8c62be82010-05-06 00:08:46 +000010713 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 if (getresuid(&ruid, &euid, &suid) < 0)
10715 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010716 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10717 _PyLong_FromUid(euid),
10718 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010719}
Larry Hastings2f936352014-08-05 14:04:04 +100010720#endif /* HAVE_GETRESUID */
10721
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010722
10723#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010724/*[clinic input]
10725os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010726
Larry Hastings2f936352014-08-05 14:04:04 +100010727Return a tuple of the current process's real, effective, and saved group ids.
10728[clinic start generated code]*/
10729
Larry Hastings2f936352014-08-05 14:04:04 +100010730static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010731os_getresgid_impl(PyObject *module)
10732/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010733{
10734 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 if (getresgid(&rgid, &egid, &sgid) < 0)
10736 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010737 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10738 _PyLong_FromGid(egid),
10739 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010740}
Larry Hastings2f936352014-08-05 14:04:04 +100010741#endif /* HAVE_GETRESGID */
10742
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010743
Benjamin Peterson9428d532011-09-14 11:45:52 -040010744#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010745/*[clinic input]
10746os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010747
Larry Hastings2f936352014-08-05 14:04:04 +100010748 path: path_t(allow_fd=True)
10749 attribute: path_t
10750 *
10751 follow_symlinks: bool = True
10752
10753Return the value of extended attribute attribute on path.
10754
10755path may be either a string or an open file descriptor.
10756If follow_symlinks is False, and the last element of the path is a symbolic
10757 link, getxattr will examine the symbolic link itself instead of the file
10758 the link points to.
10759
10760[clinic start generated code]*/
10761
Larry Hastings2f936352014-08-05 14:04:04 +100010762static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010763os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010764 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010765/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010766{
10767 Py_ssize_t i;
10768 PyObject *buffer = NULL;
10769
10770 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10771 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010772
Larry Hastings9cf065c2012-06-22 16:30:09 -070010773 for (i = 0; ; i++) {
10774 void *ptr;
10775 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010776 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010777 Py_ssize_t buffer_size = buffer_sizes[i];
10778 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010779 path_error(path);
10780 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010781 }
10782 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10783 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010784 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010785 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010786
Larry Hastings9cf065c2012-06-22 16:30:09 -070010787 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010788 if (path->fd >= 0)
10789 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010790 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010791 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010792 else
Larry Hastings2f936352014-08-05 14:04:04 +100010793 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010794 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010795
Larry Hastings9cf065c2012-06-22 16:30:09 -070010796 if (result < 0) {
10797 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010798 if (errno == ERANGE)
10799 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010800 path_error(path);
10801 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010802 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010803
Larry Hastings9cf065c2012-06-22 16:30:09 -070010804 if (result != buffer_size) {
10805 /* Can only shrink. */
10806 _PyBytes_Resize(&buffer, result);
10807 }
10808 break;
10809 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010810
Larry Hastings9cf065c2012-06-22 16:30:09 -070010811 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010812}
10813
Larry Hastings2f936352014-08-05 14:04:04 +100010814
10815/*[clinic input]
10816os.setxattr
10817
10818 path: path_t(allow_fd=True)
10819 attribute: path_t
10820 value: Py_buffer
10821 flags: int = 0
10822 *
10823 follow_symlinks: bool = True
10824
10825Set extended attribute attribute on path to value.
10826
10827path may be either a string or an open file descriptor.
10828If follow_symlinks is False, and the last element of the path is a symbolic
10829 link, setxattr will modify the symbolic link itself instead of the file
10830 the link points to.
10831
10832[clinic start generated code]*/
10833
Benjamin Peterson799bd802011-08-31 22:15:17 -040010834static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010835os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010836 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010837/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010838{
Larry Hastings2f936352014-08-05 14:04:04 +100010839 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010840
Larry Hastings2f936352014-08-05 14:04:04 +100010841 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010842 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010843
Benjamin Peterson799bd802011-08-31 22:15:17 -040010844 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010845 if (path->fd > -1)
10846 result = fsetxattr(path->fd, attribute->narrow,
10847 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010848 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010849 result = setxattr(path->narrow, attribute->narrow,
10850 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010851 else
Larry Hastings2f936352014-08-05 14:04:04 +100010852 result = lsetxattr(path->narrow, attribute->narrow,
10853 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010854 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010855
Larry Hastings9cf065c2012-06-22 16:30:09 -070010856 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010857 path_error(path);
10858 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010859 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010860
Larry Hastings2f936352014-08-05 14:04:04 +100010861 Py_RETURN_NONE;
10862}
10863
10864
10865/*[clinic input]
10866os.removexattr
10867
10868 path: path_t(allow_fd=True)
10869 attribute: path_t
10870 *
10871 follow_symlinks: bool = True
10872
10873Remove extended attribute attribute on path.
10874
10875path may be either a string or an open file descriptor.
10876If follow_symlinks is False, and the last element of the path is a symbolic
10877 link, removexattr will modify the symbolic link itself instead of the file
10878 the link points to.
10879
10880[clinic start generated code]*/
10881
Larry Hastings2f936352014-08-05 14:04:04 +100010882static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010883os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010884 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010885/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010886{
10887 ssize_t result;
10888
10889 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10890 return NULL;
10891
10892 Py_BEGIN_ALLOW_THREADS;
10893 if (path->fd > -1)
10894 result = fremovexattr(path->fd, attribute->narrow);
10895 else if (follow_symlinks)
10896 result = removexattr(path->narrow, attribute->narrow);
10897 else
10898 result = lremovexattr(path->narrow, attribute->narrow);
10899 Py_END_ALLOW_THREADS;
10900
10901 if (result) {
10902 return path_error(path);
10903 }
10904
10905 Py_RETURN_NONE;
10906}
10907
10908
10909/*[clinic input]
10910os.listxattr
10911
10912 path: path_t(allow_fd=True, nullable=True) = None
10913 *
10914 follow_symlinks: bool = True
10915
10916Return a list of extended attributes on path.
10917
10918path may be either None, a string, or an open file descriptor.
10919if path is None, listxattr will examine the current directory.
10920If follow_symlinks is False, and the last element of the path is a symbolic
10921 link, listxattr will examine the symbolic link itself instead of the file
10922 the link points to.
10923[clinic start generated code]*/
10924
Larry Hastings2f936352014-08-05 14:04:04 +100010925static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010926os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10927/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010928{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010929 Py_ssize_t i;
10930 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010931 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010932 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010933
Larry Hastings2f936352014-08-05 14:04:04 +100010934 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010935 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010936
Larry Hastings2f936352014-08-05 14:04:04 +100010937 name = path->narrow ? path->narrow : ".";
10938
Larry Hastings9cf065c2012-06-22 16:30:09 -070010939 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010940 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010941 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010942 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010943 Py_ssize_t buffer_size = buffer_sizes[i];
10944 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010945 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010946 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010947 break;
10948 }
10949 buffer = PyMem_MALLOC(buffer_size);
10950 if (!buffer) {
10951 PyErr_NoMemory();
10952 break;
10953 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010954
Larry Hastings9cf065c2012-06-22 16:30:09 -070010955 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010956 if (path->fd > -1)
10957 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010958 else if (follow_symlinks)
10959 length = listxattr(name, buffer, buffer_size);
10960 else
10961 length = llistxattr(name, buffer, buffer_size);
10962 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010963
Larry Hastings9cf065c2012-06-22 16:30:09 -070010964 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010965 if (errno == ERANGE) {
10966 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010967 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010968 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010969 }
Larry Hastings2f936352014-08-05 14:04:04 +100010970 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010971 break;
10972 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010973
Larry Hastings9cf065c2012-06-22 16:30:09 -070010974 result = PyList_New(0);
10975 if (!result) {
10976 goto exit;
10977 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010978
Larry Hastings9cf065c2012-06-22 16:30:09 -070010979 end = buffer + length;
10980 for (trace = start = buffer; trace != end; trace++) {
10981 if (!*trace) {
10982 int error;
10983 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10984 trace - start);
10985 if (!attribute) {
10986 Py_DECREF(result);
10987 result = NULL;
10988 goto exit;
10989 }
10990 error = PyList_Append(result, attribute);
10991 Py_DECREF(attribute);
10992 if (error) {
10993 Py_DECREF(result);
10994 result = NULL;
10995 goto exit;
10996 }
10997 start = trace + 1;
10998 }
10999 }
11000 break;
11001 }
11002exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011003 if (buffer)
11004 PyMem_FREE(buffer);
11005 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011006}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011007#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011008
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011009
Larry Hastings2f936352014-08-05 14:04:04 +100011010/*[clinic input]
11011os.urandom
11012
11013 size: Py_ssize_t
11014 /
11015
11016Return a bytes object containing random bytes suitable for cryptographic use.
11017[clinic start generated code]*/
11018
Larry Hastings2f936352014-08-05 14:04:04 +100011019static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011020os_urandom_impl(PyObject *module, Py_ssize_t size)
11021/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011022{
11023 PyObject *bytes;
11024 int result;
11025
Georg Brandl2fb477c2012-02-21 00:33:36 +010011026 if (size < 0)
11027 return PyErr_Format(PyExc_ValueError,
11028 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011029 bytes = PyBytes_FromStringAndSize(NULL, size);
11030 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011031 return NULL;
11032
Victor Stinnere66987e2016-09-06 16:33:52 -070011033 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011034 if (result == -1) {
11035 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011036 return NULL;
11037 }
Larry Hastings2f936352014-08-05 14:04:04 +100011038 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011039}
11040
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011041/* Terminal size querying */
11042
11043static PyTypeObject TerminalSizeType;
11044
11045PyDoc_STRVAR(TerminalSize_docstring,
11046 "A tuple of (columns, lines) for holding terminal window size");
11047
11048static PyStructSequence_Field TerminalSize_fields[] = {
11049 {"columns", "width of the terminal window in characters"},
11050 {"lines", "height of the terminal window in characters"},
11051 {NULL, NULL}
11052};
11053
11054static PyStructSequence_Desc TerminalSize_desc = {
11055 "os.terminal_size",
11056 TerminalSize_docstring,
11057 TerminalSize_fields,
11058 2,
11059};
11060
11061#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011062/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011063PyDoc_STRVAR(termsize__doc__,
11064 "Return the size of the terminal window as (columns, lines).\n" \
11065 "\n" \
11066 "The optional argument fd (default standard output) specifies\n" \
11067 "which file descriptor should be queried.\n" \
11068 "\n" \
11069 "If the file descriptor is not connected to a terminal, an OSError\n" \
11070 "is thrown.\n" \
11071 "\n" \
11072 "This function will only be defined if an implementation is\n" \
11073 "available for this system.\n" \
11074 "\n" \
11075 "shutil.get_terminal_size is the high-level function which should \n" \
11076 "normally be used, os.get_terminal_size is the low-level implementation.");
11077
11078static PyObject*
11079get_terminal_size(PyObject *self, PyObject *args)
11080{
11081 int columns, lines;
11082 PyObject *termsize;
11083
11084 int fd = fileno(stdout);
11085 /* Under some conditions stdout may not be connected and
11086 * fileno(stdout) may point to an invalid file descriptor. For example
11087 * GUI apps don't have valid standard streams by default.
11088 *
11089 * If this happens, and the optional fd argument is not present,
11090 * the ioctl below will fail returning EBADF. This is what we want.
11091 */
11092
11093 if (!PyArg_ParseTuple(args, "|i", &fd))
11094 return NULL;
11095
11096#ifdef TERMSIZE_USE_IOCTL
11097 {
11098 struct winsize w;
11099 if (ioctl(fd, TIOCGWINSZ, &w))
11100 return PyErr_SetFromErrno(PyExc_OSError);
11101 columns = w.ws_col;
11102 lines = w.ws_row;
11103 }
11104#endif /* TERMSIZE_USE_IOCTL */
11105
11106#ifdef TERMSIZE_USE_CONIO
11107 {
11108 DWORD nhandle;
11109 HANDLE handle;
11110 CONSOLE_SCREEN_BUFFER_INFO csbi;
11111 switch (fd) {
11112 case 0: nhandle = STD_INPUT_HANDLE;
11113 break;
11114 case 1: nhandle = STD_OUTPUT_HANDLE;
11115 break;
11116 case 2: nhandle = STD_ERROR_HANDLE;
11117 break;
11118 default:
11119 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11120 }
11121 handle = GetStdHandle(nhandle);
11122 if (handle == NULL)
11123 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11124 if (handle == INVALID_HANDLE_VALUE)
11125 return PyErr_SetFromWindowsErr(0);
11126
11127 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11128 return PyErr_SetFromWindowsErr(0);
11129
11130 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11131 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11132 }
11133#endif /* TERMSIZE_USE_CONIO */
11134
11135 termsize = PyStructSequence_New(&TerminalSizeType);
11136 if (termsize == NULL)
11137 return NULL;
11138 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11139 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11140 if (PyErr_Occurred()) {
11141 Py_DECREF(termsize);
11142 return NULL;
11143 }
11144 return termsize;
11145}
11146#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11147
Larry Hastings2f936352014-08-05 14:04:04 +100011148
11149/*[clinic input]
11150os.cpu_count
11151
Charles-François Natali80d62e62015-08-13 20:37:08 +010011152Return the number of CPUs in the system; return None if indeterminable.
11153
11154This number is not equivalent to the number of CPUs the current process can
11155use. The number of usable CPUs can be obtained with
11156``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011157[clinic start generated code]*/
11158
Larry Hastings2f936352014-08-05 14:04:04 +100011159static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011160os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011161/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011162{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011163 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011164#ifdef MS_WINDOWS
11165 SYSTEM_INFO sysinfo;
11166 GetSystemInfo(&sysinfo);
11167 ncpu = sysinfo.dwNumberOfProcessors;
11168#elif defined(__hpux)
11169 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11170#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11171 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011172#elif defined(__DragonFly__) || \
11173 defined(__OpenBSD__) || \
11174 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011175 defined(__NetBSD__) || \
11176 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011177 int mib[2];
11178 size_t len = sizeof(ncpu);
11179 mib[0] = CTL_HW;
11180 mib[1] = HW_NCPU;
11181 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11182 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011183#endif
11184 if (ncpu >= 1)
11185 return PyLong_FromLong(ncpu);
11186 else
11187 Py_RETURN_NONE;
11188}
11189
Victor Stinnerdaf45552013-08-28 00:53:59 +020011190
Larry Hastings2f936352014-08-05 14:04:04 +100011191/*[clinic input]
11192os.get_inheritable -> bool
11193
11194 fd: int
11195 /
11196
11197Get the close-on-exe flag of the specified file descriptor.
11198[clinic start generated code]*/
11199
Larry Hastings2f936352014-08-05 14:04:04 +100011200static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011201os_get_inheritable_impl(PyObject *module, int fd)
11202/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011203{
Steve Dower8fc89802015-04-12 00:26:27 -040011204 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011205 _Py_BEGIN_SUPPRESS_IPH
11206 return_value = _Py_get_inheritable(fd);
11207 _Py_END_SUPPRESS_IPH
11208 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011209}
11210
11211
11212/*[clinic input]
11213os.set_inheritable
11214 fd: int
11215 inheritable: int
11216 /
11217
11218Set the inheritable flag of the specified file descriptor.
11219[clinic start generated code]*/
11220
Larry Hastings2f936352014-08-05 14:04:04 +100011221static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011222os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11223/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011224{
Steve Dower8fc89802015-04-12 00:26:27 -040011225 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011226
Steve Dower8fc89802015-04-12 00:26:27 -040011227 _Py_BEGIN_SUPPRESS_IPH
11228 result = _Py_set_inheritable(fd, inheritable, NULL);
11229 _Py_END_SUPPRESS_IPH
11230 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011231 return NULL;
11232 Py_RETURN_NONE;
11233}
11234
11235
11236#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011237/*[clinic input]
11238os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011239 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011240 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011241
Larry Hastings2f936352014-08-05 14:04:04 +100011242Get the close-on-exe flag of the specified file descriptor.
11243[clinic start generated code]*/
11244
Larry Hastings2f936352014-08-05 14:04:04 +100011245static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011246os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011247/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011248{
11249 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011250
11251 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11252 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011253 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011254 }
11255
Larry Hastings2f936352014-08-05 14:04:04 +100011256 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011257}
11258
Victor Stinnerdaf45552013-08-28 00:53:59 +020011259
Larry Hastings2f936352014-08-05 14:04:04 +100011260/*[clinic input]
11261os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011262 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011263 inheritable: bool
11264 /
11265
11266Set the inheritable flag of the specified handle.
11267[clinic start generated code]*/
11268
Larry Hastings2f936352014-08-05 14:04:04 +100011269static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011270os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011271 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011272/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011273{
11274 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011275 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11276 PyErr_SetFromWindowsErr(0);
11277 return NULL;
11278 }
11279 Py_RETURN_NONE;
11280}
Larry Hastings2f936352014-08-05 14:04:04 +100011281#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011282
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011283#ifndef MS_WINDOWS
11284PyDoc_STRVAR(get_blocking__doc__,
11285 "get_blocking(fd) -> bool\n" \
11286 "\n" \
11287 "Get the blocking mode of the file descriptor:\n" \
11288 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11289
11290static PyObject*
11291posix_get_blocking(PyObject *self, PyObject *args)
11292{
11293 int fd;
11294 int blocking;
11295
11296 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11297 return NULL;
11298
Steve Dower8fc89802015-04-12 00:26:27 -040011299 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011300 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011301 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011302 if (blocking < 0)
11303 return NULL;
11304 return PyBool_FromLong(blocking);
11305}
11306
11307PyDoc_STRVAR(set_blocking__doc__,
11308 "set_blocking(fd, blocking)\n" \
11309 "\n" \
11310 "Set the blocking mode of the specified file descriptor.\n" \
11311 "Set the O_NONBLOCK flag if blocking is False,\n" \
11312 "clear the O_NONBLOCK flag otherwise.");
11313
11314static PyObject*
11315posix_set_blocking(PyObject *self, PyObject *args)
11316{
Steve Dower8fc89802015-04-12 00:26:27 -040011317 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011318
11319 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11320 return NULL;
11321
Steve Dower8fc89802015-04-12 00:26:27 -040011322 _Py_BEGIN_SUPPRESS_IPH
11323 result = _Py_set_blocking(fd, blocking);
11324 _Py_END_SUPPRESS_IPH
11325 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011326 return NULL;
11327 Py_RETURN_NONE;
11328}
11329#endif /* !MS_WINDOWS */
11330
11331
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011332/*[clinic input]
11333class os.DirEntry "DirEntry *" "&DirEntryType"
11334[clinic start generated code]*/
11335/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011336
11337typedef struct {
11338 PyObject_HEAD
11339 PyObject *name;
11340 PyObject *path;
11341 PyObject *stat;
11342 PyObject *lstat;
11343#ifdef MS_WINDOWS
11344 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011345 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011346 int got_file_index;
11347#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011348#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011349 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011350#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011351 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011352 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011353#endif
11354} DirEntry;
11355
11356static void
11357DirEntry_dealloc(DirEntry *entry)
11358{
11359 Py_XDECREF(entry->name);
11360 Py_XDECREF(entry->path);
11361 Py_XDECREF(entry->stat);
11362 Py_XDECREF(entry->lstat);
11363 Py_TYPE(entry)->tp_free((PyObject *)entry);
11364}
11365
11366/* Forward reference */
11367static int
11368DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11369
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011370/*[clinic input]
11371os.DirEntry.is_symlink -> bool
11372
11373Return True if the entry is a symbolic link; cached per entry.
11374[clinic start generated code]*/
11375
Victor Stinner6036e442015-03-08 01:58:04 +010011376static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011377os_DirEntry_is_symlink_impl(DirEntry *self)
11378/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011379{
11380#ifdef MS_WINDOWS
11381 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011382#elif defined(HAVE_DIRENT_D_TYPE)
11383 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011384 if (self->d_type != DT_UNKNOWN)
11385 return self->d_type == DT_LNK;
11386 else
11387 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011388#else
11389 /* POSIX without d_type */
11390 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011391#endif
11392}
11393
11394static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011395DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11396{
11397 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011398 STRUCT_STAT st;
11399 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011400
11401#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011402 if (!PyUnicode_FSDecoder(self->path, &ub))
11403 return NULL;
11404 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011405#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011406 if (!PyUnicode_FSConverter(self->path, &ub))
11407 return NULL;
11408 const char *path = PyBytes_AS_STRING(ub);
11409 if (self->dir_fd != DEFAULT_DIR_FD) {
11410#ifdef HAVE_FSTATAT
11411 result = fstatat(self->dir_fd, path, &st,
11412 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11413#else
11414 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11415 return NULL;
11416#endif /* HAVE_FSTATAT */
11417 }
11418 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011419#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011420 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011421 if (follow_symlinks)
11422 result = STAT(path, &st);
11423 else
11424 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011425 }
11426 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011427
11428 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011429 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011430
11431 return _pystat_fromstructstat(&st);
11432}
11433
11434static PyObject *
11435DirEntry_get_lstat(DirEntry *self)
11436{
11437 if (!self->lstat) {
11438#ifdef MS_WINDOWS
11439 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11440#else /* POSIX */
11441 self->lstat = DirEntry_fetch_stat(self, 0);
11442#endif
11443 }
11444 Py_XINCREF(self->lstat);
11445 return self->lstat;
11446}
11447
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011448/*[clinic input]
11449os.DirEntry.stat
11450 *
11451 follow_symlinks: bool = True
11452
11453Return stat_result object for the entry; cached per entry.
11454[clinic start generated code]*/
11455
Victor Stinner6036e442015-03-08 01:58:04 +010011456static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011457os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11458/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011459{
11460 if (!follow_symlinks)
11461 return DirEntry_get_lstat(self);
11462
11463 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011464 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011465 if (result == -1)
11466 return NULL;
11467 else if (result)
11468 self->stat = DirEntry_fetch_stat(self, 1);
11469 else
11470 self->stat = DirEntry_get_lstat(self);
11471 }
11472
11473 Py_XINCREF(self->stat);
11474 return self->stat;
11475}
11476
Victor Stinner6036e442015-03-08 01:58:04 +010011477/* Set exception and return -1 on error, 0 for False, 1 for True */
11478static int
11479DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11480{
11481 PyObject *stat = NULL;
11482 PyObject *st_mode = NULL;
11483 long mode;
11484 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011485#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011486 int is_symlink;
11487 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011488#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011489#ifdef MS_WINDOWS
11490 unsigned long dir_bits;
11491#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011492 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011493
11494#ifdef MS_WINDOWS
11495 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11496 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011497#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011498 is_symlink = self->d_type == DT_LNK;
11499 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11500#endif
11501
Victor Stinner35a97c02015-03-08 02:59:09 +010011502#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011503 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011504#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011505 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011506 if (!stat) {
11507 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11508 /* If file doesn't exist (anymore), then return False
11509 (i.e., say it's not a file/directory) */
11510 PyErr_Clear();
11511 return 0;
11512 }
11513 goto error;
11514 }
11515 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11516 if (!st_mode)
11517 goto error;
11518
11519 mode = PyLong_AsLong(st_mode);
11520 if (mode == -1 && PyErr_Occurred())
11521 goto error;
11522 Py_CLEAR(st_mode);
11523 Py_CLEAR(stat);
11524 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011525#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011526 }
11527 else if (is_symlink) {
11528 assert(mode_bits != S_IFLNK);
11529 result = 0;
11530 }
11531 else {
11532 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11533#ifdef MS_WINDOWS
11534 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11535 if (mode_bits == S_IFDIR)
11536 result = dir_bits != 0;
11537 else
11538 result = dir_bits == 0;
11539#else /* POSIX */
11540 if (mode_bits == S_IFDIR)
11541 result = self->d_type == DT_DIR;
11542 else
11543 result = self->d_type == DT_REG;
11544#endif
11545 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011546#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011547
11548 return result;
11549
11550error:
11551 Py_XDECREF(st_mode);
11552 Py_XDECREF(stat);
11553 return -1;
11554}
11555
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011556/*[clinic input]
11557os.DirEntry.is_dir -> bool
11558 *
11559 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011560
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011561Return True if the entry is a directory; cached per entry.
11562[clinic start generated code]*/
11563
11564static int
11565os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11566/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11567{
11568 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011569}
11570
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011571/*[clinic input]
11572os.DirEntry.is_file -> bool
11573 *
11574 follow_symlinks: bool = True
11575
11576Return True if the entry is a file; cached per entry.
11577[clinic start generated code]*/
11578
11579static int
11580os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11581/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011582{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011583 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011584}
11585
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011586/*[clinic input]
11587os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011588
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011589Return inode of the entry; cached per entry.
11590[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011591
11592static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011593os_DirEntry_inode_impl(DirEntry *self)
11594/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011595{
11596#ifdef MS_WINDOWS
11597 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011598 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011599 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011600 STRUCT_STAT stat;
11601 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011602
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011603 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011604 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011605 path = PyUnicode_AsUnicode(unicode);
11606 result = LSTAT(path, &stat);
11607 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011608
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011609 if (result != 0)
11610 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011611
11612 self->win32_file_index = stat.st_ino;
11613 self->got_file_index = 1;
11614 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011615 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11616 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011617#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011618 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11619 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011620#endif
11621}
11622
11623static PyObject *
11624DirEntry_repr(DirEntry *self)
11625{
11626 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11627}
11628
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011629/*[clinic input]
11630os.DirEntry.__fspath__
11631
11632Returns the path for the entry.
11633[clinic start generated code]*/
11634
Brett Cannon96881cd2016-06-10 14:37:21 -070011635static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011636os_DirEntry___fspath___impl(DirEntry *self)
11637/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011638{
11639 Py_INCREF(self->path);
11640 return self->path;
11641}
11642
Victor Stinner6036e442015-03-08 01:58:04 +010011643static PyMemberDef DirEntry_members[] = {
11644 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11645 "the entry's base filename, relative to scandir() \"path\" argument"},
11646 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11647 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11648 {NULL}
11649};
11650
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011651#include "clinic/posixmodule.c.h"
11652
Victor Stinner6036e442015-03-08 01:58:04 +010011653static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011654 OS_DIRENTRY_IS_DIR_METHODDEF
11655 OS_DIRENTRY_IS_FILE_METHODDEF
11656 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11657 OS_DIRENTRY_STAT_METHODDEF
11658 OS_DIRENTRY_INODE_METHODDEF
11659 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011660 {NULL}
11661};
11662
Benjamin Peterson5646de42015-04-12 17:56:34 -040011663static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011664 PyVarObject_HEAD_INIT(NULL, 0)
11665 MODNAME ".DirEntry", /* tp_name */
11666 sizeof(DirEntry), /* tp_basicsize */
11667 0, /* tp_itemsize */
11668 /* methods */
11669 (destructor)DirEntry_dealloc, /* tp_dealloc */
11670 0, /* tp_print */
11671 0, /* tp_getattr */
11672 0, /* tp_setattr */
11673 0, /* tp_compare */
11674 (reprfunc)DirEntry_repr, /* tp_repr */
11675 0, /* tp_as_number */
11676 0, /* tp_as_sequence */
11677 0, /* tp_as_mapping */
11678 0, /* tp_hash */
11679 0, /* tp_call */
11680 0, /* tp_str */
11681 0, /* tp_getattro */
11682 0, /* tp_setattro */
11683 0, /* tp_as_buffer */
11684 Py_TPFLAGS_DEFAULT, /* tp_flags */
11685 0, /* tp_doc */
11686 0, /* tp_traverse */
11687 0, /* tp_clear */
11688 0, /* tp_richcompare */
11689 0, /* tp_weaklistoffset */
11690 0, /* tp_iter */
11691 0, /* tp_iternext */
11692 DirEntry_methods, /* tp_methods */
11693 DirEntry_members, /* tp_members */
11694};
11695
11696#ifdef MS_WINDOWS
11697
11698static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011699join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011700{
11701 Py_ssize_t path_len;
11702 Py_ssize_t size;
11703 wchar_t *result;
11704 wchar_t ch;
11705
11706 if (!path_wide) { /* Default arg: "." */
11707 path_wide = L".";
11708 path_len = 1;
11709 }
11710 else {
11711 path_len = wcslen(path_wide);
11712 }
11713
11714 /* The +1's are for the path separator and the NUL */
11715 size = path_len + 1 + wcslen(filename) + 1;
11716 result = PyMem_New(wchar_t, size);
11717 if (!result) {
11718 PyErr_NoMemory();
11719 return NULL;
11720 }
11721 wcscpy(result, path_wide);
11722 if (path_len > 0) {
11723 ch = result[path_len - 1];
11724 if (ch != SEP && ch != ALTSEP && ch != L':')
11725 result[path_len++] = SEP;
11726 wcscpy(result + path_len, filename);
11727 }
11728 return result;
11729}
11730
11731static PyObject *
11732DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11733{
11734 DirEntry *entry;
11735 BY_HANDLE_FILE_INFORMATION file_info;
11736 ULONG reparse_tag;
11737 wchar_t *joined_path;
11738
11739 entry = PyObject_New(DirEntry, &DirEntryType);
11740 if (!entry)
11741 return NULL;
11742 entry->name = NULL;
11743 entry->path = NULL;
11744 entry->stat = NULL;
11745 entry->lstat = NULL;
11746 entry->got_file_index = 0;
11747
11748 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11749 if (!entry->name)
11750 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011751 if (path->narrow) {
11752 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11753 if (!entry->name)
11754 goto error;
11755 }
Victor Stinner6036e442015-03-08 01:58:04 +010011756
11757 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11758 if (!joined_path)
11759 goto error;
11760
11761 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11762 PyMem_Free(joined_path);
11763 if (!entry->path)
11764 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011765 if (path->narrow) {
11766 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11767 if (!entry->path)
11768 goto error;
11769 }
Victor Stinner6036e442015-03-08 01:58:04 +010011770
Steve Dowercc16be82016-09-08 10:35:16 -070011771 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011772 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11773
11774 return (PyObject *)entry;
11775
11776error:
11777 Py_DECREF(entry);
11778 return NULL;
11779}
11780
11781#else /* POSIX */
11782
11783static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011784join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011785{
11786 Py_ssize_t path_len;
11787 Py_ssize_t size;
11788 char *result;
11789
11790 if (!path_narrow) { /* Default arg: "." */
11791 path_narrow = ".";
11792 path_len = 1;
11793 }
11794 else {
11795 path_len = strlen(path_narrow);
11796 }
11797
11798 if (filename_len == -1)
11799 filename_len = strlen(filename);
11800
11801 /* The +1's are for the path separator and the NUL */
11802 size = path_len + 1 + filename_len + 1;
11803 result = PyMem_New(char, size);
11804 if (!result) {
11805 PyErr_NoMemory();
11806 return NULL;
11807 }
11808 strcpy(result, path_narrow);
11809 if (path_len > 0 && result[path_len - 1] != '/')
11810 result[path_len++] = '/';
11811 strcpy(result + path_len, filename);
11812 return result;
11813}
11814
11815static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011816DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011817 ino_t d_ino
11818#ifdef HAVE_DIRENT_D_TYPE
11819 , unsigned char d_type
11820#endif
11821 )
Victor Stinner6036e442015-03-08 01:58:04 +010011822{
11823 DirEntry *entry;
11824 char *joined_path;
11825
11826 entry = PyObject_New(DirEntry, &DirEntryType);
11827 if (!entry)
11828 return NULL;
11829 entry->name = NULL;
11830 entry->path = NULL;
11831 entry->stat = NULL;
11832 entry->lstat = NULL;
11833
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011834 if (path->fd != -1) {
11835 entry->dir_fd = path->fd;
11836 joined_path = NULL;
11837 }
11838 else {
11839 entry->dir_fd = DEFAULT_DIR_FD;
11840 joined_path = join_path_filename(path->narrow, name, name_len);
11841 if (!joined_path)
11842 goto error;
11843 }
Victor Stinner6036e442015-03-08 01:58:04 +010011844
11845 if (!path->narrow || !PyBytes_Check(path->object)) {
11846 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011847 if (joined_path)
11848 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011849 }
11850 else {
11851 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011852 if (joined_path)
11853 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011854 }
11855 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011856 if (!entry->name)
11857 goto error;
11858
11859 if (path->fd != -1) {
11860 entry->path = entry->name;
11861 Py_INCREF(entry->path);
11862 }
11863 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010011864 goto error;
11865
Victor Stinner35a97c02015-03-08 02:59:09 +010011866#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011867 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011868#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011869 entry->d_ino = d_ino;
11870
11871 return (PyObject *)entry;
11872
11873error:
11874 Py_XDECREF(entry);
11875 return NULL;
11876}
11877
11878#endif
11879
11880
11881typedef struct {
11882 PyObject_HEAD
11883 path_t path;
11884#ifdef MS_WINDOWS
11885 HANDLE handle;
11886 WIN32_FIND_DATAW file_data;
11887 int first_time;
11888#else /* POSIX */
11889 DIR *dirp;
11890#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011891#ifdef HAVE_FDOPENDIR
11892 int fd;
11893#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011894} ScandirIterator;
11895
11896#ifdef MS_WINDOWS
11897
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011898static int
11899ScandirIterator_is_closed(ScandirIterator *iterator)
11900{
11901 return iterator->handle == INVALID_HANDLE_VALUE;
11902}
11903
Victor Stinner6036e442015-03-08 01:58:04 +010011904static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011905ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011906{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011907 HANDLE handle = iterator->handle;
11908
11909 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011910 return;
11911
Victor Stinner6036e442015-03-08 01:58:04 +010011912 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011913 Py_BEGIN_ALLOW_THREADS
11914 FindClose(handle);
11915 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011916}
11917
11918static PyObject *
11919ScandirIterator_iternext(ScandirIterator *iterator)
11920{
11921 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11922 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011923 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011924
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011925 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011926 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011927 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011928
11929 while (1) {
11930 if (!iterator->first_time) {
11931 Py_BEGIN_ALLOW_THREADS
11932 success = FindNextFileW(iterator->handle, file_data);
11933 Py_END_ALLOW_THREADS
11934 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011935 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011936 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011937 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011938 break;
11939 }
11940 }
11941 iterator->first_time = 0;
11942
11943 /* Skip over . and .. */
11944 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011945 wcscmp(file_data->cFileName, L"..") != 0) {
11946 entry = DirEntry_from_find_data(&iterator->path, file_data);
11947 if (!entry)
11948 break;
11949 return entry;
11950 }
Victor Stinner6036e442015-03-08 01:58:04 +010011951
11952 /* Loop till we get a non-dot directory or finish iterating */
11953 }
11954
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011955 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011956 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011957 return NULL;
11958}
11959
11960#else /* POSIX */
11961
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011962static int
11963ScandirIterator_is_closed(ScandirIterator *iterator)
11964{
11965 return !iterator->dirp;
11966}
11967
Victor Stinner6036e442015-03-08 01:58:04 +010011968static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011969ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011970{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011971 DIR *dirp = iterator->dirp;
11972
11973 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011974 return;
11975
Victor Stinner6036e442015-03-08 01:58:04 +010011976 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011977 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011978#ifdef HAVE_FDOPENDIR
11979 if (iterator->path.fd != -1)
11980 rewinddir(dirp);
11981#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011982 closedir(dirp);
11983 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011984 return;
11985}
11986
11987static PyObject *
11988ScandirIterator_iternext(ScandirIterator *iterator)
11989{
11990 struct dirent *direntp;
11991 Py_ssize_t name_len;
11992 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011993 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011994
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011995 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011996 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011997 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011998
11999 while (1) {
12000 errno = 0;
12001 Py_BEGIN_ALLOW_THREADS
12002 direntp = readdir(iterator->dirp);
12003 Py_END_ALLOW_THREADS
12004
12005 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012006 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012007 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012008 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012009 break;
12010 }
12011
12012 /* Skip over . and .. */
12013 name_len = NAMLEN(direntp);
12014 is_dot = direntp->d_name[0] == '.' &&
12015 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12016 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012017 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012018 name_len, direntp->d_ino
12019#ifdef HAVE_DIRENT_D_TYPE
12020 , direntp->d_type
12021#endif
12022 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012023 if (!entry)
12024 break;
12025 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012026 }
12027
12028 /* Loop till we get a non-dot directory or finish iterating */
12029 }
12030
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012031 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012032 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012033 return NULL;
12034}
12035
12036#endif
12037
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012038static PyObject *
12039ScandirIterator_close(ScandirIterator *self, PyObject *args)
12040{
12041 ScandirIterator_closedir(self);
12042 Py_RETURN_NONE;
12043}
12044
12045static PyObject *
12046ScandirIterator_enter(PyObject *self, PyObject *args)
12047{
12048 Py_INCREF(self);
12049 return self;
12050}
12051
12052static PyObject *
12053ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12054{
12055 ScandirIterator_closedir(self);
12056 Py_RETURN_NONE;
12057}
12058
Victor Stinner6036e442015-03-08 01:58:04 +010012059static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012060ScandirIterator_finalize(ScandirIterator *iterator)
12061{
12062 PyObject *error_type, *error_value, *error_traceback;
12063
12064 /* Save the current exception, if any. */
12065 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12066
12067 if (!ScandirIterator_is_closed(iterator)) {
12068 ScandirIterator_closedir(iterator);
12069
12070 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12071 "unclosed scandir iterator %R", iterator)) {
12072 /* Spurious errors can appear at shutdown */
12073 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12074 PyErr_WriteUnraisable((PyObject *) iterator);
12075 }
12076 }
12077 }
12078
Victor Stinner7bfa4092016-03-23 00:43:54 +010012079 path_cleanup(&iterator->path);
12080
12081 /* Restore the saved exception. */
12082 PyErr_Restore(error_type, error_value, error_traceback);
12083}
12084
12085static void
Victor Stinner6036e442015-03-08 01:58:04 +010012086ScandirIterator_dealloc(ScandirIterator *iterator)
12087{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012088 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12089 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012090
Victor Stinner6036e442015-03-08 01:58:04 +010012091 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12092}
12093
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012094static PyMethodDef ScandirIterator_methods[] = {
12095 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12096 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12097 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12098 {NULL}
12099};
12100
Benjamin Peterson5646de42015-04-12 17:56:34 -040012101static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012102 PyVarObject_HEAD_INIT(NULL, 0)
12103 MODNAME ".ScandirIterator", /* tp_name */
12104 sizeof(ScandirIterator), /* tp_basicsize */
12105 0, /* tp_itemsize */
12106 /* methods */
12107 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12108 0, /* tp_print */
12109 0, /* tp_getattr */
12110 0, /* tp_setattr */
12111 0, /* tp_compare */
12112 0, /* tp_repr */
12113 0, /* tp_as_number */
12114 0, /* tp_as_sequence */
12115 0, /* tp_as_mapping */
12116 0, /* tp_hash */
12117 0, /* tp_call */
12118 0, /* tp_str */
12119 0, /* tp_getattro */
12120 0, /* tp_setattro */
12121 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012122 Py_TPFLAGS_DEFAULT
12123 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012124 0, /* tp_doc */
12125 0, /* tp_traverse */
12126 0, /* tp_clear */
12127 0, /* tp_richcompare */
12128 0, /* tp_weaklistoffset */
12129 PyObject_SelfIter, /* tp_iter */
12130 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012131 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012132 0, /* tp_members */
12133 0, /* tp_getset */
12134 0, /* tp_base */
12135 0, /* tp_dict */
12136 0, /* tp_descr_get */
12137 0, /* tp_descr_set */
12138 0, /* tp_dictoffset */
12139 0, /* tp_init */
12140 0, /* tp_alloc */
12141 0, /* tp_new */
12142 0, /* tp_free */
12143 0, /* tp_is_gc */
12144 0, /* tp_bases */
12145 0, /* tp_mro */
12146 0, /* tp_cache */
12147 0, /* tp_subclasses */
12148 0, /* tp_weaklist */
12149 0, /* tp_del */
12150 0, /* tp_version_tag */
12151 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012152};
12153
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012154/*[clinic input]
12155os.scandir
12156
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012157 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012158
12159Return an iterator of DirEntry objects for given path.
12160
12161path can be specified as either str, bytes or path-like object. If path
12162is bytes, the names of yielded DirEntry objects will also be bytes; in
12163all other circumstances they will be str.
12164
12165If path is None, uses the path='.'.
12166[clinic start generated code]*/
12167
Victor Stinner6036e442015-03-08 01:58:04 +010012168static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012169os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012170/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012171{
12172 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012173#ifdef MS_WINDOWS
12174 wchar_t *path_strW;
12175#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012176 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012177#ifdef HAVE_FDOPENDIR
12178 int fd = -1;
12179#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012180#endif
12181
12182 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12183 if (!iterator)
12184 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012185
12186#ifdef MS_WINDOWS
12187 iterator->handle = INVALID_HANDLE_VALUE;
12188#else
12189 iterator->dirp = NULL;
12190#endif
12191
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012192 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012193 /* Move the ownership to iterator->path */
12194 path->object = NULL;
12195 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012196
12197#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012198 iterator->first_time = 1;
12199
12200 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12201 if (!path_strW)
12202 goto error;
12203
12204 Py_BEGIN_ALLOW_THREADS
12205 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12206 Py_END_ALLOW_THREADS
12207
12208 PyMem_Free(path_strW);
12209
12210 if (iterator->handle == INVALID_HANDLE_VALUE) {
12211 path_error(&iterator->path);
12212 goto error;
12213 }
12214#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012215 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012216#ifdef HAVE_FDOPENDIR
12217 if (path->fd != -1) {
12218 /* closedir() closes the FD, so we duplicate it */
12219 fd = _Py_dup(path->fd);
12220 if (fd == -1)
12221 goto error;
12222
12223 Py_BEGIN_ALLOW_THREADS
12224 iterator->dirp = fdopendir(fd);
12225 Py_END_ALLOW_THREADS
12226 }
12227 else
12228#endif
12229 {
12230 if (iterator->path.narrow)
12231 path_str = iterator->path.narrow;
12232 else
12233 path_str = ".";
12234
12235 Py_BEGIN_ALLOW_THREADS
12236 iterator->dirp = opendir(path_str);
12237 Py_END_ALLOW_THREADS
12238 }
Victor Stinner6036e442015-03-08 01:58:04 +010012239
12240 if (!iterator->dirp) {
12241 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012242#ifdef HAVE_FDOPENDIR
12243 if (fd != -1) {
12244 Py_BEGIN_ALLOW_THREADS
12245 close(fd);
12246 Py_END_ALLOW_THREADS
12247 }
12248#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012249 goto error;
12250 }
12251#endif
12252
12253 return (PyObject *)iterator;
12254
12255error:
12256 Py_DECREF(iterator);
12257 return NULL;
12258}
12259
Ethan Furman410ef8e2016-06-04 12:06:26 -070012260/*
12261 Return the file system path representation of the object.
12262
12263 If the object is str or bytes, then allow it to pass through with
12264 an incremented refcount. If the object defines __fspath__(), then
12265 return the result of that method. All other types raise a TypeError.
12266*/
12267PyObject *
12268PyOS_FSPath(PyObject *path)
12269{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012270 /* For error message reasons, this function is manually inlined in
12271 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012272 _Py_IDENTIFIER(__fspath__);
12273 PyObject *func = NULL;
12274 PyObject *path_repr = NULL;
12275
12276 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12277 Py_INCREF(path);
12278 return path;
12279 }
12280
12281 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12282 if (NULL == func) {
12283 return PyErr_Format(PyExc_TypeError,
12284 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012285 "not %.200s",
12286 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012287 }
12288
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012289 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012290 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012291 if (NULL == path_repr) {
12292 return NULL;
12293 }
12294
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012295 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12296 PyErr_Format(PyExc_TypeError,
12297 "expected %.200s.__fspath__() to return str or bytes, "
12298 "not %.200s", Py_TYPE(path)->tp_name,
12299 Py_TYPE(path_repr)->tp_name);
12300 Py_DECREF(path_repr);
12301 return NULL;
12302 }
12303
Ethan Furman410ef8e2016-06-04 12:06:26 -070012304 return path_repr;
12305}
12306
12307/*[clinic input]
12308os.fspath
12309
12310 path: object
12311
12312Return the file system path representation of the object.
12313
Brett Cannonb4f43e92016-06-09 14:32:08 -070012314If the object is str or bytes, then allow it to pass through as-is. If the
12315object defines __fspath__(), then return the result of that method. All other
12316types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012317[clinic start generated code]*/
12318
12319static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012320os_fspath_impl(PyObject *module, PyObject *path)
12321/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012322{
12323 return PyOS_FSPath(path);
12324}
Victor Stinner6036e442015-03-08 01:58:04 +010012325
Victor Stinner9b1f4742016-09-06 16:18:52 -070012326#ifdef HAVE_GETRANDOM_SYSCALL
12327/*[clinic input]
12328os.getrandom
12329
12330 size: Py_ssize_t
12331 flags: int=0
12332
12333Obtain a series of random bytes.
12334[clinic start generated code]*/
12335
12336static PyObject *
12337os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12338/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12339{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012340 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012341 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012342
12343 if (size < 0) {
12344 errno = EINVAL;
12345 return posix_error();
12346 }
12347
Victor Stinnerec2319c2016-09-20 23:00:59 +020012348 bytes = PyBytes_FromStringAndSize(NULL, size);
12349 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012350 PyErr_NoMemory();
12351 return NULL;
12352 }
12353
12354 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012355 n = syscall(SYS_getrandom,
12356 PyBytes_AS_STRING(bytes),
12357 PyBytes_GET_SIZE(bytes),
12358 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012359 if (n < 0 && errno == EINTR) {
12360 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012361 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012362 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012363
12364 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012365 continue;
12366 }
12367 break;
12368 }
12369
12370 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012371 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012372 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012373 }
12374
Victor Stinnerec2319c2016-09-20 23:00:59 +020012375 if (n != size) {
12376 _PyBytes_Resize(&bytes, n);
12377 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012378
12379 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012380
12381error:
12382 Py_DECREF(bytes);
12383 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012384}
12385#endif /* HAVE_GETRANDOM_SYSCALL */
12386
Larry Hastings31826802013-10-19 00:09:25 -070012387
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012388static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012389
12390 OS_STAT_METHODDEF
12391 OS_ACCESS_METHODDEF
12392 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012393 OS_CHDIR_METHODDEF
12394 OS_CHFLAGS_METHODDEF
12395 OS_CHMOD_METHODDEF
12396 OS_FCHMOD_METHODDEF
12397 OS_LCHMOD_METHODDEF
12398 OS_CHOWN_METHODDEF
12399 OS_FCHOWN_METHODDEF
12400 OS_LCHOWN_METHODDEF
12401 OS_LCHFLAGS_METHODDEF
12402 OS_CHROOT_METHODDEF
12403 OS_CTERMID_METHODDEF
12404 OS_GETCWD_METHODDEF
12405 OS_GETCWDB_METHODDEF
12406 OS_LINK_METHODDEF
12407 OS_LISTDIR_METHODDEF
12408 OS_LSTAT_METHODDEF
12409 OS_MKDIR_METHODDEF
12410 OS_NICE_METHODDEF
12411 OS_GETPRIORITY_METHODDEF
12412 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012413#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012414 {"readlink", (PyCFunction)posix_readlink,
12415 METH_VARARGS | METH_KEYWORDS,
12416 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012417#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012418#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012419 {"readlink", (PyCFunction)win_readlink,
12420 METH_VARARGS | METH_KEYWORDS,
12421 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012422#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012423 OS_RENAME_METHODDEF
12424 OS_REPLACE_METHODDEF
12425 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012426 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012427 OS_SYMLINK_METHODDEF
12428 OS_SYSTEM_METHODDEF
12429 OS_UMASK_METHODDEF
12430 OS_UNAME_METHODDEF
12431 OS_UNLINK_METHODDEF
12432 OS_REMOVE_METHODDEF
12433 OS_UTIME_METHODDEF
12434 OS_TIMES_METHODDEF
12435 OS__EXIT_METHODDEF
12436 OS_EXECV_METHODDEF
12437 OS_EXECVE_METHODDEF
12438 OS_SPAWNV_METHODDEF
12439 OS_SPAWNVE_METHODDEF
12440 OS_FORK1_METHODDEF
12441 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012442 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012443 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12444 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12445 OS_SCHED_GETPARAM_METHODDEF
12446 OS_SCHED_GETSCHEDULER_METHODDEF
12447 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12448 OS_SCHED_SETPARAM_METHODDEF
12449 OS_SCHED_SETSCHEDULER_METHODDEF
12450 OS_SCHED_YIELD_METHODDEF
12451 OS_SCHED_SETAFFINITY_METHODDEF
12452 OS_SCHED_GETAFFINITY_METHODDEF
12453 OS_OPENPTY_METHODDEF
12454 OS_FORKPTY_METHODDEF
12455 OS_GETEGID_METHODDEF
12456 OS_GETEUID_METHODDEF
12457 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012458#ifdef HAVE_GETGROUPLIST
12459 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12460#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012461 OS_GETGROUPS_METHODDEF
12462 OS_GETPID_METHODDEF
12463 OS_GETPGRP_METHODDEF
12464 OS_GETPPID_METHODDEF
12465 OS_GETUID_METHODDEF
12466 OS_GETLOGIN_METHODDEF
12467 OS_KILL_METHODDEF
12468 OS_KILLPG_METHODDEF
12469 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012470#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012471 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012472#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012473 OS_SETUID_METHODDEF
12474 OS_SETEUID_METHODDEF
12475 OS_SETREUID_METHODDEF
12476 OS_SETGID_METHODDEF
12477 OS_SETEGID_METHODDEF
12478 OS_SETREGID_METHODDEF
12479 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012480#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012481 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012482#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012483 OS_GETPGID_METHODDEF
12484 OS_SETPGRP_METHODDEF
12485 OS_WAIT_METHODDEF
12486 OS_WAIT3_METHODDEF
12487 OS_WAIT4_METHODDEF
12488 OS_WAITID_METHODDEF
12489 OS_WAITPID_METHODDEF
12490 OS_GETSID_METHODDEF
12491 OS_SETSID_METHODDEF
12492 OS_SETPGID_METHODDEF
12493 OS_TCGETPGRP_METHODDEF
12494 OS_TCSETPGRP_METHODDEF
12495 OS_OPEN_METHODDEF
12496 OS_CLOSE_METHODDEF
12497 OS_CLOSERANGE_METHODDEF
12498 OS_DEVICE_ENCODING_METHODDEF
12499 OS_DUP_METHODDEF
12500 OS_DUP2_METHODDEF
12501 OS_LOCKF_METHODDEF
12502 OS_LSEEK_METHODDEF
12503 OS_READ_METHODDEF
12504 OS_READV_METHODDEF
12505 OS_PREAD_METHODDEF
12506 OS_WRITE_METHODDEF
12507 OS_WRITEV_METHODDEF
12508 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012509#ifdef HAVE_SENDFILE
12510 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12511 posix_sendfile__doc__},
12512#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012513 OS_FSTAT_METHODDEF
12514 OS_ISATTY_METHODDEF
12515 OS_PIPE_METHODDEF
12516 OS_PIPE2_METHODDEF
12517 OS_MKFIFO_METHODDEF
12518 OS_MKNOD_METHODDEF
12519 OS_MAJOR_METHODDEF
12520 OS_MINOR_METHODDEF
12521 OS_MAKEDEV_METHODDEF
12522 OS_FTRUNCATE_METHODDEF
12523 OS_TRUNCATE_METHODDEF
12524 OS_POSIX_FALLOCATE_METHODDEF
12525 OS_POSIX_FADVISE_METHODDEF
12526 OS_PUTENV_METHODDEF
12527 OS_UNSETENV_METHODDEF
12528 OS_STRERROR_METHODDEF
12529 OS_FCHDIR_METHODDEF
12530 OS_FSYNC_METHODDEF
12531 OS_SYNC_METHODDEF
12532 OS_FDATASYNC_METHODDEF
12533 OS_WCOREDUMP_METHODDEF
12534 OS_WIFCONTINUED_METHODDEF
12535 OS_WIFSTOPPED_METHODDEF
12536 OS_WIFSIGNALED_METHODDEF
12537 OS_WIFEXITED_METHODDEF
12538 OS_WEXITSTATUS_METHODDEF
12539 OS_WTERMSIG_METHODDEF
12540 OS_WSTOPSIG_METHODDEF
12541 OS_FSTATVFS_METHODDEF
12542 OS_STATVFS_METHODDEF
12543 OS_CONFSTR_METHODDEF
12544 OS_SYSCONF_METHODDEF
12545 OS_FPATHCONF_METHODDEF
12546 OS_PATHCONF_METHODDEF
12547 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012548 OS__GETFULLPATHNAME_METHODDEF
12549 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012550 OS__GETDISKUSAGE_METHODDEF
12551 OS__GETFINALPATHNAME_METHODDEF
12552 OS__GETVOLUMEPATHNAME_METHODDEF
12553 OS_GETLOADAVG_METHODDEF
12554 OS_URANDOM_METHODDEF
12555 OS_SETRESUID_METHODDEF
12556 OS_SETRESGID_METHODDEF
12557 OS_GETRESUID_METHODDEF
12558 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012559
Larry Hastings2f936352014-08-05 14:04:04 +100012560 OS_GETXATTR_METHODDEF
12561 OS_SETXATTR_METHODDEF
12562 OS_REMOVEXATTR_METHODDEF
12563 OS_LISTXATTR_METHODDEF
12564
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012565#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12566 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12567#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012568 OS_CPU_COUNT_METHODDEF
12569 OS_GET_INHERITABLE_METHODDEF
12570 OS_SET_INHERITABLE_METHODDEF
12571 OS_GET_HANDLE_INHERITABLE_METHODDEF
12572 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012573#ifndef MS_WINDOWS
12574 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12575 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12576#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012577 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012578 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012579 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012580 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012581};
12582
12583
Brian Curtin52173d42010-12-02 18:29:18 +000012584#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012585static int
Brian Curtin52173d42010-12-02 18:29:18 +000012586enable_symlink()
12587{
12588 HANDLE tok;
12589 TOKEN_PRIVILEGES tok_priv;
12590 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012591
12592 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012593 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012594
12595 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012596 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012597
12598 tok_priv.PrivilegeCount = 1;
12599 tok_priv.Privileges[0].Luid = luid;
12600 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12601
12602 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12603 sizeof(TOKEN_PRIVILEGES),
12604 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012605 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012606
Brian Curtin3b4499c2010-12-28 14:31:47 +000012607 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12608 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012609}
12610#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12611
Barry Warsaw4a342091996-12-19 23:50:02 +000012612static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012613all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012614{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012615#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012616 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012617#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012618#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012619 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012620#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012621#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012622 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012623#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012624#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012625 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012626#endif
Fred Drakec9680921999-12-13 16:37:25 +000012627#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012628 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012629#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012630#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012631 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012632#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012633#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012634 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012635#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012636#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012637 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012638#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012639#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012640 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012641#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012642#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012643 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012644#endif
12645#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012646 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012647#endif
12648#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012649 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012650#endif
12651#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012652 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012653#endif
12654#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012655 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012656#endif
12657#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012658 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012659#endif
12660#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012661 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012662#endif
12663#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012664 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012665#endif
12666#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012667 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012668#endif
12669#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012670 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012671#endif
12672#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012673 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012674#endif
12675#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012676 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012677#endif
12678#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012679 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012680#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012681#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012682 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012683#endif
12684#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012685 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012686#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012687#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012688 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012689#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012690#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012691 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012692#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012693#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012694#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012696#endif
12697#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012698 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012699#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012700#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012701#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012702 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012703#endif
12704#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012705 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012706#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012707#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012708 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012709#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012710#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012711 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012712#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012713#ifdef O_TMPFILE
12714 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12715#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012716#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012717 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012718#endif
12719#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012720 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012721#endif
12722#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012723 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012724#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012725#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012726 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012727#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012728#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012729 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012730#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012731
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012732
Jesus Cea94363612012-06-22 18:32:07 +020012733#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012734 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012735#endif
12736#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012738#endif
12739
Tim Peters5aa91602002-01-30 05:46:57 +000012740/* MS Windows */
12741#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012742 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012743 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012744#endif
12745#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012746 /* Optimize for short life (keep in memory). */
12747 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012748 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012749#endif
12750#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012751 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012752 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012753#endif
12754#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012755 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012756 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012757#endif
12758#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012759 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012760 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012761#endif
12762
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012763/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012764#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012765 /* Send a SIGIO signal whenever input or output
12766 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012767 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012768#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012769#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012770 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012771 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012772#endif
12773#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012774 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012775 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012776#endif
12777#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012778 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012779 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012780#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012781#ifdef O_NOLINKS
12782 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012783 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012784#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012785#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012786 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012787 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012788#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012789
Victor Stinner8c62be82010-05-06 00:08:46 +000012790 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012791#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012792 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012793#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012794#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012795 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012796#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012797#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012798 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012799#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012800#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012801 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012802#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012803#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012804 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012805#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012806#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012807 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012808#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012809#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012810 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012811#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012812#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012813 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012814#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012815#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012816 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012817#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012818#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012819 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012820#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012821#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012822 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012823#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012824#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012825 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012826#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012827#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012828 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012829#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012830#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012831 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012832#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012833#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012834 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012835#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012836#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012837 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012838#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012839#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012840 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012841#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012842
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012843 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012844#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012845 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012846#endif /* ST_RDONLY */
12847#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012848 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012849#endif /* ST_NOSUID */
12850
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012851 /* GNU extensions */
12852#ifdef ST_NODEV
12853 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12854#endif /* ST_NODEV */
12855#ifdef ST_NOEXEC
12856 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12857#endif /* ST_NOEXEC */
12858#ifdef ST_SYNCHRONOUS
12859 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12860#endif /* ST_SYNCHRONOUS */
12861#ifdef ST_MANDLOCK
12862 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12863#endif /* ST_MANDLOCK */
12864#ifdef ST_WRITE
12865 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12866#endif /* ST_WRITE */
12867#ifdef ST_APPEND
12868 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12869#endif /* ST_APPEND */
12870#ifdef ST_NOATIME
12871 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12872#endif /* ST_NOATIME */
12873#ifdef ST_NODIRATIME
12874 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12875#endif /* ST_NODIRATIME */
12876#ifdef ST_RELATIME
12877 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12878#endif /* ST_RELATIME */
12879
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012880 /* FreeBSD sendfile() constants */
12881#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012882 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012883#endif
12884#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012885 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012886#endif
12887#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012888 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012889#endif
12890
Ross Lagerwall7807c352011-03-17 20:20:30 +020012891 /* constants for posix_fadvise */
12892#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012893 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012894#endif
12895#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012896 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012897#endif
12898#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012899 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012900#endif
12901#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012902 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012903#endif
12904#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012905 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012906#endif
12907#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012908 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012909#endif
12910
12911 /* constants for waitid */
12912#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012913 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12914 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12915 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012916#endif
12917#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012918 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012919#endif
12920#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012921 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012922#endif
12923#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012924 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012925#endif
12926#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012927 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012928#endif
12929#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012930 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012931#endif
12932#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012933 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012934#endif
12935#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012936 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012937#endif
12938
12939 /* constants for lockf */
12940#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012941 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012942#endif
12943#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012944 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012945#endif
12946#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012947 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012948#endif
12949#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012950 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012951#endif
12952
Guido van Rossum246bc171999-02-01 23:54:31 +000012953#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012954 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12955 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12956 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12957 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12958 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012959#endif
12960
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012961#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012962#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012963 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012964#endif
12965#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012966 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012967#endif
12968#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012969 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012970#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012971#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080012972 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012973#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012974#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012975 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012976#endif
12977#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012978 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012979#endif
12980#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012981 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012982#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012983#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012984 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012985#endif
12986#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012987 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012988#endif
12989#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012990 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012991#endif
12992#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012993 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012994#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012995#endif
12996
Benjamin Peterson9428d532011-09-14 11:45:52 -040012997#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012998 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12999 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13000 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013001#endif
13002
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013003#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013004 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013005#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013006#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013007 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013008#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013009#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013010 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013011#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013012#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013013 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013014#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013015#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013016 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013017#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013018#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013019 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013020#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013021#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013022 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013023#endif
13024
Victor Stinner9b1f4742016-09-06 16:18:52 -070013025#ifdef HAVE_GETRANDOM_SYSCALL
13026 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13027 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13028#endif
13029
Victor Stinner8c62be82010-05-06 00:08:46 +000013030 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013031}
13032
13033
Martin v. Löwis1a214512008-06-11 05:26:20 +000013034static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013035 PyModuleDef_HEAD_INIT,
13036 MODNAME,
13037 posix__doc__,
13038 -1,
13039 posix_methods,
13040 NULL,
13041 NULL,
13042 NULL,
13043 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013044};
13045
13046
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013047static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013048
13049#ifdef HAVE_FACCESSAT
13050 "HAVE_FACCESSAT",
13051#endif
13052
13053#ifdef HAVE_FCHDIR
13054 "HAVE_FCHDIR",
13055#endif
13056
13057#ifdef HAVE_FCHMOD
13058 "HAVE_FCHMOD",
13059#endif
13060
13061#ifdef HAVE_FCHMODAT
13062 "HAVE_FCHMODAT",
13063#endif
13064
13065#ifdef HAVE_FCHOWN
13066 "HAVE_FCHOWN",
13067#endif
13068
Larry Hastings00964ed2013-08-12 13:49:30 -040013069#ifdef HAVE_FCHOWNAT
13070 "HAVE_FCHOWNAT",
13071#endif
13072
Larry Hastings9cf065c2012-06-22 16:30:09 -070013073#ifdef HAVE_FEXECVE
13074 "HAVE_FEXECVE",
13075#endif
13076
13077#ifdef HAVE_FDOPENDIR
13078 "HAVE_FDOPENDIR",
13079#endif
13080
Georg Brandl306336b2012-06-24 12:55:33 +020013081#ifdef HAVE_FPATHCONF
13082 "HAVE_FPATHCONF",
13083#endif
13084
Larry Hastings9cf065c2012-06-22 16:30:09 -070013085#ifdef HAVE_FSTATAT
13086 "HAVE_FSTATAT",
13087#endif
13088
13089#ifdef HAVE_FSTATVFS
13090 "HAVE_FSTATVFS",
13091#endif
13092
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013093#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013094 "HAVE_FTRUNCATE",
13095#endif
13096
Larry Hastings9cf065c2012-06-22 16:30:09 -070013097#ifdef HAVE_FUTIMENS
13098 "HAVE_FUTIMENS",
13099#endif
13100
13101#ifdef HAVE_FUTIMES
13102 "HAVE_FUTIMES",
13103#endif
13104
13105#ifdef HAVE_FUTIMESAT
13106 "HAVE_FUTIMESAT",
13107#endif
13108
13109#ifdef HAVE_LINKAT
13110 "HAVE_LINKAT",
13111#endif
13112
13113#ifdef HAVE_LCHFLAGS
13114 "HAVE_LCHFLAGS",
13115#endif
13116
13117#ifdef HAVE_LCHMOD
13118 "HAVE_LCHMOD",
13119#endif
13120
13121#ifdef HAVE_LCHOWN
13122 "HAVE_LCHOWN",
13123#endif
13124
13125#ifdef HAVE_LSTAT
13126 "HAVE_LSTAT",
13127#endif
13128
13129#ifdef HAVE_LUTIMES
13130 "HAVE_LUTIMES",
13131#endif
13132
13133#ifdef HAVE_MKDIRAT
13134 "HAVE_MKDIRAT",
13135#endif
13136
13137#ifdef HAVE_MKFIFOAT
13138 "HAVE_MKFIFOAT",
13139#endif
13140
13141#ifdef HAVE_MKNODAT
13142 "HAVE_MKNODAT",
13143#endif
13144
13145#ifdef HAVE_OPENAT
13146 "HAVE_OPENAT",
13147#endif
13148
13149#ifdef HAVE_READLINKAT
13150 "HAVE_READLINKAT",
13151#endif
13152
13153#ifdef HAVE_RENAMEAT
13154 "HAVE_RENAMEAT",
13155#endif
13156
13157#ifdef HAVE_SYMLINKAT
13158 "HAVE_SYMLINKAT",
13159#endif
13160
13161#ifdef HAVE_UNLINKAT
13162 "HAVE_UNLINKAT",
13163#endif
13164
13165#ifdef HAVE_UTIMENSAT
13166 "HAVE_UTIMENSAT",
13167#endif
13168
13169#ifdef MS_WINDOWS
13170 "MS_WINDOWS",
13171#endif
13172
13173 NULL
13174};
13175
13176
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013177PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013178INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013179{
Victor Stinner8c62be82010-05-06 00:08:46 +000013180 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013181 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013182 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013183
Brian Curtin52173d42010-12-02 18:29:18 +000013184#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013185 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013186#endif
13187
Victor Stinner8c62be82010-05-06 00:08:46 +000013188 m = PyModule_Create(&posixmodule);
13189 if (m == NULL)
13190 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013191
Victor Stinner8c62be82010-05-06 00:08:46 +000013192 /* Initialize environ dictionary */
13193 v = convertenviron();
13194 Py_XINCREF(v);
13195 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13196 return NULL;
13197 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013198
Victor Stinner8c62be82010-05-06 00:08:46 +000013199 if (all_ins(m))
13200 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013201
Victor Stinner8c62be82010-05-06 00:08:46 +000013202 if (setup_confname_tables(m))
13203 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013204
Victor Stinner8c62be82010-05-06 00:08:46 +000013205 Py_INCREF(PyExc_OSError);
13206 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013207
Guido van Rossumb3d39562000-01-31 18:41:26 +000013208#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013209 if (posix_putenv_garbage == NULL)
13210 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013211#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013212
Victor Stinner8c62be82010-05-06 00:08:46 +000013213 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013214#if defined(HAVE_WAITID) && !defined(__APPLE__)
13215 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013216 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13217 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013218#endif
13219
Christian Heimes25827622013-10-12 01:27:08 +020013220 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013221 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13222 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13223 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013224 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13225 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013226 structseq_new = StatResultType.tp_new;
13227 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013228
Christian Heimes25827622013-10-12 01:27:08 +020013229 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013230 if (PyStructSequence_InitType2(&StatVFSResultType,
13231 &statvfs_result_desc) < 0)
13232 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013233#ifdef NEED_TICKS_PER_SECOND
13234# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013235 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013236# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013237 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013238# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013239 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013240# endif
13241#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013242
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013243#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013244 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013245 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13246 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013247 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013248#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013249
13250 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013251 if (PyStructSequence_InitType2(&TerminalSizeType,
13252 &TerminalSize_desc) < 0)
13253 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013254
13255 /* initialize scandir types */
13256 if (PyType_Ready(&ScandirIteratorType) < 0)
13257 return NULL;
13258 if (PyType_Ready(&DirEntryType) < 0)
13259 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013260 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013261#if defined(HAVE_WAITID) && !defined(__APPLE__)
13262 Py_INCREF((PyObject*) &WaitidResultType);
13263 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13264#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013265 Py_INCREF((PyObject*) &StatResultType);
13266 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13267 Py_INCREF((PyObject*) &StatVFSResultType);
13268 PyModule_AddObject(m, "statvfs_result",
13269 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013270
13271#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013272 Py_INCREF(&SchedParamType);
13273 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013274#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013275
Larry Hastings605a62d2012-06-24 04:33:36 -070013276 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013277 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13278 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013279 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13280
13281 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013282 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13283 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013284 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13285
Thomas Wouters477c8d52006-05-27 19:21:47 +000013286#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013287 /*
13288 * Step 2 of weak-linking support on Mac OS X.
13289 *
13290 * The code below removes functions that are not available on the
13291 * currently active platform.
13292 *
13293 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013294 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013295 * OSX 10.4.
13296 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013297#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013298 if (fstatvfs == NULL) {
13299 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13300 return NULL;
13301 }
13302 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013303#endif /* HAVE_FSTATVFS */
13304
13305#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013306 if (statvfs == NULL) {
13307 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13308 return NULL;
13309 }
13310 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013311#endif /* HAVE_STATVFS */
13312
13313# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013314 if (lchown == NULL) {
13315 if (PyObject_DelAttrString(m, "lchown") == -1) {
13316 return NULL;
13317 }
13318 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013319#endif /* HAVE_LCHOWN */
13320
13321
13322#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013323
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013324 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013325 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13326
Larry Hastings6fe20b32012-04-19 15:07:49 -070013327 billion = PyLong_FromLong(1000000000);
13328 if (!billion)
13329 return NULL;
13330
Larry Hastings9cf065c2012-06-22 16:30:09 -070013331 /* suppress "function not used" warnings */
13332 {
13333 int ignored;
13334 fd_specified("", -1);
13335 follow_symlinks_specified("", 1);
13336 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13337 dir_fd_converter(Py_None, &ignored);
13338 dir_fd_unavailable(Py_None, &ignored);
13339 }
13340
13341 /*
13342 * provide list of locally available functions
13343 * so os.py can populate support_* lists
13344 */
13345 list = PyList_New(0);
13346 if (!list)
13347 return NULL;
13348 for (trace = have_functions; *trace; trace++) {
13349 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13350 if (!unicode)
13351 return NULL;
13352 if (PyList_Append(list, unicode))
13353 return NULL;
13354 Py_DECREF(unicode);
13355 }
13356 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013357
13358 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013359 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013360
13361 initialized = 1;
13362
Victor Stinner8c62be82010-05-06 00:08:46 +000013363 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013364}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013365
13366#ifdef __cplusplus
13367}
13368#endif