blob: 435e5f61271cc43427efe710279cabb0778ed192 [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
Christian Heimes75b96182017-09-05 15:53:09 +020059#ifdef HAVE_SYS_SYSMACROS_H
60/* GNU C Library: major(), minor(), makedev() */
61#include <sys/sysmacros.h>
62#endif
63
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000065#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#endif /* HAVE_SYS_TYPES_H */
67
68#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000069#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000070#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000071
Guido van Rossum36bc6801995-06-14 22:54:23 +000072#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000073#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000074#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000075
Thomas Wouters0e3f5912006-08-11 14:57:12 +000076#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000077#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000079
Guido van Rossumb6775db1994-08-01 11:34:53 +000080#ifdef HAVE_FCNTL_H
81#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000082#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000083
Guido van Rossuma6535fd2001-10-18 19:44:10 +000084#ifdef HAVE_GRP_H
85#include <grp.h>
86#endif
87
Barry Warsaw5676bd12003-01-07 20:57:09 +000088#ifdef HAVE_SYSEXITS_H
89#include <sysexits.h>
90#endif /* HAVE_SYSEXITS_H */
91
Anthony Baxter8a560de2004-10-13 15:30:56 +000092#ifdef HAVE_SYS_LOADAVG_H
93#include <sys/loadavg.h>
94#endif
95
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000096#ifdef HAVE_SYS_SENDFILE_H
97#include <sys/sendfile.h>
98#endif
99
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200100#if defined(__APPLE__)
101#include <copyfile.h>
102#endif
103
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500104#ifdef HAVE_SCHED_H
105#include <sched.h>
106#endif
107
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500108#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500109#undef HAVE_SCHED_SETAFFINITY
110#endif
111
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200112#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400113#define USE_XATTRS
114#endif
115
116#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400117#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400118#endif
119
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000120#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
121#ifdef HAVE_SYS_SOCKET_H
122#include <sys/socket.h>
123#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000124#endif
125
Victor Stinner8b905bd2011-10-25 13:34:04 +0200126#ifdef HAVE_DLFCN_H
127#include <dlfcn.h>
128#endif
129
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200130#ifdef __hpux
131#include <sys/mpctl.h>
132#endif
133
134#if defined(__DragonFly__) || \
135 defined(__OpenBSD__) || \
136 defined(__FreeBSD__) || \
137 defined(__NetBSD__) || \
138 defined(__APPLE__)
139#include <sys/sysctl.h>
140#endif
141
Victor Stinner9b1f4742016-09-06 16:18:52 -0700142#ifdef HAVE_LINUX_RANDOM_H
143# include <linux/random.h>
144#endif
145#ifdef HAVE_GETRANDOM_SYSCALL
146# include <sys/syscall.h>
147#endif
148
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100149#if defined(MS_WINDOWS)
150# define TERMSIZE_USE_CONIO
151#elif defined(HAVE_SYS_IOCTL_H)
152# include <sys/ioctl.h>
153# if defined(HAVE_TERMIOS_H)
154# include <termios.h>
155# endif
156# if defined(TIOCGWINSZ)
157# define TERMSIZE_USE_IOCTL
158# endif
159#endif /* MS_WINDOWS */
160
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000161/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000162/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000163#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000164#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166#include <process.h>
167#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000168#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000169#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000170#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000171#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700173#define HAVE_WSPAWNV 1
174#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000176#define HAVE_SYSTEM 1
177#define HAVE_CWAIT 1
178#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000179#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000180#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181/* Unix functions that the configure script doesn't check for */
182#define HAVE_EXECV 1
183#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000184#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000185#define HAVE_FORK1 1
186#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000187#define HAVE_GETEGID 1
188#define HAVE_GETEUID 1
189#define HAVE_GETGID 1
190#define HAVE_GETPPID 1
191#define HAVE_GETUID 1
192#define HAVE_KILL 1
193#define HAVE_OPENDIR 1
194#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000195#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000196#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000197#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000199#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000200
Victor Stinnera2f7c002012-02-08 03:36:25 +0100201
Larry Hastings61272b72014-01-07 12:41:53 -0800202/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000203# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800204module os
Larry Hastings61272b72014-01-07 12:41:53 -0800205[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000206/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100207
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000208#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000209
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000210#if defined(__sgi)&&_COMPILER_VERSION>=700
211/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
212 (default) */
213extern char *ctermid_r(char *);
214#endif
215
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000216#ifndef HAVE_UNISTD_H
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000217#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000218extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000219#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000220extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000221#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000222#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000223extern int chdir(char *);
224extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000225#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000226extern int chdir(const char *);
227extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000228#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000229extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000230/*#ifdef HAVE_FCHMOD
231extern int fchmod(int, mode_t);
232#endif*/
233/*#ifdef HAVE_LCHMOD
234extern int lchmod(const char *, mode_t);
235#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000236extern int chown(const char *, uid_t, gid_t);
237extern char *getcwd(char *, int);
238extern char *strerror(int);
239extern int link(const char *, const char *);
240extern int rename(const char *, const char *);
241extern int stat(const char *, struct stat *);
242extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000244extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000245#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000247extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000248#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000250
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000251#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000252
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000253#ifdef HAVE_POSIX_SPAWN
254#include <spawn.h>
255#endif
256
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#ifdef HAVE_UTIME_H
258#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000259#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000261#ifdef HAVE_SYS_UTIME_H
262#include <sys/utime.h>
263#define HAVE_UTIME_H /* pretend we do for the rest of this file */
264#endif /* HAVE_SYS_UTIME_H */
265
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266#ifdef HAVE_SYS_TIMES_H
267#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000268#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269
270#ifdef HAVE_SYS_PARAM_H
271#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000272#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273
274#ifdef HAVE_SYS_UTSNAME_H
275#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000276#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#define NAMLEN(dirent) strlen((dirent)->d_name)
281#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000282#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000283#include <direct.h>
284#define NAMLEN(dirent) strlen((dirent)->d_name)
285#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000286#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000287#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000289#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000291#endif
292#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000294#endif
295#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000297#endif
298#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000300#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000301#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000302#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000303#endif
304#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000305#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000306#endif
307#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000308#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000309#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000310#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000311#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000312#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100313#ifndef IO_REPARSE_TAG_MOUNT_POINT
314#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
315#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000316#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000317#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000319#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000320#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000321#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
322#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000323static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000324#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000325#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000326
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328#if defined(PATH_MAX) && PATH_MAX > 1024
329#define MAXPATHLEN PATH_MAX
330#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000331#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000332#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000333#endif /* MAXPATHLEN */
334
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000335#ifdef UNION_WAIT
336/* Emulate some macros on systems that have a union instead of macros */
337
338#ifndef WIFEXITED
339#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
340#endif
341
342#ifndef WEXITSTATUS
343#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
344#endif
345
346#ifndef WTERMSIG
347#define WTERMSIG(u_wait) ((u_wait).w_termsig)
348#endif
349
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000350#define WAIT_TYPE union wait
351#define WAIT_STATUS_INT(s) (s.w_status)
352
353#else /* !UNION_WAIT */
354#define WAIT_TYPE int
355#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000356#endif /* UNION_WAIT */
357
Greg Wardb48bc172000-03-01 21:51:56 +0000358/* Don't use the "_r" form if we don't need it (also, won't have a
359 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200360#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000361#define USE_CTERMID_R
362#endif
363
Fred Drake699f3522000-06-29 21:12:41 +0000364/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000365#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000366#undef FSTAT
367#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200368#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000369# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700370# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200371# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800372# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000373#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000374# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700375# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000376# define FSTAT fstat
377# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000378#endif
379
Tim Peters11b23062003-04-23 02:39:17 +0000380#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000381#include <sys/mkdev.h>
382#else
383#if defined(MAJOR_IN_SYSMACROS)
384#include <sys/sysmacros.h>
385#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000386#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
387#include <sys/mkdev.h>
388#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000389#endif
Fred Drake699f3522000-06-29 21:12:41 +0000390
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200391#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100392#define INITFUNC PyInit_nt
393#define MODNAME "nt"
394#else
395#define INITFUNC PyInit_posix
396#define MODNAME "posix"
397#endif
398
jcea6c51d512018-01-28 14:00:08 +0100399#if defined(__sun)
400/* Something to implement in autoconf, not present in autoconf 2.69 */
401#define HAVE_STRUCT_STAT_ST_FSTYPE 1
402#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200403
404#ifdef HAVE_FORK
405static void
406run_at_forkers(PyObject *lst, int reverse)
407{
408 Py_ssize_t i;
409 PyObject *cpy;
410
411 if (lst != NULL) {
412 assert(PyList_CheckExact(lst));
413
414 /* Use a list copy in case register_at_fork() is called from
415 * one of the callbacks.
416 */
417 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
418 if (cpy == NULL)
419 PyErr_WriteUnraisable(lst);
420 else {
421 if (reverse)
422 PyList_Reverse(cpy);
423 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
424 PyObject *func, *res;
425 func = PyList_GET_ITEM(cpy, i);
426 res = PyObject_CallObject(func, NULL);
427 if (res == NULL)
428 PyErr_WriteUnraisable(func);
429 else
430 Py_DECREF(res);
431 }
432 Py_DECREF(cpy);
433 }
434 }
435}
436
437void
438PyOS_BeforeFork(void)
439{
440 run_at_forkers(PyThreadState_Get()->interp->before_forkers, 1);
441
442 _PyImport_AcquireLock();
443}
444
445void
446PyOS_AfterFork_Parent(void)
447{
448 if (_PyImport_ReleaseLock() <= 0)
449 Py_FatalError("failed releasing import lock after fork");
450
451 run_at_forkers(PyThreadState_Get()->interp->after_forkers_parent, 0);
452}
453
454void
455PyOS_AfterFork_Child(void)
456{
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200457 _PyGILState_Reinit();
458 PyEval_ReInitThreads();
459 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200460 _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 Storchaka1180e5a2017-07-11 06:36:46 +03001040 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001041 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001042 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1043 "%s%s%s should be %s, not %.200s",
1044 path->function_name ? path->function_name : "",
1045 path->function_name ? ": " : "",
1046 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001047 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1048 "integer or None" :
1049 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1050 path->nullable ? "string, bytes, os.PathLike or None" :
1051 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001052 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001053 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001054 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001055 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001056 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001057 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001058 }
1059 }
Steve Dowercc16be82016-09-08 10:35:16 -07001060 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001061 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001062 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001063 }
1064 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001065#ifdef MS_WINDOWS
1066 path->narrow = FALSE;
1067#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001068 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001069#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001070 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001071 }
1072 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001073 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001074 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1075 path->function_name ? path->function_name : "",
1076 path->function_name ? ": " : "",
1077 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001078 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1079 "integer or None" :
1080 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1081 path->nullable ? "string, bytes, os.PathLike or None" :
1082 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001083 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001084 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001085 }
1086
Larry Hastings9cf065c2012-06-22 16:30:09 -07001087 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001088 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001089 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001090 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001091 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001092 }
1093
Steve Dowercc16be82016-09-08 10:35:16 -07001094#ifdef MS_WINDOWS
1095 wo = PyUnicode_DecodeFSDefaultAndSize(
1096 narrow,
1097 length
1098 );
1099 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001100 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001101 }
1102
Xiang Zhang04316c42017-01-08 23:26:57 +08001103 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001104 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001105 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001106 }
1107 if (length > 32767) {
1108 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001109 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001110 }
1111 if (wcslen(wide) != length) {
1112 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001113 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001114 }
1115 path->wide = wide;
1116 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001117 path->cleanup = wo;
1118 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001119#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001120 path->wide = NULL;
1121 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001122 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001123 /* Still a reference owned by path->object, don't have to
1124 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001125 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001126 }
1127 else {
1128 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001129 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001130#endif
1131 path->fd = -1;
1132
1133 success_exit:
1134 path->length = length;
1135 path->object = o;
1136 return Py_CLEANUP_SUPPORTED;
1137
1138 error_exit:
1139 Py_XDECREF(o);
1140 Py_XDECREF(bytes);
1141#ifdef MS_WINDOWS
1142 Py_XDECREF(wo);
1143#endif
1144 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001145}
1146
1147static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001148argument_unavailable_error(const char *function_name, const char *argument_name)
1149{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001150 PyErr_Format(PyExc_NotImplementedError,
1151 "%s%s%s unavailable on this platform",
1152 (function_name != NULL) ? function_name : "",
1153 (function_name != NULL) ? ": ": "",
1154 argument_name);
1155}
1156
1157static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001158dir_fd_unavailable(PyObject *o, void *p)
1159{
1160 int dir_fd;
1161 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001162 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001163 if (dir_fd != DEFAULT_DIR_FD) {
1164 argument_unavailable_error(NULL, "dir_fd");
1165 return 0;
1166 }
1167 *(int *)p = dir_fd;
1168 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001169}
1170
1171static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001172fd_specified(const char *function_name, int fd)
1173{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001174 if (fd == -1)
1175 return 0;
1176
1177 argument_unavailable_error(function_name, "fd");
1178 return 1;
1179}
1180
1181static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001182follow_symlinks_specified(const char *function_name, int follow_symlinks)
1183{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001184 if (follow_symlinks)
1185 return 0;
1186
1187 argument_unavailable_error(function_name, "follow_symlinks");
1188 return 1;
1189}
1190
1191static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001192path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1193{
Steve Dowercc16be82016-09-08 10:35:16 -07001194 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1195#ifndef MS_WINDOWS
1196 && !path->narrow
1197#endif
1198 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001199 PyErr_Format(PyExc_ValueError,
1200 "%s: can't specify dir_fd without matching path",
1201 function_name);
1202 return 1;
1203 }
1204 return 0;
1205}
1206
1207static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001208dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1209{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001210 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1211 PyErr_Format(PyExc_ValueError,
1212 "%s: can't specify both dir_fd and fd",
1213 function_name);
1214 return 1;
1215 }
1216 return 0;
1217}
1218
1219static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001220fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1221 int follow_symlinks)
1222{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001223 if ((fd > 0) && (!follow_symlinks)) {
1224 PyErr_Format(PyExc_ValueError,
1225 "%s: cannot use fd and follow_symlinks together",
1226 function_name);
1227 return 1;
1228 }
1229 return 0;
1230}
1231
1232static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001233dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1234 int follow_symlinks)
1235{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001236 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1237 PyErr_Format(PyExc_ValueError,
1238 "%s: cannot use dir_fd and follow_symlinks together",
1239 function_name);
1240 return 1;
1241 }
1242 return 0;
1243}
1244
Larry Hastings2f936352014-08-05 14:04:04 +10001245#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001246 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001247#else
Larry Hastings2f936352014-08-05 14:04:04 +10001248 typedef off_t Py_off_t;
1249#endif
1250
1251static int
1252Py_off_t_converter(PyObject *arg, void *addr)
1253{
1254#ifdef HAVE_LARGEFILE_SUPPORT
1255 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1256#else
1257 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001258#endif
1259 if (PyErr_Occurred())
1260 return 0;
1261 return 1;
1262}
Larry Hastings2f936352014-08-05 14:04:04 +10001263
1264static PyObject *
1265PyLong_FromPy_off_t(Py_off_t offset)
1266{
1267#ifdef HAVE_LARGEFILE_SUPPORT
1268 return PyLong_FromLongLong(offset);
1269#else
1270 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001271#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001272}
1273
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001274#ifdef HAVE_SIGSET_T
1275/* Convert an iterable of integers to a sigset.
1276 Return 1 on success, return 0 and raise an exception on error. */
1277int
1278_Py_Sigset_Converter(PyObject *obj, void *addr)
1279{
1280 sigset_t *mask = (sigset_t *)addr;
1281 PyObject *iterator, *item;
1282 long signum;
1283 int overflow;
1284
1285 if (sigemptyset(mask)) {
1286 /* Probably only if mask == NULL. */
1287 PyErr_SetFromErrno(PyExc_OSError);
1288 return 0;
1289 }
1290
1291 iterator = PyObject_GetIter(obj);
1292 if (iterator == NULL) {
1293 return 0;
1294 }
1295
1296 while ((item = PyIter_Next(iterator)) != NULL) {
1297 signum = PyLong_AsLongAndOverflow(item, &overflow);
1298 Py_DECREF(item);
1299 if (signum <= 0 || signum >= NSIG) {
1300 if (overflow || signum != -1 || !PyErr_Occurred()) {
1301 PyErr_Format(PyExc_ValueError,
1302 "signal number %ld out of range", signum);
1303 }
1304 goto error;
1305 }
1306 if (sigaddset(mask, (int)signum)) {
1307 if (errno != EINVAL) {
1308 /* Probably impossible */
1309 PyErr_SetFromErrno(PyExc_OSError);
1310 goto error;
1311 }
1312 /* For backwards compatibility, allow idioms such as
1313 * `range(1, NSIG)` but warn about invalid signal numbers
1314 */
1315 const char msg[] =
1316 "invalid signal number %ld, please use valid_signals()";
1317 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1318 goto error;
1319 }
1320 }
1321 }
1322 if (!PyErr_Occurred()) {
1323 Py_DECREF(iterator);
1324 return 1;
1325 }
1326
1327error:
1328 Py_DECREF(iterator);
1329 return 0;
1330}
1331#endif /* HAVE_SIGSET_T */
1332
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001333#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001334
1335static int
Brian Curtind25aef52011-06-13 15:16:04 -05001336win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001337{
Martin Panter70214ad2016-08-04 02:38:59 +00001338 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1339 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001340 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001341
1342 if (0 == DeviceIoControl(
1343 reparse_point_handle,
1344 FSCTL_GET_REPARSE_POINT,
1345 NULL, 0, /* in buffer */
1346 target_buffer, sizeof(target_buffer),
1347 &n_bytes_returned,
1348 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001349 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001350
1351 if (reparse_tag)
1352 *reparse_tag = rdb->ReparseTag;
1353
Brian Curtind25aef52011-06-13 15:16:04 -05001354 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001355}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001356
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001357#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001358
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001359/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001360#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001361/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001362** environ directly, we must obtain it with _NSGetEnviron(). See also
1363** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001364*/
1365#include <crt_externs.h>
1366static char **environ;
1367#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001368extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001369#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001370
Barry Warsaw53699e91996-12-10 23:23:01 +00001371static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001372convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001373{
Victor Stinner8c62be82010-05-06 00:08:46 +00001374 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001375#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001376 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001377#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001378 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001379#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001380
Victor Stinner8c62be82010-05-06 00:08:46 +00001381 d = PyDict_New();
1382 if (d == NULL)
1383 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001384#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001385 if (environ == NULL)
1386 environ = *_NSGetEnviron();
1387#endif
1388#ifdef MS_WINDOWS
1389 /* _wenviron must be initialized in this way if the program is started
1390 through main() instead of wmain(). */
1391 _wgetenv(L"");
1392 if (_wenviron == NULL)
1393 return d;
1394 /* This part ignores errors */
1395 for (e = _wenviron; *e != NULL; e++) {
1396 PyObject *k;
1397 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001398 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001399 if (p == NULL)
1400 continue;
1401 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1402 if (k == NULL) {
1403 PyErr_Clear();
1404 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001405 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001406 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1407 if (v == NULL) {
1408 PyErr_Clear();
1409 Py_DECREF(k);
1410 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001411 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001412 if (PyDict_GetItem(d, k) == NULL) {
1413 if (PyDict_SetItem(d, k, v) != 0)
1414 PyErr_Clear();
1415 }
1416 Py_DECREF(k);
1417 Py_DECREF(v);
1418 }
1419#else
1420 if (environ == NULL)
1421 return d;
1422 /* This part ignores errors */
1423 for (e = environ; *e != NULL; e++) {
1424 PyObject *k;
1425 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001426 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001427 if (p == NULL)
1428 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001429 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001430 if (k == NULL) {
1431 PyErr_Clear();
1432 continue;
1433 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001434 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001435 if (v == NULL) {
1436 PyErr_Clear();
1437 Py_DECREF(k);
1438 continue;
1439 }
1440 if (PyDict_GetItem(d, k) == NULL) {
1441 if (PyDict_SetItem(d, k, v) != 0)
1442 PyErr_Clear();
1443 }
1444 Py_DECREF(k);
1445 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001446 }
1447#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001448 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001449}
1450
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001451/* Set a POSIX-specific error from errno, and return NULL */
1452
Barry Warsawd58d7641998-07-23 16:14:40 +00001453static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001454posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001455{
Victor Stinner8c62be82010-05-06 00:08:46 +00001456 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001457}
Mark Hammondef8b6542001-05-13 08:04:26 +00001458
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001459#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001460static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001461win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001462{
Victor Stinner8c62be82010-05-06 00:08:46 +00001463 /* XXX We should pass the function name along in the future.
1464 (winreg.c also wants to pass the function name.)
1465 This would however require an additional param to the
1466 Windows error object, which is non-trivial.
1467 */
1468 errno = GetLastError();
1469 if (filename)
1470 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1471 else
1472 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001473}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001474
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001475static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001476win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001477{
1478 /* XXX - see win32_error for comments on 'function' */
1479 errno = GetLastError();
1480 if (filename)
1481 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001482 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001483 errno,
1484 filename);
1485 else
1486 return PyErr_SetFromWindowsErr(errno);
1487}
1488
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001489#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001490
Larry Hastings9cf065c2012-06-22 16:30:09 -07001491static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001492path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001493{
1494#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001495 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1496 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001497#else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001498 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001499#endif
1500}
1501
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001502static PyObject *
1503path_object_error2(PyObject *path, PyObject *path2)
1504{
1505#ifdef MS_WINDOWS
1506 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1507 PyExc_OSError, 0, path, path2);
1508#else
1509 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1510#endif
1511}
1512
1513static PyObject *
1514path_error(path_t *path)
1515{
1516 return path_object_error(path->object);
1517}
Larry Hastings31826802013-10-19 00:09:25 -07001518
Larry Hastingsb0827312014-02-09 22:05:19 -08001519static PyObject *
1520path_error2(path_t *path, path_t *path2)
1521{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001522 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001523}
1524
1525
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001526/* POSIX generic methods */
1527
Larry Hastings2f936352014-08-05 14:04:04 +10001528static int
1529fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001530{
Victor Stinner8c62be82010-05-06 00:08:46 +00001531 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001532 int *pointer = (int *)p;
1533 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001534 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001535 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001536 *pointer = fd;
1537 return 1;
1538}
1539
1540static PyObject *
1541posix_fildes_fd(int fd, int (*func)(int))
1542{
1543 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001544 int async_err = 0;
1545
1546 do {
1547 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001548 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001549 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001550 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001551 Py_END_ALLOW_THREADS
1552 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1553 if (res != 0)
1554 return (!async_err) ? posix_error() : NULL;
1555 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001556}
Guido van Rossum21142a01999-01-08 21:05:37 +00001557
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001558
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001559#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001560/* This is a reimplementation of the C library's chdir function,
1561 but one that produces Win32 errors instead of DOS error codes.
1562 chdir is essentially a wrapper around SetCurrentDirectory; however,
1563 it also needs to set "magic" environment variables indicating
1564 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001565static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001566win32_wchdir(LPCWSTR path)
1567{
Victor Stinnered537822015-12-13 21:40:26 +01001568 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001569 int result;
1570 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001571
Victor Stinner8c62be82010-05-06 00:08:46 +00001572 if(!SetCurrentDirectoryW(path))
1573 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001574 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001575 if (!result)
1576 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001577 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001578 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001579 if (!new_path) {
1580 SetLastError(ERROR_OUTOFMEMORY);
1581 return FALSE;
1582 }
1583 result = GetCurrentDirectoryW(result, new_path);
1584 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001585 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001586 return FALSE;
1587 }
1588 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001589 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1590 wcsncmp(new_path, L"//", 2) == 0);
1591 if (!is_unc_like_path) {
1592 env[1] = new_path[0];
1593 result = SetEnvironmentVariableW(env, new_path);
1594 }
Victor Stinnered537822015-12-13 21:40:26 +01001595 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001596 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001597 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001598}
1599#endif
1600
Martin v. Löwis14694662006-02-03 12:54:16 +00001601#ifdef MS_WINDOWS
1602/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1603 - time stamps are restricted to second resolution
1604 - file modification times suffer from forth-and-back conversions between
1605 UTC and local time
1606 Therefore, we implement our own stat, based on the Win32 API directly.
1607*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001608#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001609#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001610
Victor Stinner6036e442015-03-08 01:58:04 +01001611static void
Steve Dowercc16be82016-09-08 10:35:16 -07001612find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1613 BY_HANDLE_FILE_INFORMATION *info,
1614 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001615{
1616 memset(info, 0, sizeof(*info));
1617 info->dwFileAttributes = pFileData->dwFileAttributes;
1618 info->ftCreationTime = pFileData->ftCreationTime;
1619 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1620 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1621 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1622 info->nFileSizeLow = pFileData->nFileSizeLow;
1623/* info->nNumberOfLinks = 1; */
1624 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1625 *reparse_tag = pFileData->dwReserved0;
1626 else
1627 *reparse_tag = 0;
1628}
1629
Guido van Rossumd8faa362007-04-27 19:54:29 +00001630static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001631attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001632{
Victor Stinner8c62be82010-05-06 00:08:46 +00001633 HANDLE hFindFile;
1634 WIN32_FIND_DATAW FileData;
1635 hFindFile = FindFirstFileW(pszFile, &FileData);
1636 if (hFindFile == INVALID_HANDLE_VALUE)
1637 return FALSE;
1638 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001639 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001640 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001641}
1642
Brian Curtind25aef52011-06-13 15:16:04 -05001643static BOOL
1644get_target_path(HANDLE hdl, wchar_t **target_path)
1645{
1646 int buf_size, result_length;
1647 wchar_t *buf;
1648
1649 /* We have a good handle to the target, use it to determine
1650 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001651 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1652 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001653 if(!buf_size)
1654 return FALSE;
1655
Victor Stinnerc36674a2016-03-16 14:30:16 +01001656 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001657 if (!buf) {
1658 SetLastError(ERROR_OUTOFMEMORY);
1659 return FALSE;
1660 }
1661
Steve Dower2ea51c92015-03-20 21:49:12 -07001662 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001663 buf, buf_size, VOLUME_NAME_DOS);
1664
1665 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001666 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001667 return FALSE;
1668 }
1669
1670 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001671 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001672 return FALSE;
1673 }
1674
1675 buf[result_length] = 0;
1676
1677 *target_path = buf;
1678 return TRUE;
1679}
1680
1681static int
Steve Dowercc16be82016-09-08 10:35:16 -07001682win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001683 BOOL traverse)
1684{
Victor Stinner26de69d2011-06-17 15:15:38 +02001685 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001686 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001687 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001688 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001689 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001690 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001691
Steve Dowercc16be82016-09-08 10:35:16 -07001692 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001693 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001694 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001695 0, /* share mode */
1696 NULL, /* security attributes */
1697 OPEN_EXISTING,
1698 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001699 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1700 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001701 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001702 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1703 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001704 NULL);
1705
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001706 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001707 /* Either the target doesn't exist, or we don't have access to
1708 get a handle to it. If the former, we need to return an error.
1709 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001710 DWORD lastError = GetLastError();
1711 if (lastError != ERROR_ACCESS_DENIED &&
1712 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001713 return -1;
1714 /* Could not get attributes on open file. Fall back to
1715 reading the directory. */
1716 if (!attributes_from_dir(path, &info, &reparse_tag))
1717 /* Very strange. This should not fail now */
1718 return -1;
1719 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1720 if (traverse) {
1721 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001722 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001723 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001724 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001725 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001726 } else {
1727 if (!GetFileInformationByHandle(hFile, &info)) {
1728 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001729 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001730 }
1731 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001732 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1733 return -1;
1734
1735 /* Close the outer open file handle now that we're about to
1736 reopen it with different flags. */
1737 if (!CloseHandle(hFile))
1738 return -1;
1739
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001740 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001741 /* In order to call GetFinalPathNameByHandle we need to open
1742 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001743 hFile2 = CreateFileW(
1744 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1745 NULL, OPEN_EXISTING,
1746 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1747 NULL);
1748 if (hFile2 == INVALID_HANDLE_VALUE)
1749 return -1;
1750
1751 if (!get_target_path(hFile2, &target_path))
1752 return -1;
1753
Steve Dowercc16be82016-09-08 10:35:16 -07001754 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001755 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001756 return code;
1757 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001758 } else
1759 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001760 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001761 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001762
1763 /* Set S_IEXEC if it is an .exe, .bat, ... */
1764 dot = wcsrchr(path, '.');
1765 if (dot) {
1766 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1767 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1768 result->st_mode |= 0111;
1769 }
1770 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001771}
1772
1773static int
Steve Dowercc16be82016-09-08 10:35:16 -07001774win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001775{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001776 /* Protocol violation: we explicitly clear errno, instead of
1777 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001778 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001779 errno = 0;
1780 return code;
1781}
Brian Curtind25aef52011-06-13 15:16:04 -05001782/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001783
1784 In Posix, stat automatically traverses symlinks and returns the stat
1785 structure for the target. In Windows, the equivalent GetFileAttributes by
1786 default does not traverse symlinks and instead returns attributes for
1787 the symlink.
1788
1789 Therefore, win32_lstat will get the attributes traditionally, and
1790 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001791 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001792
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001793static int
Steve Dowercc16be82016-09-08 10:35:16 -07001794win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001795{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001796 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001797}
1798
Victor Stinner8c62be82010-05-06 00:08:46 +00001799static int
Steve Dowercc16be82016-09-08 10:35:16 -07001800win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001801{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001802 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001803}
1804
Martin v. Löwis14694662006-02-03 12:54:16 +00001805#endif /* MS_WINDOWS */
1806
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001807PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001808"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001809This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001810 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001811or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1812\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001813Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1814or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001815\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001816See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001817
1818static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001819 {"st_mode", "protection bits"},
1820 {"st_ino", "inode"},
1821 {"st_dev", "device"},
1822 {"st_nlink", "number of hard links"},
1823 {"st_uid", "user ID of owner"},
1824 {"st_gid", "group ID of owner"},
1825 {"st_size", "total size, in bytes"},
1826 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1827 {NULL, "integer time of last access"},
1828 {NULL, "integer time of last modification"},
1829 {NULL, "integer time of last change"},
1830 {"st_atime", "time of last access"},
1831 {"st_mtime", "time of last modification"},
1832 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001833 {"st_atime_ns", "time of last access in nanoseconds"},
1834 {"st_mtime_ns", "time of last modification in nanoseconds"},
1835 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001836#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001837 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001838#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001839#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001840 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001841#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001842#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001843 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001844#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001845#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001847#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001848#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001849 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001850#endif
1851#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001852 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001853#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001854#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1855 {"st_file_attributes", "Windows file attribute bits"},
1856#endif
jcea6c51d512018-01-28 14:00:08 +01001857#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1858 {"st_fstype", "Type of filesystem"},
1859#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001860 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001861};
1862
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001863#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001864#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001865#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001866#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001867#endif
1868
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001869#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001870#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1871#else
1872#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1873#endif
1874
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001875#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001876#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1877#else
1878#define ST_RDEV_IDX ST_BLOCKS_IDX
1879#endif
1880
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001881#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1882#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1883#else
1884#define ST_FLAGS_IDX ST_RDEV_IDX
1885#endif
1886
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001887#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001888#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001889#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001890#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001891#endif
1892
1893#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1894#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1895#else
1896#define ST_BIRTHTIME_IDX ST_GEN_IDX
1897#endif
1898
Zachary Ware63f277b2014-06-19 09:46:37 -05001899#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1900#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1901#else
1902#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1903#endif
1904
jcea6c51d512018-01-28 14:00:08 +01001905#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1906#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1907#else
1908#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1909#endif
1910
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001911static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001912 "stat_result", /* name */
1913 stat_result__doc__, /* doc */
1914 stat_result_fields,
1915 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001916};
1917
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001918PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001919"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1920This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001921 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001922or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001923\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001924See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001925
1926static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001927 {"f_bsize", },
1928 {"f_frsize", },
1929 {"f_blocks", },
1930 {"f_bfree", },
1931 {"f_bavail", },
1932 {"f_files", },
1933 {"f_ffree", },
1934 {"f_favail", },
1935 {"f_flag", },
1936 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001937 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001939};
1940
1941static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001942 "statvfs_result", /* name */
1943 statvfs_result__doc__, /* doc */
1944 statvfs_result_fields,
1945 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001946};
1947
Ross Lagerwall7807c352011-03-17 20:20:30 +02001948#if defined(HAVE_WAITID) && !defined(__APPLE__)
1949PyDoc_STRVAR(waitid_result__doc__,
1950"waitid_result: Result from waitid.\n\n\
1951This object may be accessed either as a tuple of\n\
1952 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1953or via the attributes si_pid, si_uid, and so on.\n\
1954\n\
1955See os.waitid for more information.");
1956
1957static PyStructSequence_Field waitid_result_fields[] = {
1958 {"si_pid", },
1959 {"si_uid", },
1960 {"si_signo", },
1961 {"si_status", },
1962 {"si_code", },
1963 {0}
1964};
1965
1966static PyStructSequence_Desc waitid_result_desc = {
1967 "waitid_result", /* name */
1968 waitid_result__doc__, /* doc */
1969 waitid_result_fields,
1970 5
1971};
1972static PyTypeObject WaitidResultType;
1973#endif
1974
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001975static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001976static PyTypeObject StatResultType;
1977static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001978#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001979static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001980#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001981static newfunc structseq_new;
1982
1983static PyObject *
1984statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1985{
Victor Stinner8c62be82010-05-06 00:08:46 +00001986 PyStructSequence *result;
1987 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001988
Victor Stinner8c62be82010-05-06 00:08:46 +00001989 result = (PyStructSequence*)structseq_new(type, args, kwds);
1990 if (!result)
1991 return NULL;
1992 /* If we have been initialized from a tuple,
1993 st_?time might be set to None. Initialize it
1994 from the int slots. */
1995 for (i = 7; i <= 9; i++) {
1996 if (result->ob_item[i+3] == Py_None) {
1997 Py_DECREF(Py_None);
1998 Py_INCREF(result->ob_item[i]);
1999 result->ob_item[i+3] = result->ob_item[i];
2000 }
2001 }
2002 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002003}
2004
2005
Larry Hastings6fe20b32012-04-19 15:07:49 -07002006static PyObject *billion = NULL;
2007
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002008static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002009fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002010{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002011 PyObject *s = _PyLong_FromTime_t(sec);
2012 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2013 PyObject *s_in_ns = NULL;
2014 PyObject *ns_total = NULL;
2015 PyObject *float_s = NULL;
2016
2017 if (!(s && ns_fractional))
2018 goto exit;
2019
2020 s_in_ns = PyNumber_Multiply(s, billion);
2021 if (!s_in_ns)
2022 goto exit;
2023
2024 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2025 if (!ns_total)
2026 goto exit;
2027
Victor Stinner01b5aab2017-10-24 02:02:00 -07002028 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2029 if (!float_s) {
2030 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002031 }
2032
2033 PyStructSequence_SET_ITEM(v, index, s);
2034 PyStructSequence_SET_ITEM(v, index+3, float_s);
2035 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2036 s = NULL;
2037 float_s = NULL;
2038 ns_total = NULL;
2039exit:
2040 Py_XDECREF(s);
2041 Py_XDECREF(ns_fractional);
2042 Py_XDECREF(s_in_ns);
2043 Py_XDECREF(ns_total);
2044 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002045}
2046
Tim Peters5aa91602002-01-30 05:46:57 +00002047/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002048 (used by posix_stat() and posix_fstat()) */
2049static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002050_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002051{
Victor Stinner8c62be82010-05-06 00:08:46 +00002052 unsigned long ansec, mnsec, cnsec;
2053 PyObject *v = PyStructSequence_New(&StatResultType);
2054 if (v == NULL)
2055 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002056
Victor Stinner8c62be82010-05-06 00:08:46 +00002057 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002058 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002059 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002060#ifdef MS_WINDOWS
2061 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002062#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002063 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002064#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002065 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002066#if defined(MS_WINDOWS)
2067 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2068 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2069#else
2070 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2071 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2072#endif
xdegaye50e86032017-05-22 11:15:08 +02002073 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2074 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002075
Martin v. Löwis14694662006-02-03 12:54:16 +00002076#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 ansec = st->st_atim.tv_nsec;
2078 mnsec = st->st_mtim.tv_nsec;
2079 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002080#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002081 ansec = st->st_atimespec.tv_nsec;
2082 mnsec = st->st_mtimespec.tv_nsec;
2083 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002084#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002085 ansec = st->st_atime_nsec;
2086 mnsec = st->st_mtime_nsec;
2087 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002088#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002089 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002090#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002091 fill_time(v, 7, st->st_atime, ansec);
2092 fill_time(v, 8, st->st_mtime, mnsec);
2093 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002094
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002095#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002096 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2097 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002098#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002099#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2101 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002102#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002103#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002104 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2105 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002106#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002107#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002108 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2109 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002110#endif
2111#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002112 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002113 PyObject *val;
2114 unsigned long bsec,bnsec;
2115 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002116#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002117 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002118#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002119 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002120#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002121 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002122 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2123 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002124 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002125#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002126#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002127 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2128 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002129#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002130#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2131 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2132 PyLong_FromUnsignedLong(st->st_file_attributes));
2133#endif
jcea6c51d512018-01-28 14:00:08 +01002134#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2135 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2136 PyUnicode_FromString(st->st_fstype));
2137#endif
Fred Drake699f3522000-06-29 21:12:41 +00002138
Victor Stinner8c62be82010-05-06 00:08:46 +00002139 if (PyErr_Occurred()) {
2140 Py_DECREF(v);
2141 return NULL;
2142 }
Fred Drake699f3522000-06-29 21:12:41 +00002143
Victor Stinner8c62be82010-05-06 00:08:46 +00002144 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002145}
2146
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002147/* POSIX methods */
2148
Guido van Rossum94f6f721999-01-06 18:42:14 +00002149
2150static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002151posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002152 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002153{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002154 STRUCT_STAT st;
2155 int result;
2156
2157#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2158 if (follow_symlinks_specified(function_name, follow_symlinks))
2159 return NULL;
2160#endif
2161
2162 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2163 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2164 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2165 return NULL;
2166
2167 Py_BEGIN_ALLOW_THREADS
2168 if (path->fd != -1)
2169 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002170#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002171 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002172 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002173 else
Steve Dowercc16be82016-09-08 10:35:16 -07002174 result = win32_lstat(path->wide, &st);
2175#else
2176 else
2177#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002178 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2179 result = LSTAT(path->narrow, &st);
2180 else
Steve Dowercc16be82016-09-08 10:35:16 -07002181#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002182#ifdef HAVE_FSTATAT
2183 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2184 result = fstatat(dir_fd, path->narrow, &st,
2185 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2186 else
Steve Dowercc16be82016-09-08 10:35:16 -07002187#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002188 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002189#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002190 Py_END_ALLOW_THREADS
2191
Victor Stinner292c8352012-10-30 02:17:38 +01002192 if (result != 0) {
2193 return path_error(path);
2194 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002195
2196 return _pystat_fromstructstat(&st);
2197}
2198
Larry Hastings2f936352014-08-05 14:04:04 +10002199/*[python input]
2200
2201for s in """
2202
2203FACCESSAT
2204FCHMODAT
2205FCHOWNAT
2206FSTATAT
2207LINKAT
2208MKDIRAT
2209MKFIFOAT
2210MKNODAT
2211OPENAT
2212READLINKAT
2213SYMLINKAT
2214UNLINKAT
2215
2216""".strip().split():
2217 s = s.strip()
2218 print("""
2219#ifdef HAVE_{s}
2220 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002221#else
Larry Hastings2f936352014-08-05 14:04:04 +10002222 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002223#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002224""".rstrip().format(s=s))
2225
2226for s in """
2227
2228FCHDIR
2229FCHMOD
2230FCHOWN
2231FDOPENDIR
2232FEXECVE
2233FPATHCONF
2234FSTATVFS
2235FTRUNCATE
2236
2237""".strip().split():
2238 s = s.strip()
2239 print("""
2240#ifdef HAVE_{s}
2241 #define PATH_HAVE_{s} 1
2242#else
2243 #define PATH_HAVE_{s} 0
2244#endif
2245
2246""".rstrip().format(s=s))
2247[python start generated code]*/
2248
2249#ifdef HAVE_FACCESSAT
2250 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2251#else
2252 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2253#endif
2254
2255#ifdef HAVE_FCHMODAT
2256 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2257#else
2258 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2259#endif
2260
2261#ifdef HAVE_FCHOWNAT
2262 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2263#else
2264 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2265#endif
2266
2267#ifdef HAVE_FSTATAT
2268 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2269#else
2270 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2271#endif
2272
2273#ifdef HAVE_LINKAT
2274 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2275#else
2276 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2277#endif
2278
2279#ifdef HAVE_MKDIRAT
2280 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2281#else
2282 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2283#endif
2284
2285#ifdef HAVE_MKFIFOAT
2286 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2287#else
2288 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2289#endif
2290
2291#ifdef HAVE_MKNODAT
2292 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2293#else
2294 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2295#endif
2296
2297#ifdef HAVE_OPENAT
2298 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2299#else
2300 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2301#endif
2302
2303#ifdef HAVE_READLINKAT
2304 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2305#else
2306 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2307#endif
2308
2309#ifdef HAVE_SYMLINKAT
2310 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2311#else
2312 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2313#endif
2314
2315#ifdef HAVE_UNLINKAT
2316 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2317#else
2318 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2319#endif
2320
2321#ifdef HAVE_FCHDIR
2322 #define PATH_HAVE_FCHDIR 1
2323#else
2324 #define PATH_HAVE_FCHDIR 0
2325#endif
2326
2327#ifdef HAVE_FCHMOD
2328 #define PATH_HAVE_FCHMOD 1
2329#else
2330 #define PATH_HAVE_FCHMOD 0
2331#endif
2332
2333#ifdef HAVE_FCHOWN
2334 #define PATH_HAVE_FCHOWN 1
2335#else
2336 #define PATH_HAVE_FCHOWN 0
2337#endif
2338
2339#ifdef HAVE_FDOPENDIR
2340 #define PATH_HAVE_FDOPENDIR 1
2341#else
2342 #define PATH_HAVE_FDOPENDIR 0
2343#endif
2344
2345#ifdef HAVE_FEXECVE
2346 #define PATH_HAVE_FEXECVE 1
2347#else
2348 #define PATH_HAVE_FEXECVE 0
2349#endif
2350
2351#ifdef HAVE_FPATHCONF
2352 #define PATH_HAVE_FPATHCONF 1
2353#else
2354 #define PATH_HAVE_FPATHCONF 0
2355#endif
2356
2357#ifdef HAVE_FSTATVFS
2358 #define PATH_HAVE_FSTATVFS 1
2359#else
2360 #define PATH_HAVE_FSTATVFS 0
2361#endif
2362
2363#ifdef HAVE_FTRUNCATE
2364 #define PATH_HAVE_FTRUNCATE 1
2365#else
2366 #define PATH_HAVE_FTRUNCATE 0
2367#endif
2368/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002369
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002370#ifdef MS_WINDOWS
2371 #undef PATH_HAVE_FTRUNCATE
2372 #define PATH_HAVE_FTRUNCATE 1
2373#endif
Larry Hastings31826802013-10-19 00:09:25 -07002374
Larry Hastings61272b72014-01-07 12:41:53 -08002375/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002376
2377class path_t_converter(CConverter):
2378
2379 type = "path_t"
2380 impl_by_reference = True
2381 parse_by_reference = True
2382
2383 converter = 'path_converter'
2384
2385 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002386 # right now path_t doesn't support default values.
2387 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002388 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002389 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002390
Larry Hastings2f936352014-08-05 14:04:04 +10002391 if self.c_default not in (None, 'Py_None'):
2392 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002393
2394 self.nullable = nullable
2395 self.allow_fd = allow_fd
2396
Larry Hastings7726ac92014-01-31 22:03:12 -08002397 def pre_render(self):
2398 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002399 if isinstance(value, str):
2400 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002401 return str(int(bool(value)))
2402
2403 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002404 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002405 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002406 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002407 strify(self.nullable),
2408 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002409 )
2410
2411 def cleanup(self):
2412 return "path_cleanup(&" + self.name + ");\n"
2413
2414
2415class dir_fd_converter(CConverter):
2416 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002417
Larry Hastings2f936352014-08-05 14:04:04 +10002418 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002419 if self.default in (unspecified, None):
2420 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002421 if isinstance(requires, str):
2422 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2423 else:
2424 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002425
Larry Hastings2f936352014-08-05 14:04:04 +10002426class fildes_converter(CConverter):
2427 type = 'int'
2428 converter = 'fildes_converter'
2429
2430class uid_t_converter(CConverter):
2431 type = "uid_t"
2432 converter = '_Py_Uid_Converter'
2433
2434class gid_t_converter(CConverter):
2435 type = "gid_t"
2436 converter = '_Py_Gid_Converter'
2437
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002438class dev_t_converter(CConverter):
2439 type = 'dev_t'
2440 converter = '_Py_Dev_Converter'
2441
2442class dev_t_return_converter(unsigned_long_return_converter):
2443 type = 'dev_t'
2444 conversion_fn = '_PyLong_FromDev'
2445 unsigned_cast = '(dev_t)'
2446
Larry Hastings2f936352014-08-05 14:04:04 +10002447class FSConverter_converter(CConverter):
2448 type = 'PyObject *'
2449 converter = 'PyUnicode_FSConverter'
2450 def converter_init(self):
2451 if self.default is not unspecified:
2452 fail("FSConverter_converter does not support default values")
2453 self.c_default = 'NULL'
2454
2455 def cleanup(self):
2456 return "Py_XDECREF(" + self.name + ");\n"
2457
2458class pid_t_converter(CConverter):
2459 type = 'pid_t'
2460 format_unit = '" _Py_PARSE_PID "'
2461
2462class idtype_t_converter(int_converter):
2463 type = 'idtype_t'
2464
2465class id_t_converter(CConverter):
2466 type = 'id_t'
2467 format_unit = '" _Py_PARSE_PID "'
2468
Benjamin Petersonca470632016-09-06 13:47:26 -07002469class intptr_t_converter(CConverter):
2470 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002471 format_unit = '" _Py_PARSE_INTPTR "'
2472
2473class Py_off_t_converter(CConverter):
2474 type = 'Py_off_t'
2475 converter = 'Py_off_t_converter'
2476
2477class Py_off_t_return_converter(long_return_converter):
2478 type = 'Py_off_t'
2479 conversion_fn = 'PyLong_FromPy_off_t'
2480
2481class path_confname_converter(CConverter):
2482 type="int"
2483 converter="conv_path_confname"
2484
2485class confstr_confname_converter(path_confname_converter):
2486 converter='conv_confstr_confname'
2487
2488class sysconf_confname_converter(path_confname_converter):
2489 converter="conv_sysconf_confname"
2490
2491class sched_param_converter(CConverter):
2492 type = 'struct sched_param'
2493 converter = 'convert_sched_param'
2494 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002495
Larry Hastings61272b72014-01-07 12:41:53 -08002496[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002497/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002498
Larry Hastings61272b72014-01-07 12:41:53 -08002499/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002500
Larry Hastings2a727912014-01-16 11:32:01 -08002501os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002502
2503 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002504 Path to be examined; can be string, bytes, path-like object or
2505 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002506
2507 *
2508
Larry Hastings2f936352014-08-05 14:04:04 +10002509 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002510 If not None, it should be a file descriptor open to a directory,
2511 and path should be a relative string; path will then be relative to
2512 that directory.
2513
2514 follow_symlinks: bool = True
2515 If False, and the last element of the path is a symbolic link,
2516 stat will examine the symbolic link itself instead of the file
2517 the link points to.
2518
2519Perform a stat system call on the given path.
2520
2521dir_fd and follow_symlinks may not be implemented
2522 on your platform. If they are unavailable, using them will raise a
2523 NotImplementedError.
2524
2525It's an error to use dir_fd or follow_symlinks when specifying path as
2526 an open file descriptor.
2527
Larry Hastings61272b72014-01-07 12:41:53 -08002528[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002529
Larry Hastings31826802013-10-19 00:09:25 -07002530static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002531os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002532/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002533{
2534 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2535}
2536
Larry Hastings2f936352014-08-05 14:04:04 +10002537
2538/*[clinic input]
2539os.lstat
2540
2541 path : path_t
2542
2543 *
2544
2545 dir_fd : dir_fd(requires='fstatat') = None
2546
2547Perform a stat system call on the given path, without following symbolic links.
2548
2549Like stat(), but do not follow symbolic links.
2550Equivalent to stat(path, follow_symlinks=False).
2551[clinic start generated code]*/
2552
Larry Hastings2f936352014-08-05 14:04:04 +10002553static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002554os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2555/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002556{
2557 int follow_symlinks = 0;
2558 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2559}
Larry Hastings31826802013-10-19 00:09:25 -07002560
Larry Hastings2f936352014-08-05 14:04:04 +10002561
Larry Hastings61272b72014-01-07 12:41:53 -08002562/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002563os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002564
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002565 path: path_t
2566 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002567
2568 mode: int
2569 Operating-system mode bitfield. Can be F_OK to test existence,
2570 or the inclusive-OR of R_OK, W_OK, and X_OK.
2571
2572 *
2573
Larry Hastings2f936352014-08-05 14:04:04 +10002574 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002575 If not None, it should be a file descriptor open to a directory,
2576 and path should be relative; path will then be relative to that
2577 directory.
2578
2579 effective_ids: bool = False
2580 If True, access will use the effective uid/gid instead of
2581 the real uid/gid.
2582
2583 follow_symlinks: bool = True
2584 If False, and the last element of the path is a symbolic link,
2585 access will examine the symbolic link itself instead of the file
2586 the link points to.
2587
2588Use the real uid/gid to test for access to a path.
2589
2590{parameters}
2591dir_fd, effective_ids, and follow_symlinks may not be implemented
2592 on your platform. If they are unavailable, using them will raise a
2593 NotImplementedError.
2594
2595Note that most operations will use the effective uid/gid, therefore this
2596 routine can be used in a suid/sgid environment to test if the invoking user
2597 has the specified access to the path.
2598
Larry Hastings61272b72014-01-07 12:41:53 -08002599[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002600
Larry Hastings2f936352014-08-05 14:04:04 +10002601static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002602os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002603 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002604/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002605{
Larry Hastings2f936352014-08-05 14:04:04 +10002606 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002607
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002608#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002609 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002610#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002611 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002612#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002613
Larry Hastings9cf065c2012-06-22 16:30:09 -07002614#ifndef HAVE_FACCESSAT
2615 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002616 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002617
2618 if (effective_ids) {
2619 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002620 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002621 }
2622#endif
2623
2624#ifdef MS_WINDOWS
2625 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002626 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002627 Py_END_ALLOW_THREADS
2628
2629 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002630 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002631 * * we didn't get a -1, and
2632 * * write access wasn't requested,
2633 * * or the file isn't read-only,
2634 * * or it's a directory.
2635 * (Directories cannot be read-only on Windows.)
2636 */
Larry Hastings2f936352014-08-05 14:04:04 +10002637 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002638 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002639 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002640 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002641#else
2642
2643 Py_BEGIN_ALLOW_THREADS
2644#ifdef HAVE_FACCESSAT
2645 if ((dir_fd != DEFAULT_DIR_FD) ||
2646 effective_ids ||
2647 !follow_symlinks) {
2648 int flags = 0;
2649 if (!follow_symlinks)
2650 flags |= AT_SYMLINK_NOFOLLOW;
2651 if (effective_ids)
2652 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002653 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002654 }
2655 else
2656#endif
Larry Hastings31826802013-10-19 00:09:25 -07002657 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002658 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002659 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002660#endif
2661
Larry Hastings9cf065c2012-06-22 16:30:09 -07002662 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002663}
2664
Guido van Rossumd371ff11999-01-25 16:12:23 +00002665#ifndef F_OK
2666#define F_OK 0
2667#endif
2668#ifndef R_OK
2669#define R_OK 4
2670#endif
2671#ifndef W_OK
2672#define W_OK 2
2673#endif
2674#ifndef X_OK
2675#define X_OK 1
2676#endif
2677
Larry Hastings31826802013-10-19 00:09:25 -07002678
Guido van Rossumd371ff11999-01-25 16:12:23 +00002679#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002680/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002681os.ttyname -> DecodeFSDefault
2682
2683 fd: int
2684 Integer file descriptor handle.
2685
2686 /
2687
2688Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002689[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002690
Larry Hastings31826802013-10-19 00:09:25 -07002691static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002692os_ttyname_impl(PyObject *module, int fd)
2693/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002694{
2695 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002696
Larry Hastings31826802013-10-19 00:09:25 -07002697 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002698 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002699 posix_error();
2700 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002701}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002702#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002703
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002704#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002705/*[clinic input]
2706os.ctermid
2707
2708Return the name of the controlling terminal for this process.
2709[clinic start generated code]*/
2710
Larry Hastings2f936352014-08-05 14:04:04 +10002711static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002712os_ctermid_impl(PyObject *module)
2713/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002714{
Victor Stinner8c62be82010-05-06 00:08:46 +00002715 char *ret;
2716 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002717
Greg Wardb48bc172000-03-01 21:51:56 +00002718#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002719 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002720#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002721 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002722#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002723 if (ret == NULL)
2724 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002725 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002726}
Larry Hastings2f936352014-08-05 14:04:04 +10002727#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002728
Larry Hastings2f936352014-08-05 14:04:04 +10002729
2730/*[clinic input]
2731os.chdir
2732
2733 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2734
2735Change the current working directory to the specified path.
2736
2737path may always be specified as a string.
2738On some platforms, path may also be specified as an open file descriptor.
2739 If this functionality is unavailable, using it raises an exception.
2740[clinic start generated code]*/
2741
Larry Hastings2f936352014-08-05 14:04:04 +10002742static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002743os_chdir_impl(PyObject *module, path_t *path)
2744/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002745{
2746 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002747
2748 Py_BEGIN_ALLOW_THREADS
2749#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002750 /* on unix, success = 0, on windows, success = !0 */
2751 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002752#else
2753#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002754 if (path->fd != -1)
2755 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002756 else
2757#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002758 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002759#endif
2760 Py_END_ALLOW_THREADS
2761
2762 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002763 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002764 }
2765
Larry Hastings2f936352014-08-05 14:04:04 +10002766 Py_RETURN_NONE;
2767}
2768
2769
2770#ifdef HAVE_FCHDIR
2771/*[clinic input]
2772os.fchdir
2773
2774 fd: fildes
2775
2776Change to the directory of the given file descriptor.
2777
2778fd must be opened on a directory, not a file.
2779Equivalent to os.chdir(fd).
2780
2781[clinic start generated code]*/
2782
Fred Drake4d1e64b2002-04-15 19:40:07 +00002783static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002784os_fchdir_impl(PyObject *module, int fd)
2785/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002786{
Larry Hastings2f936352014-08-05 14:04:04 +10002787 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002788}
2789#endif /* HAVE_FCHDIR */
2790
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002791
Larry Hastings2f936352014-08-05 14:04:04 +10002792/*[clinic input]
2793os.chmod
2794
2795 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2796 Path to be modified. May always be specified as a str or bytes.
2797 On some platforms, path may also be specified as an open file descriptor.
2798 If this functionality is unavailable, using it raises an exception.
2799
2800 mode: int
2801 Operating-system mode bitfield.
2802
2803 *
2804
2805 dir_fd : dir_fd(requires='fchmodat') = None
2806 If not None, it should be a file descriptor open to a directory,
2807 and path should be relative; path will then be relative to that
2808 directory.
2809
2810 follow_symlinks: bool = True
2811 If False, and the last element of the path is a symbolic link,
2812 chmod will modify the symbolic link itself instead of the file
2813 the link points to.
2814
2815Change the access permissions of a file.
2816
2817It is an error to use dir_fd or follow_symlinks when specifying path as
2818 an open file descriptor.
2819dir_fd and follow_symlinks may not be implemented on your platform.
2820 If they are unavailable, using them will raise a NotImplementedError.
2821
2822[clinic start generated code]*/
2823
Larry Hastings2f936352014-08-05 14:04:04 +10002824static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002825os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002826 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002827/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002828{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002830
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002831#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002832 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002833#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002834
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835#ifdef HAVE_FCHMODAT
2836 int fchmodat_nofollow_unsupported = 0;
2837#endif
2838
Larry Hastings9cf065c2012-06-22 16:30:09 -07002839#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2840 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002841 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002842#endif
2843
2844#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002845 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002846 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002847 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002848 result = 0;
2849 else {
2850 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002851 attr &= ~FILE_ATTRIBUTE_READONLY;
2852 else
2853 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002854 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855 }
2856 Py_END_ALLOW_THREADS
2857
2858 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002859 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002860 }
2861#else /* MS_WINDOWS */
2862 Py_BEGIN_ALLOW_THREADS
2863#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002864 if (path->fd != -1)
2865 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002866 else
2867#endif
2868#ifdef HAVE_LCHMOD
2869 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002870 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002871 else
2872#endif
2873#ifdef HAVE_FCHMODAT
2874 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2875 /*
2876 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2877 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002878 * and then says it isn't implemented yet.
2879 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002880 *
2881 * Once it is supported, os.chmod will automatically
2882 * support dir_fd and follow_symlinks=False. (Hopefully.)
2883 * Until then, we need to be careful what exception we raise.
2884 */
Larry Hastings2f936352014-08-05 14:04:04 +10002885 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002886 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2887 /*
2888 * But wait! We can't throw the exception without allowing threads,
2889 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2890 */
2891 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002892 result &&
2893 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2894 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002895 }
2896 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002897#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002898 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002899 Py_END_ALLOW_THREADS
2900
2901 if (result) {
2902#ifdef HAVE_FCHMODAT
2903 if (fchmodat_nofollow_unsupported) {
2904 if (dir_fd != DEFAULT_DIR_FD)
2905 dir_fd_and_follow_symlinks_invalid("chmod",
2906 dir_fd, follow_symlinks);
2907 else
2908 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002909 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002910 }
2911 else
2912#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002913 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002914 }
2915#endif
2916
Larry Hastings2f936352014-08-05 14:04:04 +10002917 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002918}
2919
Larry Hastings9cf065c2012-06-22 16:30:09 -07002920
Christian Heimes4e30a842007-11-30 22:12:06 +00002921#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002922/*[clinic input]
2923os.fchmod
2924
2925 fd: int
2926 mode: int
2927
2928Change the access permissions of the file given by file descriptor fd.
2929
2930Equivalent to os.chmod(fd, mode).
2931[clinic start generated code]*/
2932
Larry Hastings2f936352014-08-05 14:04:04 +10002933static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002934os_fchmod_impl(PyObject *module, int fd, int mode)
2935/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002936{
2937 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002938 int async_err = 0;
2939
2940 do {
2941 Py_BEGIN_ALLOW_THREADS
2942 res = fchmod(fd, mode);
2943 Py_END_ALLOW_THREADS
2944 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2945 if (res != 0)
2946 return (!async_err) ? posix_error() : NULL;
2947
Victor Stinner8c62be82010-05-06 00:08:46 +00002948 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002949}
2950#endif /* HAVE_FCHMOD */
2951
Larry Hastings2f936352014-08-05 14:04:04 +10002952
Christian Heimes4e30a842007-11-30 22:12:06 +00002953#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002954/*[clinic input]
2955os.lchmod
2956
2957 path: path_t
2958 mode: int
2959
2960Change the access permissions of a file, without following symbolic links.
2961
2962If path is a symlink, this affects the link itself rather than the target.
2963Equivalent to chmod(path, mode, follow_symlinks=False)."
2964[clinic start generated code]*/
2965
Larry Hastings2f936352014-08-05 14:04:04 +10002966static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002967os_lchmod_impl(PyObject *module, path_t *path, int mode)
2968/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002969{
Victor Stinner8c62be82010-05-06 00:08:46 +00002970 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002971 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002972 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002973 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002974 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002975 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002976 return NULL;
2977 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002978 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002979}
2980#endif /* HAVE_LCHMOD */
2981
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002982
Thomas Wouterscf297e42007-02-23 15:07:44 +00002983#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002984/*[clinic input]
2985os.chflags
2986
2987 path: path_t
2988 flags: unsigned_long(bitwise=True)
2989 follow_symlinks: bool=True
2990
2991Set file flags.
2992
2993If follow_symlinks is False, and the last element of the path is a symbolic
2994 link, chflags will change flags on the symbolic link itself instead of the
2995 file the link points to.
2996follow_symlinks may not be implemented on your platform. If it is
2997unavailable, using it will raise a NotImplementedError.
2998
2999[clinic start generated code]*/
3000
Larry Hastings2f936352014-08-05 14:04:04 +10003001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003002os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003003 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003004/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003005{
3006 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003007
3008#ifndef HAVE_LCHFLAGS
3009 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003010 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003011#endif
3012
Victor Stinner8c62be82010-05-06 00:08:46 +00003013 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003014#ifdef HAVE_LCHFLAGS
3015 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003016 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003017 else
3018#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003019 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003020 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003021
Larry Hastings2f936352014-08-05 14:04:04 +10003022 if (result)
3023 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003024
Larry Hastings2f936352014-08-05 14:04:04 +10003025 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003026}
3027#endif /* HAVE_CHFLAGS */
3028
Larry Hastings2f936352014-08-05 14:04:04 +10003029
Thomas Wouterscf297e42007-02-23 15:07:44 +00003030#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003031/*[clinic input]
3032os.lchflags
3033
3034 path: path_t
3035 flags: unsigned_long(bitwise=True)
3036
3037Set file flags.
3038
3039This function will not follow symbolic links.
3040Equivalent to chflags(path, flags, follow_symlinks=False).
3041[clinic start generated code]*/
3042
Larry Hastings2f936352014-08-05 14:04:04 +10003043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003044os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3045/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003046{
Victor Stinner8c62be82010-05-06 00:08:46 +00003047 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003048 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003049 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003050 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003051 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003052 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003053 }
Victor Stinner292c8352012-10-30 02:17:38 +01003054 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003055}
3056#endif /* HAVE_LCHFLAGS */
3057
Larry Hastings2f936352014-08-05 14:04:04 +10003058
Martin v. Löwis244edc82001-10-04 22:44:26 +00003059#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003060/*[clinic input]
3061os.chroot
3062 path: path_t
3063
3064Change root directory to path.
3065
3066[clinic start generated code]*/
3067
Larry Hastings2f936352014-08-05 14:04:04 +10003068static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003069os_chroot_impl(PyObject *module, path_t *path)
3070/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003071{
3072 int res;
3073 Py_BEGIN_ALLOW_THREADS
3074 res = chroot(path->narrow);
3075 Py_END_ALLOW_THREADS
3076 if (res < 0)
3077 return path_error(path);
3078 Py_RETURN_NONE;
3079}
3080#endif /* HAVE_CHROOT */
3081
Martin v. Löwis244edc82001-10-04 22:44:26 +00003082
Guido van Rossum21142a01999-01-08 21:05:37 +00003083#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003084/*[clinic input]
3085os.fsync
3086
3087 fd: fildes
3088
3089Force write of fd to disk.
3090[clinic start generated code]*/
3091
Larry Hastings2f936352014-08-05 14:04:04 +10003092static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003093os_fsync_impl(PyObject *module, int fd)
3094/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003095{
3096 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003097}
3098#endif /* HAVE_FSYNC */
3099
Larry Hastings2f936352014-08-05 14:04:04 +10003100
Ross Lagerwall7807c352011-03-17 20:20:30 +02003101#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003102/*[clinic input]
3103os.sync
3104
3105Force write of everything to disk.
3106[clinic start generated code]*/
3107
Larry Hastings2f936352014-08-05 14:04:04 +10003108static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003109os_sync_impl(PyObject *module)
3110/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003111{
3112 Py_BEGIN_ALLOW_THREADS
3113 sync();
3114 Py_END_ALLOW_THREADS
3115 Py_RETURN_NONE;
3116}
Larry Hastings2f936352014-08-05 14:04:04 +10003117#endif /* HAVE_SYNC */
3118
Ross Lagerwall7807c352011-03-17 20:20:30 +02003119
Guido van Rossum21142a01999-01-08 21:05:37 +00003120#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003121#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003122extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3123#endif
3124
Larry Hastings2f936352014-08-05 14:04:04 +10003125/*[clinic input]
3126os.fdatasync
3127
3128 fd: fildes
3129
3130Force write of fd to disk without forcing update of metadata.
3131[clinic start generated code]*/
3132
Larry Hastings2f936352014-08-05 14:04:04 +10003133static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003134os_fdatasync_impl(PyObject *module, int fd)
3135/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003136{
3137 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003138}
3139#endif /* HAVE_FDATASYNC */
3140
3141
Fredrik Lundh10723342000-07-10 16:38:09 +00003142#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003143/*[clinic input]
3144os.chown
3145
3146 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3147 Path to be examined; can be string, bytes, or open-file-descriptor int.
3148
3149 uid: uid_t
3150
3151 gid: gid_t
3152
3153 *
3154
3155 dir_fd : dir_fd(requires='fchownat') = None
3156 If not None, it should be a file descriptor open to a directory,
3157 and path should be relative; path will then be relative to that
3158 directory.
3159
3160 follow_symlinks: bool = True
3161 If False, and the last element of the path is a symbolic link,
3162 stat will examine the symbolic link itself instead of the file
3163 the link points to.
3164
3165Change the owner and group id of path to the numeric uid and gid.\
3166
3167path may always be specified as a string.
3168On some platforms, path may also be specified as an open file descriptor.
3169 If this functionality is unavailable, using it raises an exception.
3170If dir_fd is not None, it should be a file descriptor open to a directory,
3171 and path should be relative; path will then be relative to that directory.
3172If follow_symlinks is False, and the last element of the path is a symbolic
3173 link, chown will modify the symbolic link itself instead of the file the
3174 link points to.
3175It is an error to use dir_fd or follow_symlinks when specifying path as
3176 an open file descriptor.
3177dir_fd and follow_symlinks may not be implemented on your platform.
3178 If they are unavailable, using them will raise a NotImplementedError.
3179
3180[clinic start generated code]*/
3181
Larry Hastings2f936352014-08-05 14:04:04 +10003182static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003183os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003184 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003185/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003186{
3187 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003188
3189#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3190 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003191 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003193 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3194 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3195 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003196
3197#ifdef __APPLE__
3198 /*
3199 * This is for Mac OS X 10.3, which doesn't have lchown.
3200 * (But we still have an lchown symbol because of weak-linking.)
3201 * It doesn't have fchownat either. So there's no possibility
3202 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003203 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003204 if ((!follow_symlinks) && (lchown == NULL)) {
3205 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003206 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003207 }
3208#endif
3209
Victor Stinner8c62be82010-05-06 00:08:46 +00003210 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003211#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003212 if (path->fd != -1)
3213 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003214 else
3215#endif
3216#ifdef HAVE_LCHOWN
3217 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003218 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003219 else
3220#endif
3221#ifdef HAVE_FCHOWNAT
3222 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003223 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003224 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3225 else
3226#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003227 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003228 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003229
Larry Hastings2f936352014-08-05 14:04:04 +10003230 if (result)
3231 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003232
Larry Hastings2f936352014-08-05 14:04:04 +10003233 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003234}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003235#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003236
Larry Hastings2f936352014-08-05 14:04:04 +10003237
Christian Heimes4e30a842007-11-30 22:12:06 +00003238#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003239/*[clinic input]
3240os.fchown
3241
3242 fd: int
3243 uid: uid_t
3244 gid: gid_t
3245
3246Change the owner and group id of the file specified by file descriptor.
3247
3248Equivalent to os.chown(fd, uid, gid).
3249
3250[clinic start generated code]*/
3251
Larry Hastings2f936352014-08-05 14:04:04 +10003252static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003253os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3254/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003255{
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003257 int async_err = 0;
3258
3259 do {
3260 Py_BEGIN_ALLOW_THREADS
3261 res = fchown(fd, uid, gid);
3262 Py_END_ALLOW_THREADS
3263 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3264 if (res != 0)
3265 return (!async_err) ? posix_error() : NULL;
3266
Victor Stinner8c62be82010-05-06 00:08:46 +00003267 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003268}
3269#endif /* HAVE_FCHOWN */
3270
Larry Hastings2f936352014-08-05 14:04:04 +10003271
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003272#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003273/*[clinic input]
3274os.lchown
3275
3276 path : path_t
3277 uid: uid_t
3278 gid: gid_t
3279
3280Change the owner and group id of path to the numeric uid and gid.
3281
3282This function will not follow symbolic links.
3283Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3284[clinic start generated code]*/
3285
Larry Hastings2f936352014-08-05 14:04:04 +10003286static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003287os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3288/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003289{
Victor Stinner8c62be82010-05-06 00:08:46 +00003290 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003291 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003292 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003293 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003294 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003295 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003296 }
Larry Hastings2f936352014-08-05 14:04:04 +10003297 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003298}
3299#endif /* HAVE_LCHOWN */
3300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003301
Barry Warsaw53699e91996-12-10 23:23:01 +00003302static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003303posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003304{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003305 char *buf, *tmpbuf;
3306 char *cwd;
3307 const size_t chunk = 1024;
3308 size_t buflen = 0;
3309 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003310
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003311#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003312 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003313 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003314 wchar_t *wbuf2 = wbuf;
3315 PyObject *resobj;
3316 DWORD len;
3317 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003318 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003319 /* If the buffer is large enough, len does not include the
3320 terminating \0. If the buffer is too small, len includes
3321 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003322 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003323 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003324 if (wbuf2)
3325 len = GetCurrentDirectoryW(len, wbuf2);
3326 }
3327 Py_END_ALLOW_THREADS
3328 if (!wbuf2) {
3329 PyErr_NoMemory();
3330 return NULL;
3331 }
3332 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003333 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003334 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003335 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003336 }
3337 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003338 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003339 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 return resobj;
3341 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003342
3343 if (win32_warn_bytes_api())
3344 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003345#endif
3346
Victor Stinner4403d7d2015-04-25 00:16:10 +02003347 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003348 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003349 do {
3350 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003351#ifdef MS_WINDOWS
3352 if (buflen > INT_MAX) {
3353 PyErr_NoMemory();
3354 break;
3355 }
3356#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003357 tmpbuf = PyMem_RawRealloc(buf, buflen);
3358 if (tmpbuf == NULL)
3359 break;
3360
3361 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003362#ifdef MS_WINDOWS
3363 cwd = getcwd(buf, (int)buflen);
3364#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003365 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003366#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003367 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003369
3370 if (cwd == NULL) {
3371 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003373 }
3374
Victor Stinner8c62be82010-05-06 00:08:46 +00003375 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003376 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3377 else
3378 obj = PyUnicode_DecodeFSDefault(buf);
3379 PyMem_RawFree(buf);
3380
3381 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003382}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003383
Larry Hastings2f936352014-08-05 14:04:04 +10003384
3385/*[clinic input]
3386os.getcwd
3387
3388Return a unicode string representing the current working directory.
3389[clinic start generated code]*/
3390
Larry Hastings2f936352014-08-05 14:04:04 +10003391static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003392os_getcwd_impl(PyObject *module)
3393/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003394{
3395 return posix_getcwd(0);
3396}
3397
Larry Hastings2f936352014-08-05 14:04:04 +10003398
3399/*[clinic input]
3400os.getcwdb
3401
3402Return a bytes string representing the current working directory.
3403[clinic start generated code]*/
3404
Larry Hastings2f936352014-08-05 14:04:04 +10003405static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003406os_getcwdb_impl(PyObject *module)
3407/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003408{
3409 return posix_getcwd(1);
3410}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003411
Larry Hastings2f936352014-08-05 14:04:04 +10003412
Larry Hastings9cf065c2012-06-22 16:30:09 -07003413#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3414#define HAVE_LINK 1
3415#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003416
Guido van Rossumb6775db1994-08-01 11:34:53 +00003417#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003418/*[clinic input]
3419
3420os.link
3421
3422 src : path_t
3423 dst : path_t
3424 *
3425 src_dir_fd : dir_fd = None
3426 dst_dir_fd : dir_fd = None
3427 follow_symlinks: bool = True
3428
3429Create a hard link to a file.
3430
3431If either src_dir_fd or dst_dir_fd is not None, it should be a file
3432 descriptor open to a directory, and the respective path string (src or dst)
3433 should be relative; the path will then be relative to that directory.
3434If follow_symlinks is False, and the last element of src is a symbolic
3435 link, link will create a link to the symbolic link itself instead of the
3436 file the link points to.
3437src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3438 platform. If they are unavailable, using them will raise a
3439 NotImplementedError.
3440[clinic start generated code]*/
3441
Larry Hastings2f936352014-08-05 14:04:04 +10003442static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003443os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003444 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003445/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003446{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003447#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003448 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003449#else
3450 int result;
3451#endif
3452
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453#ifndef HAVE_LINKAT
3454 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3455 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003456 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 }
3458#endif
3459
Steve Dowercc16be82016-09-08 10:35:16 -07003460#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003461 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003462 PyErr_SetString(PyExc_NotImplementedError,
3463 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003464 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465 }
Steve Dowercc16be82016-09-08 10:35:16 -07003466#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003467
Brian Curtin1b9df392010-11-24 20:24:31 +00003468#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003469 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003470 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003472
Larry Hastings2f936352014-08-05 14:04:04 +10003473 if (!result)
3474 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475#else
3476 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003477#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3479 (dst_dir_fd != DEFAULT_DIR_FD) ||
3480 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003481 result = linkat(src_dir_fd, src->narrow,
3482 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003483 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3484 else
Steve Dowercc16be82016-09-08 10:35:16 -07003485#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003486 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003488
Larry Hastings2f936352014-08-05 14:04:04 +10003489 if (result)
3490 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003491#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003492
Larry Hastings2f936352014-08-05 14:04:04 +10003493 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003494}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003495#endif
3496
Brian Curtin1b9df392010-11-24 20:24:31 +00003497
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003498#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003499static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003500_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003501{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 PyObject *v;
3503 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3504 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003505 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003507 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003509
Steve Dowercc16be82016-09-08 10:35:16 -07003510 WIN32_FIND_DATAW wFileData;
3511 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003512
Steve Dowercc16be82016-09-08 10:35:16 -07003513 if (!path->wide) { /* Default arg: "." */
3514 po_wchars = L".";
3515 len = 1;
3516 } else {
3517 po_wchars = path->wide;
3518 len = wcslen(path->wide);
3519 }
3520 /* The +5 is so we can append "\\*.*\0" */
3521 wnamebuf = PyMem_New(wchar_t, len + 5);
3522 if (!wnamebuf) {
3523 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003524 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003525 }
Steve Dowercc16be82016-09-08 10:35:16 -07003526 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003527 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003528 wchar_t wch = wnamebuf[len-1];
3529 if (wch != SEP && wch != ALTSEP && wch != L':')
3530 wnamebuf[len++] = SEP;
3531 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003532 }
Steve Dowercc16be82016-09-08 10:35:16 -07003533 if ((list = PyList_New(0)) == NULL) {
3534 goto exit;
3535 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003536 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003537 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003538 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 if (hFindFile == INVALID_HANDLE_VALUE) {
3540 int error = GetLastError();
3541 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003542 goto exit;
3543 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003544 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003545 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 }
3547 do {
3548 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003549 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3550 wcscmp(wFileData.cFileName, L"..") != 0) {
3551 v = PyUnicode_FromWideChar(wFileData.cFileName,
3552 wcslen(wFileData.cFileName));
3553 if (path->narrow && v) {
3554 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3555 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003556 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557 Py_DECREF(list);
3558 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003559 break;
3560 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003561 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 Py_DECREF(list);
3564 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003565 break;
3566 }
3567 Py_DECREF(v);
3568 }
3569 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003570 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 Py_END_ALLOW_THREADS
3572 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3573 it got to the end of the directory. */
3574 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003576 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003577 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 }
3579 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003580
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581exit:
3582 if (hFindFile != INVALID_HANDLE_VALUE) {
3583 if (FindClose(hFindFile) == FALSE) {
3584 if (list != NULL) {
3585 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003586 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 }
3588 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003589 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003590 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003591
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003593} /* end of _listdir_windows_no_opendir */
3594
3595#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3596
3597static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003598_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003599{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003600 PyObject *v;
3601 DIR *dirp = NULL;
3602 struct dirent *ep;
3603 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003604#ifdef HAVE_FDOPENDIR
3605 int fd = -1;
3606#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003607
Victor Stinner8c62be82010-05-06 00:08:46 +00003608 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003610 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003611 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003612 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003613 if (fd == -1)
3614 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003615
Larry Hastingsfdaea062012-06-25 04:42:23 -07003616 return_str = 1;
3617
Larry Hastings9cf065c2012-06-22 16:30:09 -07003618 Py_BEGIN_ALLOW_THREADS
3619 dirp = fdopendir(fd);
3620 Py_END_ALLOW_THREADS
3621 }
3622 else
3623#endif
3624 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003625 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003626 if (path->narrow) {
3627 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003628 /* only return bytes if they specified a bytes-like object */
3629 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003630 }
3631 else {
3632 name = ".";
3633 return_str = 1;
3634 }
3635
Larry Hastings9cf065c2012-06-22 16:30:09 -07003636 Py_BEGIN_ALLOW_THREADS
3637 dirp = opendir(name);
3638 Py_END_ALLOW_THREADS
3639 }
3640
3641 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003642 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003643#ifdef HAVE_FDOPENDIR
3644 if (fd != -1) {
3645 Py_BEGIN_ALLOW_THREADS
3646 close(fd);
3647 Py_END_ALLOW_THREADS
3648 }
3649#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003650 goto exit;
3651 }
3652 if ((list = PyList_New(0)) == NULL) {
3653 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003654 }
3655 for (;;) {
3656 errno = 0;
3657 Py_BEGIN_ALLOW_THREADS
3658 ep = readdir(dirp);
3659 Py_END_ALLOW_THREADS
3660 if (ep == NULL) {
3661 if (errno == 0) {
3662 break;
3663 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003664 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003665 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003666 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003667 }
3668 }
3669 if (ep->d_name[0] == '.' &&
3670 (NAMLEN(ep) == 1 ||
3671 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3672 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003673 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003674 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3675 else
3676 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003678 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003679 break;
3680 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003681 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003682 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003683 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 break;
3685 }
3686 Py_DECREF(v);
3687 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003688
Larry Hastings9cf065c2012-06-22 16:30:09 -07003689exit:
3690 if (dirp != NULL) {
3691 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003692#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003693 if (fd > -1)
3694 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003695#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003696 closedir(dirp);
3697 Py_END_ALLOW_THREADS
3698 }
3699
Larry Hastings9cf065c2012-06-22 16:30:09 -07003700 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003701} /* end of _posix_listdir */
3702#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003703
Larry Hastings2f936352014-08-05 14:04:04 +10003704
3705/*[clinic input]
3706os.listdir
3707
3708 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3709
3710Return a list containing the names of the files in the directory.
3711
3712path can be specified as either str or bytes. If path is bytes,
3713 the filenames returned will also be bytes; in all other circumstances
3714 the filenames returned will be str.
3715If path is None, uses the path='.'.
3716On some platforms, path may also be specified as an open file descriptor;\
3717 the file descriptor must refer to a directory.
3718 If this functionality is unavailable, using it raises NotImplementedError.
3719
3720The list is in arbitrary order. It does not include the special
3721entries '.' and '..' even if they are present in the directory.
3722
3723
3724[clinic start generated code]*/
3725
Larry Hastings2f936352014-08-05 14:04:04 +10003726static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003727os_listdir_impl(PyObject *module, path_t *path)
3728/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003729{
3730#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3731 return _listdir_windows_no_opendir(path, NULL);
3732#else
3733 return _posix_listdir(path, NULL);
3734#endif
3735}
3736
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003737#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003738/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003739/*[clinic input]
3740os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003741
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003742 path: path_t
3743 /
3744
3745[clinic start generated code]*/
3746
3747static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003748os__getfullpathname_impl(PyObject *module, path_t *path)
3749/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003750{
Steve Dowercc16be82016-09-08 10:35:16 -07003751 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3752 wchar_t *wtemp;
3753 DWORD result;
3754 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003755
Steve Dowercc16be82016-09-08 10:35:16 -07003756 result = GetFullPathNameW(path->wide,
3757 Py_ARRAY_LENGTH(woutbuf),
3758 woutbuf, &wtemp);
3759 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3760 woutbufp = PyMem_New(wchar_t, result);
3761 if (!woutbufp)
3762 return PyErr_NoMemory();
3763 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003764 }
Steve Dowercc16be82016-09-08 10:35:16 -07003765 if (result) {
3766 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3767 if (path->narrow)
3768 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3769 } else
3770 v = win32_error_object("GetFullPathNameW", path->object);
3771 if (woutbufp != woutbuf)
3772 PyMem_Free(woutbufp);
3773 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003774}
Brian Curtind40e6f72010-07-08 21:39:08 +00003775
Brian Curtind25aef52011-06-13 15:16:04 -05003776
Larry Hastings2f936352014-08-05 14:04:04 +10003777/*[clinic input]
3778os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003779
Steve Dower23ad6d02018-02-22 10:39:10 -08003780 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003781 /
3782
3783A helper function for samepath on windows.
3784[clinic start generated code]*/
3785
Larry Hastings2f936352014-08-05 14:04:04 +10003786static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003787os__getfinalpathname_impl(PyObject *module, path_t *path)
3788/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003789{
3790 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003791 wchar_t buf[MAXPATHLEN], *target_path = buf;
3792 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003793 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003794 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003795
Steve Dower23ad6d02018-02-22 10:39:10 -08003796 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003797 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003798 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003799 0, /* desired access */
3800 0, /* share mode */
3801 NULL, /* security attributes */
3802 OPEN_EXISTING,
3803 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3804 FILE_FLAG_BACKUP_SEMANTICS,
3805 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003806 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003807
Steve Dower23ad6d02018-02-22 10:39:10 -08003808 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003809 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003810 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003811
3812 /* We have a good handle to the target, use it to determine the
3813 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003814 while (1) {
3815 Py_BEGIN_ALLOW_THREADS
3816 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3817 buf_size, VOLUME_NAME_DOS);
3818 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003819
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003820 if (!result_length) {
3821 result = win32_error_object("GetFinalPathNameByHandleW",
3822 path->object);
3823 goto cleanup;
3824 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003825
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003826 if (result_length < buf_size) {
3827 break;
3828 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003829
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003830 wchar_t *tmp;
3831 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3832 result_length * sizeof(*tmp));
3833 if (!tmp) {
3834 result = PyErr_NoMemory();
3835 goto cleanup;
3836 }
3837
3838 buf_size = result_length;
3839 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003840 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003841
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003842 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dower23ad6d02018-02-22 10:39:10 -08003843 if (path->narrow)
3844 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dower23ad6d02018-02-22 10:39:10 -08003845
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003846cleanup:
3847 if (target_path != buf) {
3848 PyMem_Free(target_path);
3849 }
3850 CloseHandle(hFile);
3851 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003852}
Brian Curtin62857742010-09-06 17:07:27 +00003853
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003854/*[clinic input]
3855os._isdir
3856
3857 path: path_t
3858 /
3859
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003860Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003861[clinic start generated code]*/
3862
Brian Curtin9c669cc2011-06-08 18:17:18 -05003863static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003864os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003865/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003866{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003867 DWORD attributes;
3868
Steve Dowerb22a6772016-07-17 20:49:38 -07003869 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003870 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003871 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003872
Brian Curtin9c669cc2011-06-08 18:17:18 -05003873 if (attributes == INVALID_FILE_ATTRIBUTES)
3874 Py_RETURN_FALSE;
3875
Brian Curtin9c669cc2011-06-08 18:17:18 -05003876 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3877 Py_RETURN_TRUE;
3878 else
3879 Py_RETURN_FALSE;
3880}
Tim Golden6b528062013-08-01 12:44:00 +01003881
Tim Golden6b528062013-08-01 12:44:00 +01003882
Larry Hastings2f936352014-08-05 14:04:04 +10003883/*[clinic input]
3884os._getvolumepathname
3885
Steve Dower23ad6d02018-02-22 10:39:10 -08003886 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003887
3888A helper function for ismount on Win32.
3889[clinic start generated code]*/
3890
Larry Hastings2f936352014-08-05 14:04:04 +10003891static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003892os__getvolumepathname_impl(PyObject *module, path_t *path)
3893/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003894{
3895 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003896 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003897 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003898 BOOL ret;
3899
Tim Golden6b528062013-08-01 12:44:00 +01003900 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003901 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003902
Victor Stinner850a18e2017-10-24 16:53:32 -07003903 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003904 PyErr_SetString(PyExc_OverflowError, "path too long");
3905 return NULL;
3906 }
3907
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003908 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003909 if (mountpath == NULL)
3910 return PyErr_NoMemory();
3911
3912 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003913 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003914 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003915 Py_END_ALLOW_THREADS
3916
3917 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003918 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003919 goto exit;
3920 }
3921 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003922 if (path->narrow)
3923 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003924
3925exit:
3926 PyMem_Free(mountpath);
3927 return result;
3928}
Tim Golden6b528062013-08-01 12:44:00 +01003929
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003930#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003931
Larry Hastings2f936352014-08-05 14:04:04 +10003932
3933/*[clinic input]
3934os.mkdir
3935
3936 path : path_t
3937
3938 mode: int = 0o777
3939
3940 *
3941
3942 dir_fd : dir_fd(requires='mkdirat') = None
3943
3944# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3945
3946Create a directory.
3947
3948If dir_fd is not None, it should be a file descriptor open to a directory,
3949 and path should be relative; path will then be relative to that directory.
3950dir_fd may not be implemented on your platform.
3951 If it is unavailable, using it will raise a NotImplementedError.
3952
3953The mode argument is ignored on Windows.
3954[clinic start generated code]*/
3955
Larry Hastings2f936352014-08-05 14:04:04 +10003956static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003957os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3958/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003959{
3960 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003961
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003962#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003963 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003964 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003965 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003966
Larry Hastings2f936352014-08-05 14:04:04 +10003967 if (!result)
3968 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003969#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003970 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003971#if HAVE_MKDIRAT
3972 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003973 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003974 else
3975#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003976#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003977 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003978#else
Larry Hastings2f936352014-08-05 14:04:04 +10003979 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003980#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003981 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003982 if (result < 0)
3983 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003984#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003985 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003986}
3987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003988
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003989/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3990#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003991#include <sys/resource.h>
3992#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003993
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003994
3995#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003996/*[clinic input]
3997os.nice
3998
3999 increment: int
4000 /
4001
4002Add increment to the priority of process and return the new priority.
4003[clinic start generated code]*/
4004
Larry Hastings2f936352014-08-05 14:04:04 +10004005static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004006os_nice_impl(PyObject *module, int increment)
4007/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004008{
4009 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004010
Victor Stinner8c62be82010-05-06 00:08:46 +00004011 /* There are two flavours of 'nice': one that returns the new
4012 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004013 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004014 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004015
Victor Stinner8c62be82010-05-06 00:08:46 +00004016 If we are of the nice family that returns the new priority, we
4017 need to clear errno before the call, and check if errno is filled
4018 before calling posix_error() on a returnvalue of -1, because the
4019 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004020
Victor Stinner8c62be82010-05-06 00:08:46 +00004021 errno = 0;
4022 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004023#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004024 if (value == 0)
4025 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004026#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004027 if (value == -1 && errno != 0)
4028 /* either nice() or getpriority() returned an error */
4029 return posix_error();
4030 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004031}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004032#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004033
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004034
4035#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004036/*[clinic input]
4037os.getpriority
4038
4039 which: int
4040 who: int
4041
4042Return program scheduling priority.
4043[clinic start generated code]*/
4044
Larry Hastings2f936352014-08-05 14:04:04 +10004045static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004046os_getpriority_impl(PyObject *module, int which, int who)
4047/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004048{
4049 int retval;
4050
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004051 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004052 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004053 if (errno != 0)
4054 return posix_error();
4055 return PyLong_FromLong((long)retval);
4056}
4057#endif /* HAVE_GETPRIORITY */
4058
4059
4060#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004061/*[clinic input]
4062os.setpriority
4063
4064 which: int
4065 who: int
4066 priority: int
4067
4068Set program scheduling priority.
4069[clinic start generated code]*/
4070
Larry Hastings2f936352014-08-05 14:04:04 +10004071static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004072os_setpriority_impl(PyObject *module, int which, int who, int priority)
4073/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004074{
4075 int retval;
4076
4077 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004078 if (retval == -1)
4079 return posix_error();
4080 Py_RETURN_NONE;
4081}
4082#endif /* HAVE_SETPRIORITY */
4083
4084
Barry Warsaw53699e91996-12-10 23:23:01 +00004085static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004086internal_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 +00004087{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004088 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004089 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004090
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004091#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004092 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004093 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004094#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004095 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004096#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004097
Larry Hastings9cf065c2012-06-22 16:30:09 -07004098 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4099 (dst_dir_fd != DEFAULT_DIR_FD);
4100#ifndef HAVE_RENAMEAT
4101 if (dir_fd_specified) {
4102 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004103 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004104 }
4105#endif
4106
Larry Hastings9cf065c2012-06-22 16:30:09 -07004107#ifdef MS_WINDOWS
4108 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004109 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004110 Py_END_ALLOW_THREADS
4111
Larry Hastings2f936352014-08-05 14:04:04 +10004112 if (!result)
4113 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004114
4115#else
Steve Dowercc16be82016-09-08 10:35:16 -07004116 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4117 PyErr_Format(PyExc_ValueError,
4118 "%s: src and dst must be the same type", function_name);
4119 return NULL;
4120 }
4121
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122 Py_BEGIN_ALLOW_THREADS
4123#ifdef HAVE_RENAMEAT
4124 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004125 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004126 else
4127#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004128 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004129 Py_END_ALLOW_THREADS
4130
Larry Hastings2f936352014-08-05 14:04:04 +10004131 if (result)
4132 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004133#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004134 Py_RETURN_NONE;
4135}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004136
Larry Hastings2f936352014-08-05 14:04:04 +10004137
4138/*[clinic input]
4139os.rename
4140
4141 src : path_t
4142 dst : path_t
4143 *
4144 src_dir_fd : dir_fd = None
4145 dst_dir_fd : dir_fd = None
4146
4147Rename a file or directory.
4148
4149If either src_dir_fd or dst_dir_fd is not None, it should be a file
4150 descriptor open to a directory, and the respective path string (src or dst)
4151 should be relative; the path will then be relative to that directory.
4152src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4153 If they are unavailable, using them will raise a NotImplementedError.
4154[clinic start generated code]*/
4155
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004156static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004157os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004158 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004159/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004160{
Larry Hastings2f936352014-08-05 14:04:04 +10004161 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004162}
4163
Larry Hastings2f936352014-08-05 14:04:04 +10004164
4165/*[clinic input]
4166os.replace = os.rename
4167
4168Rename a file or directory, overwriting the destination.
4169
4170If either src_dir_fd or dst_dir_fd is not None, it should be a file
4171 descriptor open to a directory, and the respective path string (src or dst)
4172 should be relative; the path will then be relative to that directory.
4173src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4174 If they are unavailable, using them will raise a NotImplementedError."
4175[clinic start generated code]*/
4176
Larry Hastings2f936352014-08-05 14:04:04 +10004177static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004178os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4179 int dst_dir_fd)
4180/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004181{
4182 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4183}
4184
4185
4186/*[clinic input]
4187os.rmdir
4188
4189 path: path_t
4190 *
4191 dir_fd: dir_fd(requires='unlinkat') = None
4192
4193Remove a directory.
4194
4195If dir_fd is not None, it should be a file descriptor open to a directory,
4196 and path should be relative; path will then be relative to that directory.
4197dir_fd may not be implemented on your platform.
4198 If it is unavailable, using it will raise a NotImplementedError.
4199[clinic start generated code]*/
4200
Larry Hastings2f936352014-08-05 14:04:04 +10004201static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004202os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4203/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004204{
4205 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004206
4207 Py_BEGIN_ALLOW_THREADS
4208#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004209 /* Windows, success=1, UNIX, success=0 */
4210 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004211#else
4212#ifdef HAVE_UNLINKAT
4213 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004214 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004215 else
4216#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004217 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004218#endif
4219 Py_END_ALLOW_THREADS
4220
Larry Hastings2f936352014-08-05 14:04:04 +10004221 if (result)
4222 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004223
Larry Hastings2f936352014-08-05 14:04:04 +10004224 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004225}
4226
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004227
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004228#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004229#ifdef MS_WINDOWS
4230/*[clinic input]
4231os.system -> long
4232
4233 command: Py_UNICODE
4234
4235Execute the command in a subshell.
4236[clinic start generated code]*/
4237
Larry Hastings2f936352014-08-05 14:04:04 +10004238static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004239os_system_impl(PyObject *module, Py_UNICODE *command)
4240/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004241{
4242 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004243 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004244 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004245 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004246 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004247 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004248 return result;
4249}
4250#else /* MS_WINDOWS */
4251/*[clinic input]
4252os.system -> long
4253
4254 command: FSConverter
4255
4256Execute the command in a subshell.
4257[clinic start generated code]*/
4258
Larry Hastings2f936352014-08-05 14:04:04 +10004259static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004260os_system_impl(PyObject *module, PyObject *command)
4261/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004262{
4263 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004264 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004265 Py_BEGIN_ALLOW_THREADS
4266 result = system(bytes);
4267 Py_END_ALLOW_THREADS
4268 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004269}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004270#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004271#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004272
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004273
Larry Hastings2f936352014-08-05 14:04:04 +10004274/*[clinic input]
4275os.umask
4276
4277 mask: int
4278 /
4279
4280Set the current numeric umask and return the previous umask.
4281[clinic start generated code]*/
4282
Larry Hastings2f936352014-08-05 14:04:04 +10004283static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004284os_umask_impl(PyObject *module, int mask)
4285/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004286{
4287 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004288 if (i < 0)
4289 return posix_error();
4290 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004291}
4292
Brian Curtind40e6f72010-07-08 21:39:08 +00004293#ifdef MS_WINDOWS
4294
4295/* override the default DeleteFileW behavior so that directory
4296symlinks can be removed with this function, the same as with
4297Unix symlinks */
4298BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4299{
4300 WIN32_FILE_ATTRIBUTE_DATA info;
4301 WIN32_FIND_DATAW find_data;
4302 HANDLE find_data_handle;
4303 int is_directory = 0;
4304 int is_link = 0;
4305
4306 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4307 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004308
Brian Curtind40e6f72010-07-08 21:39:08 +00004309 /* Get WIN32_FIND_DATA structure for the path to determine if
4310 it is a symlink */
4311 if(is_directory &&
4312 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4313 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4314
4315 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004316 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4317 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4318 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4319 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004320 FindClose(find_data_handle);
4321 }
4322 }
4323 }
4324
4325 if (is_directory && is_link)
4326 return RemoveDirectoryW(lpFileName);
4327
4328 return DeleteFileW(lpFileName);
4329}
4330#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004331
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004332
Larry Hastings2f936352014-08-05 14:04:04 +10004333/*[clinic input]
4334os.unlink
4335
4336 path: path_t
4337 *
4338 dir_fd: dir_fd(requires='unlinkat')=None
4339
4340Remove a file (same as remove()).
4341
4342If dir_fd is not None, it should be a file descriptor open to a directory,
4343 and path should be relative; path will then be relative to that directory.
4344dir_fd may not be implemented on your platform.
4345 If it is unavailable, using it will raise a NotImplementedError.
4346
4347[clinic start generated code]*/
4348
Larry Hastings2f936352014-08-05 14:04:04 +10004349static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004350os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4351/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004352{
4353 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004354
4355 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004356 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004357#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004358 /* Windows, success=1, UNIX, success=0 */
4359 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004360#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004361#ifdef HAVE_UNLINKAT
4362 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004363 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004364 else
4365#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004366 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004367#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004368 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004369 Py_END_ALLOW_THREADS
4370
Larry Hastings2f936352014-08-05 14:04:04 +10004371 if (result)
4372 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004373
Larry Hastings2f936352014-08-05 14:04:04 +10004374 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004375}
4376
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004377
Larry Hastings2f936352014-08-05 14:04:04 +10004378/*[clinic input]
4379os.remove = os.unlink
4380
4381Remove a file (same as unlink()).
4382
4383If dir_fd is not None, it should be a file descriptor open to a directory,
4384 and path should be relative; path will then be relative to that directory.
4385dir_fd may not be implemented on your platform.
4386 If it is unavailable, using it will raise a NotImplementedError.
4387[clinic start generated code]*/
4388
Larry Hastings2f936352014-08-05 14:04:04 +10004389static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004390os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4391/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004392{
4393 return os_unlink_impl(module, path, dir_fd);
4394}
4395
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004396
Larry Hastings605a62d2012-06-24 04:33:36 -07004397static PyStructSequence_Field uname_result_fields[] = {
4398 {"sysname", "operating system name"},
4399 {"nodename", "name of machine on network (implementation-defined)"},
4400 {"release", "operating system release"},
4401 {"version", "operating system version"},
4402 {"machine", "hardware identifier"},
4403 {NULL}
4404};
4405
4406PyDoc_STRVAR(uname_result__doc__,
4407"uname_result: Result from os.uname().\n\n\
4408This object may be accessed either as a tuple of\n\
4409 (sysname, nodename, release, version, machine),\n\
4410or via the attributes sysname, nodename, release, version, and machine.\n\
4411\n\
4412See os.uname for more information.");
4413
4414static PyStructSequence_Desc uname_result_desc = {
4415 "uname_result", /* name */
4416 uname_result__doc__, /* doc */
4417 uname_result_fields,
4418 5
4419};
4420
4421static PyTypeObject UnameResultType;
4422
4423
4424#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004425/*[clinic input]
4426os.uname
4427
4428Return an object identifying the current operating system.
4429
4430The object behaves like a named tuple with the following fields:
4431 (sysname, nodename, release, version, machine)
4432
4433[clinic start generated code]*/
4434
Larry Hastings2f936352014-08-05 14:04:04 +10004435static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004436os_uname_impl(PyObject *module)
4437/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004438{
Victor Stinner8c62be82010-05-06 00:08:46 +00004439 struct utsname u;
4440 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004441 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004442
Victor Stinner8c62be82010-05-06 00:08:46 +00004443 Py_BEGIN_ALLOW_THREADS
4444 res = uname(&u);
4445 Py_END_ALLOW_THREADS
4446 if (res < 0)
4447 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004448
4449 value = PyStructSequence_New(&UnameResultType);
4450 if (value == NULL)
4451 return NULL;
4452
4453#define SET(i, field) \
4454 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004455 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004456 if (!o) { \
4457 Py_DECREF(value); \
4458 return NULL; \
4459 } \
4460 PyStructSequence_SET_ITEM(value, i, o); \
4461 } \
4462
4463 SET(0, u.sysname);
4464 SET(1, u.nodename);
4465 SET(2, u.release);
4466 SET(3, u.version);
4467 SET(4, u.machine);
4468
4469#undef SET
4470
4471 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004472}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004473#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004474
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004475
Larry Hastings9cf065c2012-06-22 16:30:09 -07004476
4477typedef struct {
4478 int now;
4479 time_t atime_s;
4480 long atime_ns;
4481 time_t mtime_s;
4482 long mtime_ns;
4483} utime_t;
4484
4485/*
Victor Stinner484df002014-10-09 13:52:31 +02004486 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004487 * they also intentionally leak the declaration of a pointer named "time"
4488 */
4489#define UTIME_TO_TIMESPEC \
4490 struct timespec ts[2]; \
4491 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004492 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004493 time = NULL; \
4494 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004495 ts[0].tv_sec = ut->atime_s; \
4496 ts[0].tv_nsec = ut->atime_ns; \
4497 ts[1].tv_sec = ut->mtime_s; \
4498 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004499 time = ts; \
4500 } \
4501
4502#define UTIME_TO_TIMEVAL \
4503 struct timeval tv[2]; \
4504 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004505 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004506 time = NULL; \
4507 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004508 tv[0].tv_sec = ut->atime_s; \
4509 tv[0].tv_usec = ut->atime_ns / 1000; \
4510 tv[1].tv_sec = ut->mtime_s; \
4511 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004512 time = tv; \
4513 } \
4514
4515#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004516 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004517 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004518 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004519 time = NULL; \
4520 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004521 u.actime = ut->atime_s; \
4522 u.modtime = ut->mtime_s; \
4523 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004524 }
4525
4526#define UTIME_TO_TIME_T \
4527 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004528 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004529 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004530 time = NULL; \
4531 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004532 timet[0] = ut->atime_s; \
4533 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004534 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004535 } \
4536
4537
Victor Stinner528a9ab2015-09-03 21:30:26 +02004538#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004539
4540static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004541utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542{
4543#ifdef HAVE_UTIMENSAT
4544 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4545 UTIME_TO_TIMESPEC;
4546 return utimensat(dir_fd, path, time, flags);
4547#elif defined(HAVE_FUTIMESAT)
4548 UTIME_TO_TIMEVAL;
4549 /*
4550 * follow_symlinks will never be false here;
4551 * we only allow !follow_symlinks and dir_fd together
4552 * if we have utimensat()
4553 */
4554 assert(follow_symlinks);
4555 return futimesat(dir_fd, path, time);
4556#endif
4557}
4558
Larry Hastings2f936352014-08-05 14:04:04 +10004559 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4560#else
4561 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004562#endif
4563
Victor Stinner528a9ab2015-09-03 21:30:26 +02004564#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004565
4566static int
Victor Stinner484df002014-10-09 13:52:31 +02004567utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004568{
4569#ifdef HAVE_FUTIMENS
4570 UTIME_TO_TIMESPEC;
4571 return futimens(fd, time);
4572#else
4573 UTIME_TO_TIMEVAL;
4574 return futimes(fd, time);
4575#endif
4576}
4577
Larry Hastings2f936352014-08-05 14:04:04 +10004578 #define PATH_UTIME_HAVE_FD 1
4579#else
4580 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004581#endif
4582
Victor Stinner5ebae872015-09-22 01:29:33 +02004583#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4584# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4585#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004586
Victor Stinner4552ced2015-09-21 22:37:15 +02004587#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588
4589static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004590utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004591{
4592#ifdef HAVE_UTIMENSAT
4593 UTIME_TO_TIMESPEC;
4594 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4595#else
4596 UTIME_TO_TIMEVAL;
4597 return lutimes(path, time);
4598#endif
4599}
4600
4601#endif
4602
4603#ifndef MS_WINDOWS
4604
4605static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004606utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004607{
4608#ifdef HAVE_UTIMENSAT
4609 UTIME_TO_TIMESPEC;
4610 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4611#elif defined(HAVE_UTIMES)
4612 UTIME_TO_TIMEVAL;
4613 return utimes(path, time);
4614#elif defined(HAVE_UTIME_H)
4615 UTIME_TO_UTIMBUF;
4616 return utime(path, time);
4617#else
4618 UTIME_TO_TIME_T;
4619 return utime(path, time);
4620#endif
4621}
4622
4623#endif
4624
Larry Hastings76ad59b2012-05-03 00:30:07 -07004625static int
4626split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4627{
4628 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004629 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004630 divmod = PyNumber_Divmod(py_long, billion);
4631 if (!divmod)
4632 goto exit;
4633 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4634 if ((*s == -1) && PyErr_Occurred())
4635 goto exit;
4636 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004637 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004638 goto exit;
4639
4640 result = 1;
4641exit:
4642 Py_XDECREF(divmod);
4643 return result;
4644}
4645
Larry Hastings2f936352014-08-05 14:04:04 +10004646
4647/*[clinic input]
4648os.utime
4649
4650 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4651 times: object = NULL
4652 *
4653 ns: object = NULL
4654 dir_fd: dir_fd(requires='futimensat') = None
4655 follow_symlinks: bool=True
4656
Martin Panter0ff89092015-09-09 01:56:53 +00004657# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004658
4659Set the access and modified time of path.
4660
4661path may always be specified as a string.
4662On some platforms, path may also be specified as an open file descriptor.
4663 If this functionality is unavailable, using it raises an exception.
4664
4665If times is not None, it must be a tuple (atime, mtime);
4666 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004667If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004668 atime_ns and mtime_ns should be expressed as integer nanoseconds
4669 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004670If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004671Specifying tuples for both times and ns is an error.
4672
4673If dir_fd is not None, it should be a file descriptor open to a directory,
4674 and path should be relative; path will then be relative to that directory.
4675If follow_symlinks is False, and the last element of the path is a symbolic
4676 link, utime will modify the symbolic link itself instead of the file the
4677 link points to.
4678It is an error to use dir_fd or follow_symlinks when specifying path
4679 as an open file descriptor.
4680dir_fd and follow_symlinks may not be available on your platform.
4681 If they are unavailable, using them will raise a NotImplementedError.
4682
4683[clinic start generated code]*/
4684
Larry Hastings2f936352014-08-05 14:04:04 +10004685static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004686os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4687 int dir_fd, int follow_symlinks)
4688/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004689{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690#ifdef MS_WINDOWS
4691 HANDLE hFile;
4692 FILETIME atime, mtime;
4693#else
4694 int result;
4695#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004696
Larry Hastings9cf065c2012-06-22 16:30:09 -07004697 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004698 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004699
Christian Heimesb3c87242013-08-01 00:08:16 +02004700 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004701
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702 if (times && (times != Py_None) && ns) {
4703 PyErr_SetString(PyExc_ValueError,
4704 "utime: you may specify either 'times'"
4705 " or 'ns' but not both");
4706 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004707 }
4708
4709 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004710 time_t a_sec, m_sec;
4711 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004712 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004713 PyErr_SetString(PyExc_TypeError,
4714 "utime: 'times' must be either"
4715 " a tuple of two ints or None");
4716 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004717 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004718 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004719 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004720 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004721 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004722 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004723 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004724 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004725 utime.atime_s = a_sec;
4726 utime.atime_ns = a_nsec;
4727 utime.mtime_s = m_sec;
4728 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004729 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004730 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004731 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732 PyErr_SetString(PyExc_TypeError,
4733 "utime: 'ns' must be a tuple of two ints");
4734 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004735 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004736 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004737 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004738 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004739 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004740 &utime.mtime_s, &utime.mtime_ns)) {
4741 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004742 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004743 }
4744 else {
4745 /* times and ns are both None/unspecified. use "now". */
4746 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004747 }
4748
Victor Stinner4552ced2015-09-21 22:37:15 +02004749#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004750 if (follow_symlinks_specified("utime", follow_symlinks))
4751 goto exit;
4752#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004753
Larry Hastings2f936352014-08-05 14:04:04 +10004754 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4755 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4756 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004758
Larry Hastings9cf065c2012-06-22 16:30:09 -07004759#if !defined(HAVE_UTIMENSAT)
4760 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004761 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004762 "utime: cannot use dir_fd and follow_symlinks "
4763 "together on this platform");
4764 goto exit;
4765 }
4766#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004767
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004768#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004769 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004770 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4771 NULL, OPEN_EXISTING,
4772 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004773 Py_END_ALLOW_THREADS
4774 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004775 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004776 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004777 }
4778
Larry Hastings9cf065c2012-06-22 16:30:09 -07004779 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004780 GetSystemTimeAsFileTime(&mtime);
4781 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004782 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004783 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004784 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4785 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004786 }
4787 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4788 /* Avoid putting the file name into the error here,
4789 as that may confuse the user into believing that
4790 something is wrong with the file, when it also
4791 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004792 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004793 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004794 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004795#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004796 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004797
Victor Stinner4552ced2015-09-21 22:37:15 +02004798#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004799 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004800 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004801 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004802#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004803
Victor Stinner528a9ab2015-09-03 21:30:26 +02004804#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004805 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004806 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004807 else
4808#endif
4809
Victor Stinner528a9ab2015-09-03 21:30:26 +02004810#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004811 if (path->fd != -1)
4812 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004813 else
4814#endif
4815
Larry Hastings2f936352014-08-05 14:04:04 +10004816 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004817
4818 Py_END_ALLOW_THREADS
4819
4820 if (result < 0) {
4821 /* see previous comment about not putting filename in error here */
4822 return_value = posix_error();
4823 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004824 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004825
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004826#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004827
4828 Py_INCREF(Py_None);
4829 return_value = Py_None;
4830
4831exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004832#ifdef MS_WINDOWS
4833 if (hFile != INVALID_HANDLE_VALUE)
4834 CloseHandle(hFile);
4835#endif
4836 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004837}
4838
Guido van Rossum3b066191991-06-04 19:40:25 +00004839/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004840
Larry Hastings2f936352014-08-05 14:04:04 +10004841
4842/*[clinic input]
4843os._exit
4844
4845 status: int
4846
4847Exit to the system with specified status, without normal exit processing.
4848[clinic start generated code]*/
4849
Larry Hastings2f936352014-08-05 14:04:04 +10004850static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004851os__exit_impl(PyObject *module, int status)
4852/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004853{
4854 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004855 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004856}
4857
Steve Dowercc16be82016-09-08 10:35:16 -07004858#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4859#define EXECV_CHAR wchar_t
4860#else
4861#define EXECV_CHAR char
4862#endif
4863
Martin v. Löwis114619e2002-10-07 06:44:21 +00004864#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4865static void
Steve Dowercc16be82016-09-08 10:35:16 -07004866free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004867{
Victor Stinner8c62be82010-05-06 00:08:46 +00004868 Py_ssize_t i;
4869 for (i = 0; i < count; i++)
4870 PyMem_Free(array[i]);
4871 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004872}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004873
Berker Peksag81816462016-09-15 20:19:47 +03004874static int
4875fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004876{
Victor Stinner8c62be82010-05-06 00:08:46 +00004877 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004878 PyObject *ub;
4879 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004880#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004881 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004882 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004883 *out = PyUnicode_AsWideCharString(ub, &size);
4884 if (*out)
4885 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004886#else
Berker Peksag81816462016-09-15 20:19:47 +03004887 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004888 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004889 size = PyBytes_GET_SIZE(ub);
4890 *out = PyMem_Malloc(size + 1);
4891 if (*out) {
4892 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4893 result = 1;
4894 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004895 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004896#endif
Berker Peksag81816462016-09-15 20:19:47 +03004897 Py_DECREF(ub);
4898 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004899}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004900#endif
4901
Ross Lagerwall7807c352011-03-17 20:20:30 +02004902#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004903static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004904parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4905{
Victor Stinner8c62be82010-05-06 00:08:46 +00004906 Py_ssize_t i, pos, envc;
4907 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004908 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004909 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004910
Victor Stinner8c62be82010-05-06 00:08:46 +00004911 i = PyMapping_Size(env);
4912 if (i < 0)
4913 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004914 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004915 if (envlist == NULL) {
4916 PyErr_NoMemory();
4917 return NULL;
4918 }
4919 envc = 0;
4920 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004921 if (!keys)
4922 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004923 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004924 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004925 goto error;
4926 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4927 PyErr_Format(PyExc_TypeError,
4928 "env.keys() or env.values() is not a list");
4929 goto error;
4930 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004931
Victor Stinner8c62be82010-05-06 00:08:46 +00004932 for (pos = 0; pos < i; pos++) {
4933 key = PyList_GetItem(keys, pos);
4934 val = PyList_GetItem(vals, pos);
4935 if (!key || !val)
4936 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004937
Berker Peksag81816462016-09-15 20:19:47 +03004938#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4939 if (!PyUnicode_FSDecoder(key, &key2))
4940 goto error;
4941 if (!PyUnicode_FSDecoder(val, &val2)) {
4942 Py_DECREF(key2);
4943 goto error;
4944 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004945 /* Search from index 1 because on Windows starting '=' is allowed for
4946 defining hidden environment variables. */
4947 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4948 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4949 {
4950 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004951 Py_DECREF(key2);
4952 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004953 goto error;
4954 }
Berker Peksag81816462016-09-15 20:19:47 +03004955 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4956#else
4957 if (!PyUnicode_FSConverter(key, &key2))
4958 goto error;
4959 if (!PyUnicode_FSConverter(val, &val2)) {
4960 Py_DECREF(key2);
4961 goto error;
4962 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004963 if (PyBytes_GET_SIZE(key2) == 0 ||
4964 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4965 {
4966 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004967 Py_DECREF(key2);
4968 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004969 goto error;
4970 }
Berker Peksag81816462016-09-15 20:19:47 +03004971 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4972 PyBytes_AS_STRING(val2));
4973#endif
4974 Py_DECREF(key2);
4975 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004976 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004977 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004978
4979 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4980 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 goto error;
4982 }
Berker Peksag81816462016-09-15 20:19:47 +03004983
Steve Dowercc16be82016-09-08 10:35:16 -07004984 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004985 }
4986 Py_DECREF(vals);
4987 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004988
Victor Stinner8c62be82010-05-06 00:08:46 +00004989 envlist[envc] = 0;
4990 *envc_ptr = envc;
4991 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004992
4993error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004994 Py_XDECREF(keys);
4995 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004996 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004997 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004998}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004999
Steve Dowercc16be82016-09-08 10:35:16 -07005000static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005001parse_arglist(PyObject* argv, Py_ssize_t *argc)
5002{
5003 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005004 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005005 if (argvlist == NULL) {
5006 PyErr_NoMemory();
5007 return NULL;
5008 }
5009 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005010 PyObject* item = PySequence_ITEM(argv, i);
5011 if (item == NULL)
5012 goto fail;
5013 if (!fsconvert_strdup(item, &argvlist[i])) {
5014 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005015 goto fail;
5016 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005017 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005018 }
5019 argvlist[*argc] = NULL;
5020 return argvlist;
5021fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005022 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005023 free_string_array(argvlist, *argc);
5024 return NULL;
5025}
Steve Dowercc16be82016-09-08 10:35:16 -07005026
Ross Lagerwall7807c352011-03-17 20:20:30 +02005027#endif
5028
Larry Hastings2f936352014-08-05 14:04:04 +10005029
Ross Lagerwall7807c352011-03-17 20:20:30 +02005030#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005031/*[clinic input]
5032os.execv
5033
Steve Dowercc16be82016-09-08 10:35:16 -07005034 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005035 Path of executable file.
5036 argv: object
5037 Tuple or list of strings.
5038 /
5039
5040Execute an executable path with arguments, replacing current process.
5041[clinic start generated code]*/
5042
Larry Hastings2f936352014-08-05 14:04:04 +10005043static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005044os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5045/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005046{
Steve Dowercc16be82016-09-08 10:35:16 -07005047 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005048 Py_ssize_t argc;
5049
5050 /* execv has two arguments: (path, argv), where
5051 argv is a list or tuple of strings. */
5052
Ross Lagerwall7807c352011-03-17 20:20:30 +02005053 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5054 PyErr_SetString(PyExc_TypeError,
5055 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005056 return NULL;
5057 }
5058 argc = PySequence_Size(argv);
5059 if (argc < 1) {
5060 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005061 return NULL;
5062 }
5063
5064 argvlist = parse_arglist(argv, &argc);
5065 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005066 return NULL;
5067 }
Steve Dowerbce26262016-11-19 19:17:26 -08005068 if (!argvlist[0][0]) {
5069 PyErr_SetString(PyExc_ValueError,
5070 "execv() arg 2 first element cannot be empty");
5071 free_string_array(argvlist, argc);
5072 return NULL;
5073 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005074
Steve Dowerbce26262016-11-19 19:17:26 -08005075 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005076#ifdef HAVE_WEXECV
5077 _wexecv(path->wide, argvlist);
5078#else
5079 execv(path->narrow, argvlist);
5080#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005081 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005082
5083 /* If we get here it's definitely an error */
5084
5085 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005086 return posix_error();
5087}
5088
Larry Hastings2f936352014-08-05 14:04:04 +10005089
5090/*[clinic input]
5091os.execve
5092
5093 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5094 Path of executable file.
5095 argv: object
5096 Tuple or list of strings.
5097 env: object
5098 Dictionary of strings mapping to strings.
5099
5100Execute an executable path with arguments, replacing current process.
5101[clinic start generated code]*/
5102
Larry Hastings2f936352014-08-05 14:04:04 +10005103static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005104os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5105/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005106{
Steve Dowercc16be82016-09-08 10:35:16 -07005107 EXECV_CHAR **argvlist = NULL;
5108 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005109 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005110
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 /* execve has three arguments: (path, argv, env), where
5112 argv is a list or tuple of strings and env is a dictionary
5113 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005114
Ross Lagerwall7807c352011-03-17 20:20:30 +02005115 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005116 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005117 "execve: argv must be a tuple or list");
5118 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005119 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005120 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005121 if (argc < 1) {
5122 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5123 return NULL;
5124 }
5125
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 if (!PyMapping_Check(env)) {
5127 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005128 "execve: environment must be a mapping object");
5129 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005131
Ross Lagerwall7807c352011-03-17 20:20:30 +02005132 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005133 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005134 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005135 }
Steve Dowerbce26262016-11-19 19:17:26 -08005136 if (!argvlist[0][0]) {
5137 PyErr_SetString(PyExc_ValueError,
5138 "execve: argv first element cannot be empty");
5139 goto fail;
5140 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005141
Victor Stinner8c62be82010-05-06 00:08:46 +00005142 envlist = parse_envlist(env, &envc);
5143 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005144 goto fail;
5145
Steve Dowerbce26262016-11-19 19:17:26 -08005146 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005147#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005148 if (path->fd > -1)
5149 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005150 else
5151#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005152#ifdef HAVE_WEXECV
5153 _wexecve(path->wide, argvlist, envlist);
5154#else
Larry Hastings2f936352014-08-05 14:04:04 +10005155 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005156#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005157 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005158
5159 /* If we get here it's definitely an error */
5160
Larry Hastings2f936352014-08-05 14:04:04 +10005161 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005162
Steve Dowercc16be82016-09-08 10:35:16 -07005163 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005164 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005165 if (argvlist)
5166 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005167 return NULL;
5168}
Steve Dowercc16be82016-09-08 10:35:16 -07005169
Larry Hastings9cf065c2012-06-22 16:30:09 -07005170#endif /* HAVE_EXECV */
5171
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005172#ifdef HAVE_POSIX_SPAWN
5173
5174enum posix_spawn_file_actions_identifier {
5175 POSIX_SPAWN_OPEN,
5176 POSIX_SPAWN_CLOSE,
5177 POSIX_SPAWN_DUP2
5178};
5179
Serhiy Storchakaef347532018-05-01 16:45:04 +03005180static int
5181parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005182 posix_spawn_file_actions_t *file_actionsp,
5183 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005184{
5185 PyObject *seq;
5186 PyObject *file_action = NULL;
5187 PyObject *tag_obj;
5188
5189 seq = PySequence_Fast(file_actions,
5190 "file_actions must be a sequence or None");
5191 if (seq == NULL) {
5192 return -1;
5193 }
5194
5195 errno = posix_spawn_file_actions_init(file_actionsp);
5196 if (errno) {
5197 posix_error();
5198 Py_DECREF(seq);
5199 return -1;
5200 }
5201
5202 for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
5203 file_action = PySequence_Fast_GET_ITEM(seq, i);
5204 Py_INCREF(file_action);
5205 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5206 PyErr_SetString(PyExc_TypeError,
5207 "Each file_actions element must be a non-empty tuple");
5208 goto fail;
5209 }
5210 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5211 if (tag == -1 && PyErr_Occurred()) {
5212 goto fail;
5213 }
5214
5215 /* Populate the file_actions object */
5216 switch (tag) {
5217 case POSIX_SPAWN_OPEN: {
5218 int fd, oflag;
5219 PyObject *path;
5220 unsigned long mode;
5221 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5222 ";A open file_action tuple must have 5 elements",
5223 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5224 &oflag, &mode))
5225 {
5226 goto fail;
5227 }
Pablo Galindocb970732018-06-19 09:19:50 +01005228 if (PyList_Append(temp_buffer, path)) {
5229 Py_DECREF(path);
5230 goto fail;
5231 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005232 errno = posix_spawn_file_actions_addopen(file_actionsp,
5233 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005234 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005235 if (errno) {
5236 posix_error();
5237 goto fail;
5238 }
5239 break;
5240 }
5241 case POSIX_SPAWN_CLOSE: {
5242 int fd;
5243 if (!PyArg_ParseTuple(file_action, "Oi"
5244 ";A close file_action tuple must have 2 elements",
5245 &tag_obj, &fd))
5246 {
5247 goto fail;
5248 }
5249 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5250 if (errno) {
5251 posix_error();
5252 goto fail;
5253 }
5254 break;
5255 }
5256 case POSIX_SPAWN_DUP2: {
5257 int fd1, fd2;
5258 if (!PyArg_ParseTuple(file_action, "Oii"
5259 ";A dup2 file_action tuple must have 3 elements",
5260 &tag_obj, &fd1, &fd2))
5261 {
5262 goto fail;
5263 }
5264 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5265 fd1, fd2);
5266 if (errno) {
5267 posix_error();
5268 goto fail;
5269 }
5270 break;
5271 }
5272 default: {
5273 PyErr_SetString(PyExc_TypeError,
5274 "Unknown file_actions identifier");
5275 goto fail;
5276 }
5277 }
5278 Py_DECREF(file_action);
5279 }
5280 Py_DECREF(seq);
5281 return 0;
5282
5283fail:
5284 Py_DECREF(seq);
5285 Py_DECREF(file_action);
5286 (void)posix_spawn_file_actions_destroy(file_actionsp);
5287 return -1;
5288}
5289
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005290/*[clinic input]
5291
5292os.posix_spawn
5293 path: path_t
5294 Path of executable file.
5295 argv: object
5296 Tuple or list of strings.
5297 env: object
5298 Dictionary of strings mapping to strings.
5299 file_actions: object = None
Serhiy Storchakaef347532018-05-01 16:45:04 +03005300 A sequence of file action tuples.
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005301 /
5302
5303Execute the program specified by path in a new process.
5304[clinic start generated code]*/
5305
5306static PyObject *
5307os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5308 PyObject *env, PyObject *file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005309/*[clinic end generated code: output=d023521f541c709c input=a3db1021d33230dc]*/
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005310{
5311 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005312 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005313 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005314 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005315 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005316 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005317 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005318 pid_t pid;
5319 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005320
5321 /* posix_spawn has three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005322 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005323 like posix.environ. */
5324
Serhiy Storchakaef347532018-05-01 16:45:04 +03005325 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005326 PyErr_SetString(PyExc_TypeError,
5327 "posix_spawn: argv must be a tuple or list");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005328 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005329 }
5330 argc = PySequence_Size(argv);
5331 if (argc < 1) {
5332 PyErr_SetString(PyExc_ValueError, "posix_spawn: argv must not be empty");
5333 return NULL;
5334 }
5335
5336 if (!PyMapping_Check(env)) {
5337 PyErr_SetString(PyExc_TypeError,
5338 "posix_spawn: environment must be a mapping object");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005339 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005340 }
5341
5342 argvlist = parse_arglist(argv, &argc);
5343 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005344 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005345 }
5346 if (!argvlist[0][0]) {
5347 PyErr_SetString(PyExc_ValueError,
5348 "posix_spawn: argv first element cannot be empty");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005349 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005350 }
5351
5352 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005353 if (envlist == NULL) {
5354 goto exit;
5355 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005356
Serhiy Storchakaef347532018-05-01 16:45:04 +03005357 if (file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005358 /* There is a bug in old versions of glibc that makes some of the
5359 * helper functions for manipulating file actions not copy the provided
5360 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5361 * copy the value of path for some old versions of glibc (<2.20).
5362 * The use of temp_buffer here is a workaround that keeps the
5363 * python objects that own the buffers alive until posix_spawn gets called.
5364 * Check https://bugs.python.org/issue33630 and
5365 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5366 temp_buffer = PyList_New(0);
5367 if (!temp_buffer) {
5368 goto exit;
5369 }
5370 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005371 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005372 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005373 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005374 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005375
5376 _Py_BEGIN_SUPPRESS_IPH
Serhiy Storchakaef347532018-05-01 16:45:04 +03005377 err_code = posix_spawn(&pid, path->narrow,
5378 file_actionsp, NULL, argvlist, envlist);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005379 _Py_END_SUPPRESS_IPH
Serhiy Storchakaef347532018-05-01 16:45:04 +03005380 if (err_code) {
5381 errno = err_code;
5382 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005383 goto exit;
5384 }
5385 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005386
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005387exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005388 if (file_actionsp) {
5389 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005390 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005391 if (envlist) {
5392 free_string_array(envlist, envc);
5393 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005394 if (argvlist) {
5395 free_string_array(argvlist, argc);
5396 }
Pablo Galindocb970732018-06-19 09:19:50 +01005397 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005398 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005399}
5400#endif /* HAVE_POSIX_SPAWN */
5401
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005402
Steve Dowercc16be82016-09-08 10:35:16 -07005403#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005404/*[clinic input]
5405os.spawnv
5406
5407 mode: int
5408 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005409 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005410 Path of executable file.
5411 argv: object
5412 Tuple or list of strings.
5413 /
5414
5415Execute the program specified by path in a new process.
5416[clinic start generated code]*/
5417
Larry Hastings2f936352014-08-05 14:04:04 +10005418static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005419os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5420/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005421{
Steve Dowercc16be82016-09-08 10:35:16 -07005422 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005423 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005424 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005425 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005426 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005427
Victor Stinner8c62be82010-05-06 00:08:46 +00005428 /* spawnv has three arguments: (mode, path, argv), where
5429 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005430
Victor Stinner8c62be82010-05-06 00:08:46 +00005431 if (PyList_Check(argv)) {
5432 argc = PyList_Size(argv);
5433 getitem = PyList_GetItem;
5434 }
5435 else if (PyTuple_Check(argv)) {
5436 argc = PyTuple_Size(argv);
5437 getitem = PyTuple_GetItem;
5438 }
5439 else {
5440 PyErr_SetString(PyExc_TypeError,
5441 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005442 return NULL;
5443 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005444 if (argc == 0) {
5445 PyErr_SetString(PyExc_ValueError,
5446 "spawnv() arg 2 cannot be empty");
5447 return NULL;
5448 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005449
Steve Dowercc16be82016-09-08 10:35:16 -07005450 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005451 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005452 return PyErr_NoMemory();
5453 }
5454 for (i = 0; i < argc; i++) {
5455 if (!fsconvert_strdup((*getitem)(argv, i),
5456 &argvlist[i])) {
5457 free_string_array(argvlist, i);
5458 PyErr_SetString(
5459 PyExc_TypeError,
5460 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005461 return NULL;
5462 }
Steve Dower93ff8722016-11-19 19:03:54 -08005463 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005464 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005465 PyErr_SetString(
5466 PyExc_ValueError,
5467 "spawnv() arg 2 first element cannot be empty");
5468 return NULL;
5469 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005470 }
5471 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005472
Victor Stinner8c62be82010-05-06 00:08:46 +00005473 if (mode == _OLD_P_OVERLAY)
5474 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005475
Victor Stinner8c62be82010-05-06 00:08:46 +00005476 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005477 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005478#ifdef HAVE_WSPAWNV
5479 spawnval = _wspawnv(mode, path->wide, argvlist);
5480#else
5481 spawnval = _spawnv(mode, path->narrow, argvlist);
5482#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005483 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005484 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005485
Victor Stinner8c62be82010-05-06 00:08:46 +00005486 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005487
Victor Stinner8c62be82010-05-06 00:08:46 +00005488 if (spawnval == -1)
5489 return posix_error();
5490 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005491 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005492}
5493
Larry Hastings2f936352014-08-05 14:04:04 +10005494/*[clinic input]
5495os.spawnve
5496
5497 mode: int
5498 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005499 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005500 Path of executable file.
5501 argv: object
5502 Tuple or list of strings.
5503 env: object
5504 Dictionary of strings mapping to strings.
5505 /
5506
5507Execute the program specified by path in a new process.
5508[clinic start generated code]*/
5509
Larry Hastings2f936352014-08-05 14:04:04 +10005510static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005511os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005512 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005513/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005514{
Steve Dowercc16be82016-09-08 10:35:16 -07005515 EXECV_CHAR **argvlist;
5516 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005517 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005518 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005519 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005520 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005521 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005522
Victor Stinner8c62be82010-05-06 00:08:46 +00005523 /* spawnve has four arguments: (mode, path, argv, env), where
5524 argv is a list or tuple of strings and env is a dictionary
5525 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005526
Victor Stinner8c62be82010-05-06 00:08:46 +00005527 if (PyList_Check(argv)) {
5528 argc = PyList_Size(argv);
5529 getitem = PyList_GetItem;
5530 }
5531 else if (PyTuple_Check(argv)) {
5532 argc = PyTuple_Size(argv);
5533 getitem = PyTuple_GetItem;
5534 }
5535 else {
5536 PyErr_SetString(PyExc_TypeError,
5537 "spawnve() arg 2 must be a tuple or list");
5538 goto fail_0;
5539 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005540 if (argc == 0) {
5541 PyErr_SetString(PyExc_ValueError,
5542 "spawnve() arg 2 cannot be empty");
5543 goto fail_0;
5544 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005545 if (!PyMapping_Check(env)) {
5546 PyErr_SetString(PyExc_TypeError,
5547 "spawnve() arg 3 must be a mapping object");
5548 goto fail_0;
5549 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005550
Steve Dowercc16be82016-09-08 10:35:16 -07005551 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005552 if (argvlist == NULL) {
5553 PyErr_NoMemory();
5554 goto fail_0;
5555 }
5556 for (i = 0; i < argc; i++) {
5557 if (!fsconvert_strdup((*getitem)(argv, i),
5558 &argvlist[i]))
5559 {
5560 lastarg = i;
5561 goto fail_1;
5562 }
Steve Dowerbce26262016-11-19 19:17:26 -08005563 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005564 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005565 PyErr_SetString(
5566 PyExc_ValueError,
5567 "spawnv() arg 2 first element cannot be empty");
5568 goto fail_1;
5569 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005570 }
5571 lastarg = argc;
5572 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005573
Victor Stinner8c62be82010-05-06 00:08:46 +00005574 envlist = parse_envlist(env, &envc);
5575 if (envlist == NULL)
5576 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005577
Victor Stinner8c62be82010-05-06 00:08:46 +00005578 if (mode == _OLD_P_OVERLAY)
5579 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005580
Victor Stinner8c62be82010-05-06 00:08:46 +00005581 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005582 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005583#ifdef HAVE_WSPAWNV
5584 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5585#else
5586 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5587#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005588 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005589 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005590
Victor Stinner8c62be82010-05-06 00:08:46 +00005591 if (spawnval == -1)
5592 (void) posix_error();
5593 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005594 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005595
Victor Stinner8c62be82010-05-06 00:08:46 +00005596 while (--envc >= 0)
5597 PyMem_DEL(envlist[envc]);
5598 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005599 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005600 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005601 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005602 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005603}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005604
Guido van Rossuma1065681999-01-25 23:20:23 +00005605#endif /* HAVE_SPAWNV */
5606
5607
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005608#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005609
5610/* Helper function to validate arguments.
5611 Returns 0 on success. non-zero on failure with a TypeError raised.
5612 If obj is non-NULL it must be callable. */
5613static int
5614check_null_or_callable(PyObject *obj, const char* obj_name)
5615{
5616 if (obj && !PyCallable_Check(obj)) {
5617 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5618 obj_name, Py_TYPE(obj)->tp_name);
5619 return -1;
5620 }
5621 return 0;
5622}
5623
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005624/*[clinic input]
5625os.register_at_fork
5626
Gregory P. Smith163468a2017-05-29 10:03:41 -07005627 *
5628 before: object=NULL
5629 A callable to be called in the parent before the fork() syscall.
5630 after_in_child: object=NULL
5631 A callable to be called in the child after fork().
5632 after_in_parent: object=NULL
5633 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005634
Gregory P. Smith163468a2017-05-29 10:03:41 -07005635Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005636
Gregory P. Smith163468a2017-05-29 10:03:41 -07005637'before' callbacks are called in reverse order.
5638'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005639
5640[clinic start generated code]*/
5641
5642static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005643os_register_at_fork_impl(PyObject *module, PyObject *before,
5644 PyObject *after_in_child, PyObject *after_in_parent)
5645/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005646{
5647 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005648
Gregory P. Smith163468a2017-05-29 10:03:41 -07005649 if (!before && !after_in_child && !after_in_parent) {
5650 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5651 return NULL;
5652 }
5653 if (check_null_or_callable(before, "before") ||
5654 check_null_or_callable(after_in_child, "after_in_child") ||
5655 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005656 return NULL;
5657 }
5658 interp = PyThreadState_Get()->interp;
5659
Gregory P. Smith163468a2017-05-29 10:03:41 -07005660 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005661 return NULL;
5662 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005663 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005664 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005665 }
5666 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5667 return NULL;
5668 }
5669 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005670}
5671#endif /* HAVE_FORK */
5672
5673
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005674#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005675/*[clinic input]
5676os.fork1
5677
5678Fork a child process with a single multiplexed (i.e., not bound) thread.
5679
5680Return 0 to child process and PID of child to parent process.
5681[clinic start generated code]*/
5682
Larry Hastings2f936352014-08-05 14:04:04 +10005683static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005684os_fork1_impl(PyObject *module)
5685/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005686{
Victor Stinner8c62be82010-05-06 00:08:46 +00005687 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005688
5689 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005690 pid = fork1();
5691 if (pid == 0) {
5692 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005693 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005694 } else {
5695 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005696 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005697 }
5698 if (pid == -1)
5699 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005700 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005701}
Larry Hastings2f936352014-08-05 14:04:04 +10005702#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005703
5704
Guido van Rossumad0ee831995-03-01 10:34:45 +00005705#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005706/*[clinic input]
5707os.fork
5708
5709Fork a child process.
5710
5711Return 0 to child process and PID of child to parent process.
5712[clinic start generated code]*/
5713
Larry Hastings2f936352014-08-05 14:04:04 +10005714static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005715os_fork_impl(PyObject *module)
5716/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005717{
Victor Stinner8c62be82010-05-06 00:08:46 +00005718 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005719
5720 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005721 pid = fork();
5722 if (pid == 0) {
5723 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005724 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005725 } else {
5726 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005727 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005728 }
5729 if (pid == -1)
5730 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005731 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005732}
Larry Hastings2f936352014-08-05 14:04:04 +10005733#endif /* HAVE_FORK */
5734
Guido van Rossum85e3b011991-06-03 12:42:10 +00005735
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005736#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005737#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005738/*[clinic input]
5739os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005740
Larry Hastings2f936352014-08-05 14:04:04 +10005741 policy: int
5742
5743Get the maximum scheduling priority for policy.
5744[clinic start generated code]*/
5745
Larry Hastings2f936352014-08-05 14:04:04 +10005746static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005747os_sched_get_priority_max_impl(PyObject *module, int policy)
5748/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005749{
5750 int max;
5751
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005752 max = sched_get_priority_max(policy);
5753 if (max < 0)
5754 return posix_error();
5755 return PyLong_FromLong(max);
5756}
5757
Larry Hastings2f936352014-08-05 14:04:04 +10005758
5759/*[clinic input]
5760os.sched_get_priority_min
5761
5762 policy: int
5763
5764Get the minimum scheduling priority for policy.
5765[clinic start generated code]*/
5766
Larry Hastings2f936352014-08-05 14:04:04 +10005767static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005768os_sched_get_priority_min_impl(PyObject *module, int policy)
5769/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005770{
5771 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005772 if (min < 0)
5773 return posix_error();
5774 return PyLong_FromLong(min);
5775}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005776#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5777
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005778
Larry Hastings2f936352014-08-05 14:04:04 +10005779#ifdef HAVE_SCHED_SETSCHEDULER
5780/*[clinic input]
5781os.sched_getscheduler
5782 pid: pid_t
5783 /
5784
5785Get the scheduling policy for the process identifiedy by pid.
5786
5787Passing 0 for pid returns the scheduling policy for the calling process.
5788[clinic start generated code]*/
5789
Larry Hastings2f936352014-08-05 14:04:04 +10005790static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005791os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5792/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005793{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005794 int policy;
5795
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005796 policy = sched_getscheduler(pid);
5797 if (policy < 0)
5798 return posix_error();
5799 return PyLong_FromLong(policy);
5800}
Larry Hastings2f936352014-08-05 14:04:04 +10005801#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005802
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005803
5804#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005805/*[clinic input]
5806class os.sched_param "PyObject *" "&SchedParamType"
5807
5808@classmethod
5809os.sched_param.__new__
5810
5811 sched_priority: object
5812 A scheduling parameter.
5813
5814Current has only one field: sched_priority");
5815[clinic start generated code]*/
5816
Larry Hastings2f936352014-08-05 14:04:04 +10005817static PyObject *
5818os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005819/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005820{
5821 PyObject *res;
5822
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005823 res = PyStructSequence_New(type);
5824 if (!res)
5825 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005826 Py_INCREF(sched_priority);
5827 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005828 return res;
5829}
5830
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005831
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005832PyDoc_VAR(os_sched_param__doc__);
5833
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005834static PyStructSequence_Field sched_param_fields[] = {
5835 {"sched_priority", "the scheduling priority"},
5836 {0}
5837};
5838
5839static PyStructSequence_Desc sched_param_desc = {
5840 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005841 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005842 sched_param_fields,
5843 1
5844};
5845
5846static int
5847convert_sched_param(PyObject *param, struct sched_param *res)
5848{
5849 long priority;
5850
5851 if (Py_TYPE(param) != &SchedParamType) {
5852 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5853 return 0;
5854 }
5855 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5856 if (priority == -1 && PyErr_Occurred())
5857 return 0;
5858 if (priority > INT_MAX || priority < INT_MIN) {
5859 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5860 return 0;
5861 }
5862 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5863 return 1;
5864}
Larry Hastings2f936352014-08-05 14:04:04 +10005865#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005866
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005867
5868#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005869/*[clinic input]
5870os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005871
Larry Hastings2f936352014-08-05 14:04:04 +10005872 pid: pid_t
5873 policy: int
5874 param: sched_param
5875 /
5876
5877Set the scheduling policy for the process identified by pid.
5878
5879If pid is 0, the calling process is changed.
5880param is an instance of sched_param.
5881[clinic start generated code]*/
5882
Larry Hastings2f936352014-08-05 14:04:04 +10005883static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005884os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005885 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005886/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005887{
Jesus Cea9c822272011-09-10 01:40:52 +02005888 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005889 ** sched_setscheduler() returns 0 in Linux, but the previous
5890 ** scheduling policy under Solaris/Illumos, and others.
5891 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005892 */
Larry Hastings2f936352014-08-05 14:04:04 +10005893 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005894 return posix_error();
5895 Py_RETURN_NONE;
5896}
Larry Hastings2f936352014-08-05 14:04:04 +10005897#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005898
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005899
5900#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005901/*[clinic input]
5902os.sched_getparam
5903 pid: pid_t
5904 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005905
Larry Hastings2f936352014-08-05 14:04:04 +10005906Returns scheduling parameters for the process identified by pid.
5907
5908If pid is 0, returns parameters for the calling process.
5909Return value is an instance of sched_param.
5910[clinic start generated code]*/
5911
Larry Hastings2f936352014-08-05 14:04:04 +10005912static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005913os_sched_getparam_impl(PyObject *module, pid_t pid)
5914/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005915{
5916 struct sched_param param;
5917 PyObject *result;
5918 PyObject *priority;
5919
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005920 if (sched_getparam(pid, &param))
5921 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005922 result = PyStructSequence_New(&SchedParamType);
5923 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005924 return NULL;
5925 priority = PyLong_FromLong(param.sched_priority);
5926 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005927 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005928 return NULL;
5929 }
Larry Hastings2f936352014-08-05 14:04:04 +10005930 PyStructSequence_SET_ITEM(result, 0, priority);
5931 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005932}
5933
Larry Hastings2f936352014-08-05 14:04:04 +10005934
5935/*[clinic input]
5936os.sched_setparam
5937 pid: pid_t
5938 param: sched_param
5939 /
5940
5941Set scheduling parameters for the process identified by pid.
5942
5943If pid is 0, sets parameters for the calling process.
5944param should be an instance of sched_param.
5945[clinic start generated code]*/
5946
Larry Hastings2f936352014-08-05 14:04:04 +10005947static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005948os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005949 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005950/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005951{
5952 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005953 return posix_error();
5954 Py_RETURN_NONE;
5955}
Larry Hastings2f936352014-08-05 14:04:04 +10005956#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005957
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005958
5959#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005960/*[clinic input]
5961os.sched_rr_get_interval -> double
5962 pid: pid_t
5963 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005964
Larry Hastings2f936352014-08-05 14:04:04 +10005965Return the round-robin quantum for the process identified by pid, in seconds.
5966
5967Value returned is a float.
5968[clinic start generated code]*/
5969
Larry Hastings2f936352014-08-05 14:04:04 +10005970static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005971os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5972/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005973{
5974 struct timespec interval;
5975 if (sched_rr_get_interval(pid, &interval)) {
5976 posix_error();
5977 return -1.0;
5978 }
5979 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5980}
5981#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005982
Larry Hastings2f936352014-08-05 14:04:04 +10005983
5984/*[clinic input]
5985os.sched_yield
5986
5987Voluntarily relinquish the CPU.
5988[clinic start generated code]*/
5989
Larry Hastings2f936352014-08-05 14:04:04 +10005990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005991os_sched_yield_impl(PyObject *module)
5992/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005993{
5994 if (sched_yield())
5995 return posix_error();
5996 Py_RETURN_NONE;
5997}
5998
Benjamin Peterson2740af82011-08-02 17:41:34 -05005999#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006000/* The minimum number of CPUs allocated in a cpu_set_t */
6001static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006002
Larry Hastings2f936352014-08-05 14:04:04 +10006003/*[clinic input]
6004os.sched_setaffinity
6005 pid: pid_t
6006 mask : object
6007 /
6008
6009Set the CPU affinity of the process identified by pid to mask.
6010
6011mask should be an iterable of integers identifying CPUs.
6012[clinic start generated code]*/
6013
Larry Hastings2f936352014-08-05 14:04:04 +10006014static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006015os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6016/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006017{
Antoine Pitrou84869872012-08-04 16:16:35 +02006018 int ncpus;
6019 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006020 cpu_set_t *cpu_set = NULL;
6021 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006022
Larry Hastings2f936352014-08-05 14:04:04 +10006023 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006024 if (iterator == NULL)
6025 return NULL;
6026
6027 ncpus = NCPUS_START;
6028 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006029 cpu_set = CPU_ALLOC(ncpus);
6030 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006031 PyErr_NoMemory();
6032 goto error;
6033 }
Larry Hastings2f936352014-08-05 14:04:04 +10006034 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006035
6036 while ((item = PyIter_Next(iterator))) {
6037 long cpu;
6038 if (!PyLong_Check(item)) {
6039 PyErr_Format(PyExc_TypeError,
6040 "expected an iterator of ints, "
6041 "but iterator yielded %R",
6042 Py_TYPE(item));
6043 Py_DECREF(item);
6044 goto error;
6045 }
6046 cpu = PyLong_AsLong(item);
6047 Py_DECREF(item);
6048 if (cpu < 0) {
6049 if (!PyErr_Occurred())
6050 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6051 goto error;
6052 }
6053 if (cpu > INT_MAX - 1) {
6054 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6055 goto error;
6056 }
6057 if (cpu >= ncpus) {
6058 /* Grow CPU mask to fit the CPU number */
6059 int newncpus = ncpus;
6060 cpu_set_t *newmask;
6061 size_t newsetsize;
6062 while (newncpus <= cpu) {
6063 if (newncpus > INT_MAX / 2)
6064 newncpus = cpu + 1;
6065 else
6066 newncpus = newncpus * 2;
6067 }
6068 newmask = CPU_ALLOC(newncpus);
6069 if (newmask == NULL) {
6070 PyErr_NoMemory();
6071 goto error;
6072 }
6073 newsetsize = CPU_ALLOC_SIZE(newncpus);
6074 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006075 memcpy(newmask, cpu_set, setsize);
6076 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006077 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006078 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006079 ncpus = newncpus;
6080 }
Larry Hastings2f936352014-08-05 14:04:04 +10006081 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006082 }
6083 Py_CLEAR(iterator);
6084
Larry Hastings2f936352014-08-05 14:04:04 +10006085 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006086 posix_error();
6087 goto error;
6088 }
Larry Hastings2f936352014-08-05 14:04:04 +10006089 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006090 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006091
6092error:
Larry Hastings2f936352014-08-05 14:04:04 +10006093 if (cpu_set)
6094 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006095 Py_XDECREF(iterator);
6096 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006097}
6098
Larry Hastings2f936352014-08-05 14:04:04 +10006099
6100/*[clinic input]
6101os.sched_getaffinity
6102 pid: pid_t
6103 /
6104
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006105Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006106
6107The affinity is returned as a set of CPU identifiers.
6108[clinic start generated code]*/
6109
Larry Hastings2f936352014-08-05 14:04:04 +10006110static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006111os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006112/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006113{
Antoine Pitrou84869872012-08-04 16:16:35 +02006114 int cpu, ncpus, count;
6115 size_t setsize;
6116 cpu_set_t *mask = NULL;
6117 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006118
Antoine Pitrou84869872012-08-04 16:16:35 +02006119 ncpus = NCPUS_START;
6120 while (1) {
6121 setsize = CPU_ALLOC_SIZE(ncpus);
6122 mask = CPU_ALLOC(ncpus);
6123 if (mask == NULL)
6124 return PyErr_NoMemory();
6125 if (sched_getaffinity(pid, setsize, mask) == 0)
6126 break;
6127 CPU_FREE(mask);
6128 if (errno != EINVAL)
6129 return posix_error();
6130 if (ncpus > INT_MAX / 2) {
6131 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6132 "a large enough CPU set");
6133 return NULL;
6134 }
6135 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006136 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006137
6138 res = PySet_New(NULL);
6139 if (res == NULL)
6140 goto error;
6141 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6142 if (CPU_ISSET_S(cpu, setsize, mask)) {
6143 PyObject *cpu_num = PyLong_FromLong(cpu);
6144 --count;
6145 if (cpu_num == NULL)
6146 goto error;
6147 if (PySet_Add(res, cpu_num)) {
6148 Py_DECREF(cpu_num);
6149 goto error;
6150 }
6151 Py_DECREF(cpu_num);
6152 }
6153 }
6154 CPU_FREE(mask);
6155 return res;
6156
6157error:
6158 if (mask)
6159 CPU_FREE(mask);
6160 Py_XDECREF(res);
6161 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006162}
6163
Benjamin Peterson2740af82011-08-02 17:41:34 -05006164#endif /* HAVE_SCHED_SETAFFINITY */
6165
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006166#endif /* HAVE_SCHED_H */
6167
Larry Hastings2f936352014-08-05 14:04:04 +10006168
Neal Norwitzb59798b2003-03-21 01:43:31 +00006169/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006170/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6171#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006172#define DEV_PTY_FILE "/dev/ptc"
6173#define HAVE_DEV_PTMX
6174#else
6175#define DEV_PTY_FILE "/dev/ptmx"
6176#endif
6177
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006178#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006179#ifdef HAVE_PTY_H
6180#include <pty.h>
6181#else
6182#ifdef HAVE_LIBUTIL_H
6183#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006184#else
6185#ifdef HAVE_UTIL_H
6186#include <util.h>
6187#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006188#endif /* HAVE_LIBUTIL_H */
6189#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006190#ifdef HAVE_STROPTS_H
6191#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006192#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006193#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006194
Larry Hastings2f936352014-08-05 14:04:04 +10006195
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006196#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006197/*[clinic input]
6198os.openpty
6199
6200Open a pseudo-terminal.
6201
6202Return a tuple of (master_fd, slave_fd) containing open file descriptors
6203for both the master and slave ends.
6204[clinic start generated code]*/
6205
Larry Hastings2f936352014-08-05 14:04:04 +10006206static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006207os_openpty_impl(PyObject *module)
6208/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006209{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006210 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006211#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006212 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006213#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006214#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006215 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006216#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006217 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006218#endif
6219#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006220
Thomas Wouters70c21a12000-07-14 14:28:33 +00006221#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006222 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006223 goto posix_error;
6224
6225 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6226 goto error;
6227 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6228 goto error;
6229
Neal Norwitzb59798b2003-03-21 01:43:31 +00006230#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006231 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6232 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006233 goto posix_error;
6234 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6235 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006236
Victor Stinnerdaf45552013-08-28 00:53:59 +02006237 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006238 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006239 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006240
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006241#else
Victor Stinner000de532013-11-25 23:19:58 +01006242 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006243 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006244 goto posix_error;
6245
Victor Stinner8c62be82010-05-06 00:08:46 +00006246 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006247
Victor Stinner8c62be82010-05-06 00:08:46 +00006248 /* change permission of slave */
6249 if (grantpt(master_fd) < 0) {
6250 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006251 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006252 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006253
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 /* unlock slave */
6255 if (unlockpt(master_fd) < 0) {
6256 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006257 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006258 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006259
Victor Stinner8c62be82010-05-06 00:08:46 +00006260 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006261
Victor Stinner8c62be82010-05-06 00:08:46 +00006262 slave_name = ptsname(master_fd); /* get name of slave */
6263 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006264 goto posix_error;
6265
6266 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006267 if (slave_fd == -1)
6268 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006269
6270 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6271 goto posix_error;
6272
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006273#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006274 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6275 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006276#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006277 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006278#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006279#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006280#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006281
Victor Stinner8c62be82010-05-06 00:08:46 +00006282 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006283
Victor Stinnerdaf45552013-08-28 00:53:59 +02006284posix_error:
6285 posix_error();
6286error:
6287 if (master_fd != -1)
6288 close(master_fd);
6289 if (slave_fd != -1)
6290 close(slave_fd);
6291 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006292}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006293#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006294
Larry Hastings2f936352014-08-05 14:04:04 +10006295
Fred Drake8cef4cf2000-06-28 16:40:38 +00006296#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006297/*[clinic input]
6298os.forkpty
6299
6300Fork a new process with a new pseudo-terminal as controlling tty.
6301
6302Returns a tuple of (pid, master_fd).
6303Like fork(), return pid of 0 to the child process,
6304and pid of child to the parent process.
6305To both, return fd of newly opened pseudo-terminal.
6306[clinic start generated code]*/
6307
Larry Hastings2f936352014-08-05 14:04:04 +10006308static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006309os_forkpty_impl(PyObject *module)
6310/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006311{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006312 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006313 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006314
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006315 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006316 pid = forkpty(&master_fd, NULL, NULL, NULL);
6317 if (pid == 0) {
6318 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006319 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006320 } else {
6321 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006322 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006323 }
6324 if (pid == -1)
6325 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006326 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006327}
Larry Hastings2f936352014-08-05 14:04:04 +10006328#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006329
Ross Lagerwall7807c352011-03-17 20:20:30 +02006330
Guido van Rossumad0ee831995-03-01 10:34:45 +00006331#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006332/*[clinic input]
6333os.getegid
6334
6335Return the current process's effective group id.
6336[clinic start generated code]*/
6337
Larry Hastings2f936352014-08-05 14:04:04 +10006338static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006339os_getegid_impl(PyObject *module)
6340/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006341{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006342 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006343}
Larry Hastings2f936352014-08-05 14:04:04 +10006344#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006346
Guido van Rossumad0ee831995-03-01 10:34:45 +00006347#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006348/*[clinic input]
6349os.geteuid
6350
6351Return the current process's effective user id.
6352[clinic start generated code]*/
6353
Larry Hastings2f936352014-08-05 14:04:04 +10006354static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006355os_geteuid_impl(PyObject *module)
6356/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006357{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006358 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006359}
Larry Hastings2f936352014-08-05 14:04:04 +10006360#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006361
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006362
Guido van Rossumad0ee831995-03-01 10:34:45 +00006363#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006364/*[clinic input]
6365os.getgid
6366
6367Return the current process's group id.
6368[clinic start generated code]*/
6369
Larry Hastings2f936352014-08-05 14:04:04 +10006370static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006371os_getgid_impl(PyObject *module)
6372/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006373{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006374 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006375}
Larry Hastings2f936352014-08-05 14:04:04 +10006376#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006377
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006378
Berker Peksag39404992016-09-15 20:45:16 +03006379#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006380/*[clinic input]
6381os.getpid
6382
6383Return the current process id.
6384[clinic start generated code]*/
6385
Larry Hastings2f936352014-08-05 14:04:04 +10006386static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006387os_getpid_impl(PyObject *module)
6388/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006389{
Victor Stinner8c62be82010-05-06 00:08:46 +00006390 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006391}
Berker Peksag39404992016-09-15 20:45:16 +03006392#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006393
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006394#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006395
6396/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006397PyDoc_STRVAR(posix_getgrouplist__doc__,
6398"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6399Returns a list of groups to which a user belongs.\n\n\
6400 user: username to lookup\n\
6401 group: base group id of the user");
6402
6403static PyObject *
6404posix_getgrouplist(PyObject *self, PyObject *args)
6405{
6406#ifdef NGROUPS_MAX
6407#define MAX_GROUPS NGROUPS_MAX
6408#else
6409 /* defined to be 16 on Solaris7, so this should be a small number */
6410#define MAX_GROUPS 64
6411#endif
6412
6413 const char *user;
6414 int i, ngroups;
6415 PyObject *list;
6416#ifdef __APPLE__
6417 int *groups, basegid;
6418#else
6419 gid_t *groups, basegid;
6420#endif
6421 ngroups = MAX_GROUPS;
6422
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006423#ifdef __APPLE__
6424 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006425 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006426#else
6427 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6428 _Py_Gid_Converter, &basegid))
6429 return NULL;
6430#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006431
6432#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006433 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006434#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006435 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006436#endif
6437 if (groups == NULL)
6438 return PyErr_NoMemory();
6439
6440 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6441 PyMem_Del(groups);
6442 return posix_error();
6443 }
6444
6445 list = PyList_New(ngroups);
6446 if (list == NULL) {
6447 PyMem_Del(groups);
6448 return NULL;
6449 }
6450
6451 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006452#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006453 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006454#else
6455 PyObject *o = _PyLong_FromGid(groups[i]);
6456#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006457 if (o == NULL) {
6458 Py_DECREF(list);
6459 PyMem_Del(groups);
6460 return NULL;
6461 }
6462 PyList_SET_ITEM(list, i, o);
6463 }
6464
6465 PyMem_Del(groups);
6466
6467 return list;
6468}
Larry Hastings2f936352014-08-05 14:04:04 +10006469#endif /* HAVE_GETGROUPLIST */
6470
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006471
Fred Drakec9680921999-12-13 16:37:25 +00006472#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006473/*[clinic input]
6474os.getgroups
6475
6476Return list of supplemental group IDs for the process.
6477[clinic start generated code]*/
6478
Larry Hastings2f936352014-08-05 14:04:04 +10006479static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006480os_getgroups_impl(PyObject *module)
6481/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006482{
6483 PyObject *result = NULL;
6484
Fred Drakec9680921999-12-13 16:37:25 +00006485#ifdef NGROUPS_MAX
6486#define MAX_GROUPS NGROUPS_MAX
6487#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006488 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006489#define MAX_GROUPS 64
6490#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006491 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006492
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006493 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006494 * This is a helper variable to store the intermediate result when
6495 * that happens.
6496 *
6497 * To keep the code readable the OSX behaviour is unconditional,
6498 * according to the POSIX spec this should be safe on all unix-y
6499 * systems.
6500 */
6501 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006502 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006503
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006504#ifdef __APPLE__
6505 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6506 * there are more groups than can fit in grouplist. Therefore, on OS X
6507 * always first call getgroups with length 0 to get the actual number
6508 * of groups.
6509 */
6510 n = getgroups(0, NULL);
6511 if (n < 0) {
6512 return posix_error();
6513 } else if (n <= MAX_GROUPS) {
6514 /* groups will fit in existing array */
6515 alt_grouplist = grouplist;
6516 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006517 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006518 if (alt_grouplist == NULL) {
6519 errno = EINVAL;
6520 return posix_error();
6521 }
6522 }
6523
6524 n = getgroups(n, alt_grouplist);
6525 if (n == -1) {
6526 if (alt_grouplist != grouplist) {
6527 PyMem_Free(alt_grouplist);
6528 }
6529 return posix_error();
6530 }
6531#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006532 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006533 if (n < 0) {
6534 if (errno == EINVAL) {
6535 n = getgroups(0, NULL);
6536 if (n == -1) {
6537 return posix_error();
6538 }
6539 if (n == 0) {
6540 /* Avoid malloc(0) */
6541 alt_grouplist = grouplist;
6542 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006543 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006544 if (alt_grouplist == NULL) {
6545 errno = EINVAL;
6546 return posix_error();
6547 }
6548 n = getgroups(n, alt_grouplist);
6549 if (n == -1) {
6550 PyMem_Free(alt_grouplist);
6551 return posix_error();
6552 }
6553 }
6554 } else {
6555 return posix_error();
6556 }
6557 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006558#endif
6559
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006560 result = PyList_New(n);
6561 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 int i;
6563 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006564 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006566 Py_DECREF(result);
6567 result = NULL;
6568 break;
Fred Drakec9680921999-12-13 16:37:25 +00006569 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006571 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006572 }
6573
6574 if (alt_grouplist != grouplist) {
6575 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006576 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006577
Fred Drakec9680921999-12-13 16:37:25 +00006578 return result;
6579}
Larry Hastings2f936352014-08-05 14:04:04 +10006580#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006581
Antoine Pitroub7572f02009-12-02 20:46:48 +00006582#ifdef HAVE_INITGROUPS
6583PyDoc_STRVAR(posix_initgroups__doc__,
6584"initgroups(username, gid) -> None\n\n\
6585Call the system initgroups() to initialize the group access list with all of\n\
6586the groups of which the specified username is a member, plus the specified\n\
6587group id.");
6588
Larry Hastings2f936352014-08-05 14:04:04 +10006589/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006590static PyObject *
6591posix_initgroups(PyObject *self, PyObject *args)
6592{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006593 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006594 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006595 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006596#ifdef __APPLE__
6597 int gid;
6598#else
6599 gid_t gid;
6600#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006601
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006602#ifdef __APPLE__
6603 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6604 PyUnicode_FSConverter, &oname,
6605 &gid))
6606#else
6607 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6608 PyUnicode_FSConverter, &oname,
6609 _Py_Gid_Converter, &gid))
6610#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006611 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006612 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006613
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006614 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006615 Py_DECREF(oname);
6616 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006617 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006618
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006619 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006620}
Larry Hastings2f936352014-08-05 14:04:04 +10006621#endif /* HAVE_INITGROUPS */
6622
Antoine Pitroub7572f02009-12-02 20:46:48 +00006623
Martin v. Löwis606edc12002-06-13 21:09:11 +00006624#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006625/*[clinic input]
6626os.getpgid
6627
6628 pid: pid_t
6629
6630Call the system call getpgid(), and return the result.
6631[clinic start generated code]*/
6632
Larry Hastings2f936352014-08-05 14:04:04 +10006633static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006634os_getpgid_impl(PyObject *module, pid_t pid)
6635/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006636{
6637 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006638 if (pgid < 0)
6639 return posix_error();
6640 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006641}
6642#endif /* HAVE_GETPGID */
6643
6644
Guido van Rossumb6775db1994-08-01 11:34:53 +00006645#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006646/*[clinic input]
6647os.getpgrp
6648
6649Return the current process group id.
6650[clinic start generated code]*/
6651
Larry Hastings2f936352014-08-05 14:04:04 +10006652static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006653os_getpgrp_impl(PyObject *module)
6654/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006655{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006656#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006657 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006658#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006660#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006661}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006662#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006664
Guido van Rossumb6775db1994-08-01 11:34:53 +00006665#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006666/*[clinic input]
6667os.setpgrp
6668
6669Make the current process the leader of its process group.
6670[clinic start generated code]*/
6671
Larry Hastings2f936352014-08-05 14:04:04 +10006672static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006673os_setpgrp_impl(PyObject *module)
6674/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006675{
Guido van Rossum64933891994-10-20 21:56:42 +00006676#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006677 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006678#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006679 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006680#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006681 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006682 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006683}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006684#endif /* HAVE_SETPGRP */
6685
Guido van Rossumad0ee831995-03-01 10:34:45 +00006686#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006687
6688#ifdef MS_WINDOWS
6689#include <tlhelp32.h>
6690
6691static PyObject*
6692win32_getppid()
6693{
6694 HANDLE snapshot;
6695 pid_t mypid;
6696 PyObject* result = NULL;
6697 BOOL have_record;
6698 PROCESSENTRY32 pe;
6699
6700 mypid = getpid(); /* This function never fails */
6701
6702 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6703 if (snapshot == INVALID_HANDLE_VALUE)
6704 return PyErr_SetFromWindowsErr(GetLastError());
6705
6706 pe.dwSize = sizeof(pe);
6707 have_record = Process32First(snapshot, &pe);
6708 while (have_record) {
6709 if (mypid == (pid_t)pe.th32ProcessID) {
6710 /* We could cache the ulong value in a static variable. */
6711 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6712 break;
6713 }
6714
6715 have_record = Process32Next(snapshot, &pe);
6716 }
6717
6718 /* If our loop exits and our pid was not found (result will be NULL)
6719 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6720 * error anyway, so let's raise it. */
6721 if (!result)
6722 result = PyErr_SetFromWindowsErr(GetLastError());
6723
6724 CloseHandle(snapshot);
6725
6726 return result;
6727}
6728#endif /*MS_WINDOWS*/
6729
Larry Hastings2f936352014-08-05 14:04:04 +10006730
6731/*[clinic input]
6732os.getppid
6733
6734Return the parent's process id.
6735
6736If the parent process has already exited, Windows machines will still
6737return its id; others systems will return the id of the 'init' process (1).
6738[clinic start generated code]*/
6739
Larry Hastings2f936352014-08-05 14:04:04 +10006740static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006741os_getppid_impl(PyObject *module)
6742/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006743{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006744#ifdef MS_WINDOWS
6745 return win32_getppid();
6746#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006747 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006748#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006749}
6750#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006751
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006752
Fred Drake12c6e2d1999-12-14 21:25:03 +00006753#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006754/*[clinic input]
6755os.getlogin
6756
6757Return the actual login name.
6758[clinic start generated code]*/
6759
Larry Hastings2f936352014-08-05 14:04:04 +10006760static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006761os_getlogin_impl(PyObject *module)
6762/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006763{
Victor Stinner8c62be82010-05-06 00:08:46 +00006764 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006765#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006766 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006767 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006768
6769 if (GetUserNameW(user_name, &num_chars)) {
6770 /* num_chars is the number of unicode chars plus null terminator */
6771 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006772 }
6773 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006774 result = PyErr_SetFromWindowsErr(GetLastError());
6775#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006776 char *name;
6777 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006778
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 errno = 0;
6780 name = getlogin();
6781 if (name == NULL) {
6782 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006783 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006784 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006785 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006786 }
6787 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006788 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006790#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006791 return result;
6792}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006793#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006794
Larry Hastings2f936352014-08-05 14:04:04 +10006795
Guido van Rossumad0ee831995-03-01 10:34:45 +00006796#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006797/*[clinic input]
6798os.getuid
6799
6800Return the current process's user id.
6801[clinic start generated code]*/
6802
Larry Hastings2f936352014-08-05 14:04:04 +10006803static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006804os_getuid_impl(PyObject *module)
6805/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006806{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006807 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006808}
Larry Hastings2f936352014-08-05 14:04:04 +10006809#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006810
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006811
Brian Curtineb24d742010-04-12 17:16:38 +00006812#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006813#define HAVE_KILL
6814#endif /* MS_WINDOWS */
6815
6816#ifdef HAVE_KILL
6817/*[clinic input]
6818os.kill
6819
6820 pid: pid_t
6821 signal: Py_ssize_t
6822 /
6823
6824Kill a process with a signal.
6825[clinic start generated code]*/
6826
Larry Hastings2f936352014-08-05 14:04:04 +10006827static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006828os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6829/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006830#ifndef MS_WINDOWS
6831{
6832 if (kill(pid, (int)signal) == -1)
6833 return posix_error();
6834 Py_RETURN_NONE;
6835}
6836#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006837{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006838 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006839 DWORD sig = (DWORD)signal;
6840 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006842
Victor Stinner8c62be82010-05-06 00:08:46 +00006843 /* Console processes which share a common console can be sent CTRL+C or
6844 CTRL+BREAK events, provided they handle said events. */
6845 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006846 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 err = GetLastError();
6848 PyErr_SetFromWindowsErr(err);
6849 }
6850 else
6851 Py_RETURN_NONE;
6852 }
Brian Curtineb24d742010-04-12 17:16:38 +00006853
Victor Stinner8c62be82010-05-06 00:08:46 +00006854 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6855 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006856 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 if (handle == NULL) {
6858 err = GetLastError();
6859 return PyErr_SetFromWindowsErr(err);
6860 }
Brian Curtineb24d742010-04-12 17:16:38 +00006861
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 if (TerminateProcess(handle, sig) == 0) {
6863 err = GetLastError();
6864 result = PyErr_SetFromWindowsErr(err);
6865 } else {
6866 Py_INCREF(Py_None);
6867 result = Py_None;
6868 }
Brian Curtineb24d742010-04-12 17:16:38 +00006869
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 CloseHandle(handle);
6871 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006872}
Larry Hastings2f936352014-08-05 14:04:04 +10006873#endif /* !MS_WINDOWS */
6874#endif /* HAVE_KILL */
6875
6876
6877#ifdef HAVE_KILLPG
6878/*[clinic input]
6879os.killpg
6880
6881 pgid: pid_t
6882 signal: int
6883 /
6884
6885Kill a process group with a signal.
6886[clinic start generated code]*/
6887
Larry Hastings2f936352014-08-05 14:04:04 +10006888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006889os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6890/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006891{
6892 /* XXX some man pages make the `pgid` parameter an int, others
6893 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6894 take the same type. Moreover, pid_t is always at least as wide as
6895 int (else compilation of this module fails), which is safe. */
6896 if (killpg(pgid, signal) == -1)
6897 return posix_error();
6898 Py_RETURN_NONE;
6899}
6900#endif /* HAVE_KILLPG */
6901
Brian Curtineb24d742010-04-12 17:16:38 +00006902
Guido van Rossumc0125471996-06-28 18:55:32 +00006903#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006904#ifdef HAVE_SYS_LOCK_H
6905#include <sys/lock.h>
6906#endif
6907
Larry Hastings2f936352014-08-05 14:04:04 +10006908/*[clinic input]
6909os.plock
6910 op: int
6911 /
6912
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006913Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006914[clinic start generated code]*/
6915
Larry Hastings2f936352014-08-05 14:04:04 +10006916static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006917os_plock_impl(PyObject *module, int op)
6918/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006919{
Victor Stinner8c62be82010-05-06 00:08:46 +00006920 if (plock(op) == -1)
6921 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006922 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006923}
Larry Hastings2f936352014-08-05 14:04:04 +10006924#endif /* HAVE_PLOCK */
6925
Guido van Rossumc0125471996-06-28 18:55:32 +00006926
Guido van Rossumb6775db1994-08-01 11:34:53 +00006927#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006928/*[clinic input]
6929os.setuid
6930
6931 uid: uid_t
6932 /
6933
6934Set the current process's user id.
6935[clinic start generated code]*/
6936
Larry Hastings2f936352014-08-05 14:04:04 +10006937static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006938os_setuid_impl(PyObject *module, uid_t uid)
6939/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006940{
Victor Stinner8c62be82010-05-06 00:08:46 +00006941 if (setuid(uid) < 0)
6942 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006943 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006944}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006945#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006947
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006948#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006949/*[clinic input]
6950os.seteuid
6951
6952 euid: uid_t
6953 /
6954
6955Set the current process's effective user id.
6956[clinic start generated code]*/
6957
Larry Hastings2f936352014-08-05 14:04:04 +10006958static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006959os_seteuid_impl(PyObject *module, uid_t euid)
6960/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006961{
6962 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006963 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006964 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006965}
6966#endif /* HAVE_SETEUID */
6967
Larry Hastings2f936352014-08-05 14:04:04 +10006968
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006969#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006970/*[clinic input]
6971os.setegid
6972
6973 egid: gid_t
6974 /
6975
6976Set the current process's effective group id.
6977[clinic start generated code]*/
6978
Larry Hastings2f936352014-08-05 14:04:04 +10006979static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006980os_setegid_impl(PyObject *module, gid_t egid)
6981/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006982{
6983 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006984 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006985 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006986}
6987#endif /* HAVE_SETEGID */
6988
Larry Hastings2f936352014-08-05 14:04:04 +10006989
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006990#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006991/*[clinic input]
6992os.setreuid
6993
6994 ruid: uid_t
6995 euid: uid_t
6996 /
6997
6998Set the current process's real and effective user ids.
6999[clinic start generated code]*/
7000
Larry Hastings2f936352014-08-05 14:04:04 +10007001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007002os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7003/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007004{
Victor Stinner8c62be82010-05-06 00:08:46 +00007005 if (setreuid(ruid, euid) < 0) {
7006 return posix_error();
7007 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007008 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007009 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007010}
7011#endif /* HAVE_SETREUID */
7012
Larry Hastings2f936352014-08-05 14:04:04 +10007013
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007014#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007015/*[clinic input]
7016os.setregid
7017
7018 rgid: gid_t
7019 egid: gid_t
7020 /
7021
7022Set the current process's real and effective group ids.
7023[clinic start generated code]*/
7024
Larry Hastings2f936352014-08-05 14:04:04 +10007025static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007026os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7027/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007028{
7029 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007031 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007032}
7033#endif /* HAVE_SETREGID */
7034
Larry Hastings2f936352014-08-05 14:04:04 +10007035
Guido van Rossumb6775db1994-08-01 11:34:53 +00007036#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007037/*[clinic input]
7038os.setgid
7039 gid: gid_t
7040 /
7041
7042Set the current process's group id.
7043[clinic start generated code]*/
7044
Larry Hastings2f936352014-08-05 14:04:04 +10007045static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007046os_setgid_impl(PyObject *module, gid_t gid)
7047/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007048{
Victor Stinner8c62be82010-05-06 00:08:46 +00007049 if (setgid(gid) < 0)
7050 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007051 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007052}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007053#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007054
Larry Hastings2f936352014-08-05 14:04:04 +10007055
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007056#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007057/*[clinic input]
7058os.setgroups
7059
7060 groups: object
7061 /
7062
7063Set the groups of the current process to list.
7064[clinic start generated code]*/
7065
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007066static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007067os_setgroups(PyObject *module, PyObject *groups)
7068/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007069{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007070 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007071 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007072
Victor Stinner8c62be82010-05-06 00:08:46 +00007073 if (!PySequence_Check(groups)) {
7074 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7075 return NULL;
7076 }
7077 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007078 if (len < 0) {
7079 return NULL;
7080 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 if (len > MAX_GROUPS) {
7082 PyErr_SetString(PyExc_ValueError, "too many groups");
7083 return NULL;
7084 }
7085 for(i = 0; i < len; i++) {
7086 PyObject *elem;
7087 elem = PySequence_GetItem(groups, i);
7088 if (!elem)
7089 return NULL;
7090 if (!PyLong_Check(elem)) {
7091 PyErr_SetString(PyExc_TypeError,
7092 "groups must be integers");
7093 Py_DECREF(elem);
7094 return NULL;
7095 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007096 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 Py_DECREF(elem);
7098 return NULL;
7099 }
7100 }
7101 Py_DECREF(elem);
7102 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007103
Victor Stinner8c62be82010-05-06 00:08:46 +00007104 if (setgroups(len, grouplist) < 0)
7105 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007106 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007107}
7108#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007109
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007110#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7111static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007112wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007113{
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 PyObject *result;
7115 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007116 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007117
Victor Stinner8c62be82010-05-06 00:08:46 +00007118 if (pid == -1)
7119 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007120
Victor Stinner8c62be82010-05-06 00:08:46 +00007121 if (struct_rusage == NULL) {
7122 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7123 if (m == NULL)
7124 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007125 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007126 Py_DECREF(m);
7127 if (struct_rusage == NULL)
7128 return NULL;
7129 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007130
Victor Stinner8c62be82010-05-06 00:08:46 +00007131 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7132 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7133 if (!result)
7134 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007135
7136#ifndef doubletime
7137#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7138#endif
7139
Victor Stinner8c62be82010-05-06 00:08:46 +00007140 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007141 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007142 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007143 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007144#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007145 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7146 SET_INT(result, 2, ru->ru_maxrss);
7147 SET_INT(result, 3, ru->ru_ixrss);
7148 SET_INT(result, 4, ru->ru_idrss);
7149 SET_INT(result, 5, ru->ru_isrss);
7150 SET_INT(result, 6, ru->ru_minflt);
7151 SET_INT(result, 7, ru->ru_majflt);
7152 SET_INT(result, 8, ru->ru_nswap);
7153 SET_INT(result, 9, ru->ru_inblock);
7154 SET_INT(result, 10, ru->ru_oublock);
7155 SET_INT(result, 11, ru->ru_msgsnd);
7156 SET_INT(result, 12, ru->ru_msgrcv);
7157 SET_INT(result, 13, ru->ru_nsignals);
7158 SET_INT(result, 14, ru->ru_nvcsw);
7159 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007160#undef SET_INT
7161
Victor Stinner8c62be82010-05-06 00:08:46 +00007162 if (PyErr_Occurred()) {
7163 Py_DECREF(result);
7164 return NULL;
7165 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007166
Victor Stinner8c62be82010-05-06 00:08:46 +00007167 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007168}
7169#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7170
Larry Hastings2f936352014-08-05 14:04:04 +10007171
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007172#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007173/*[clinic input]
7174os.wait3
7175
7176 options: int
7177Wait for completion of a child process.
7178
7179Returns a tuple of information about the child process:
7180 (pid, status, rusage)
7181[clinic start generated code]*/
7182
Larry Hastings2f936352014-08-05 14:04:04 +10007183static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007184os_wait3_impl(PyObject *module, int options)
7185/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007186{
Victor Stinner8c62be82010-05-06 00:08:46 +00007187 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007188 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007189 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007190 WAIT_TYPE status;
7191 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007192
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007193 do {
7194 Py_BEGIN_ALLOW_THREADS
7195 pid = wait3(&status, options, &ru);
7196 Py_END_ALLOW_THREADS
7197 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7198 if (pid < 0)
7199 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007200
Victor Stinner4195b5c2012-02-08 23:03:19 +01007201 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007202}
7203#endif /* HAVE_WAIT3 */
7204
Larry Hastings2f936352014-08-05 14:04:04 +10007205
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007206#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007207/*[clinic input]
7208
7209os.wait4
7210
7211 pid: pid_t
7212 options: int
7213
7214Wait for completion of a specific child process.
7215
7216Returns a tuple of information about the child process:
7217 (pid, status, rusage)
7218[clinic start generated code]*/
7219
Larry Hastings2f936352014-08-05 14:04:04 +10007220static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007221os_wait4_impl(PyObject *module, pid_t pid, int options)
7222/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007223{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007224 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007225 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007226 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007227 WAIT_TYPE status;
7228 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007229
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007230 do {
7231 Py_BEGIN_ALLOW_THREADS
7232 res = wait4(pid, &status, options, &ru);
7233 Py_END_ALLOW_THREADS
7234 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7235 if (res < 0)
7236 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007237
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007238 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007239}
7240#endif /* HAVE_WAIT4 */
7241
Larry Hastings2f936352014-08-05 14:04:04 +10007242
Ross Lagerwall7807c352011-03-17 20:20:30 +02007243#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007244/*[clinic input]
7245os.waitid
7246
7247 idtype: idtype_t
7248 Must be one of be P_PID, P_PGID or P_ALL.
7249 id: id_t
7250 The id to wait on.
7251 options: int
7252 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7253 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7254 /
7255
7256Returns the result of waiting for a process or processes.
7257
7258Returns either waitid_result or None if WNOHANG is specified and there are
7259no children in a waitable state.
7260[clinic start generated code]*/
7261
Larry Hastings2f936352014-08-05 14:04:04 +10007262static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007263os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7264/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007265{
7266 PyObject *result;
7267 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007268 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007269 siginfo_t si;
7270 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007271
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007272 do {
7273 Py_BEGIN_ALLOW_THREADS
7274 res = waitid(idtype, id, &si, options);
7275 Py_END_ALLOW_THREADS
7276 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7277 if (res < 0)
7278 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007279
7280 if (si.si_pid == 0)
7281 Py_RETURN_NONE;
7282
7283 result = PyStructSequence_New(&WaitidResultType);
7284 if (!result)
7285 return NULL;
7286
7287 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007288 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007289 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7290 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7291 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7292 if (PyErr_Occurred()) {
7293 Py_DECREF(result);
7294 return NULL;
7295 }
7296
7297 return result;
7298}
Larry Hastings2f936352014-08-05 14:04:04 +10007299#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007300
Larry Hastings2f936352014-08-05 14:04:04 +10007301
7302#if defined(HAVE_WAITPID)
7303/*[clinic input]
7304os.waitpid
7305 pid: pid_t
7306 options: int
7307 /
7308
7309Wait for completion of a given child process.
7310
7311Returns a tuple of information regarding the child process:
7312 (pid, status)
7313
7314The options argument is ignored on Windows.
7315[clinic start generated code]*/
7316
Larry Hastings2f936352014-08-05 14:04:04 +10007317static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007318os_waitpid_impl(PyObject *module, pid_t pid, int options)
7319/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007320{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007321 pid_t res;
7322 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007323 WAIT_TYPE status;
7324 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007325
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007326 do {
7327 Py_BEGIN_ALLOW_THREADS
7328 res = waitpid(pid, &status, options);
7329 Py_END_ALLOW_THREADS
7330 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7331 if (res < 0)
7332 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007333
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007334 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007335}
Tim Petersab034fa2002-02-01 11:27:43 +00007336#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007337/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007338/*[clinic input]
7339os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007340 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007341 options: int
7342 /
7343
7344Wait for completion of a given process.
7345
7346Returns a tuple of information regarding the process:
7347 (pid, status << 8)
7348
7349The options argument is ignored on Windows.
7350[clinic start generated code]*/
7351
Larry Hastings2f936352014-08-05 14:04:04 +10007352static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007353os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007354/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007355{
7356 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007357 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007358 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007359
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007360 do {
7361 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007362 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007363 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007364 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007365 Py_END_ALLOW_THREADS
7366 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007367 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007368 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007369
Victor Stinner8c62be82010-05-06 00:08:46 +00007370 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007371 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007372}
Larry Hastings2f936352014-08-05 14:04:04 +10007373#endif
7374
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007375
Guido van Rossumad0ee831995-03-01 10:34:45 +00007376#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007377/*[clinic input]
7378os.wait
7379
7380Wait for completion of a child process.
7381
7382Returns a tuple of information about the child process:
7383 (pid, status)
7384[clinic start generated code]*/
7385
Larry Hastings2f936352014-08-05 14:04:04 +10007386static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007387os_wait_impl(PyObject *module)
7388/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007389{
Victor Stinner8c62be82010-05-06 00:08:46 +00007390 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007391 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007392 WAIT_TYPE status;
7393 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007394
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007395 do {
7396 Py_BEGIN_ALLOW_THREADS
7397 pid = wait(&status);
7398 Py_END_ALLOW_THREADS
7399 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7400 if (pid < 0)
7401 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007402
Victor Stinner8c62be82010-05-06 00:08:46 +00007403 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007404}
Larry Hastings2f936352014-08-05 14:04:04 +10007405#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007407
Larry Hastings9cf065c2012-06-22 16:30:09 -07007408#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7409PyDoc_STRVAR(readlink__doc__,
7410"readlink(path, *, dir_fd=None) -> path\n\n\
7411Return a string representing the path to which the symbolic link points.\n\
7412\n\
7413If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7414 and path should be relative; path will then be relative to that directory.\n\
7415dir_fd may not be implemented on your platform.\n\
7416 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007417#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007418
Guido van Rossumb6775db1994-08-01 11:34:53 +00007419#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007420
Larry Hastings2f936352014-08-05 14:04:04 +10007421/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007422static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007423posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007424{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007425 path_t path;
7426 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007427 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007428 ssize_t length;
7429 PyObject *return_value = NULL;
7430 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007431
Larry Hastings9cf065c2012-06-22 16:30:09 -07007432 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007433 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007434 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7435 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007436 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007437 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007438
Victor Stinner8c62be82010-05-06 00:08:46 +00007439 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007440#ifdef HAVE_READLINKAT
7441 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007442 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007443 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007444#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007445 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007446 Py_END_ALLOW_THREADS
7447
7448 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007449 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007450 goto exit;
7451 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007452 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007453
7454 if (PyUnicode_Check(path.object))
7455 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7456 else
7457 return_value = PyBytes_FromStringAndSize(buffer, length);
7458exit:
7459 path_cleanup(&path);
7460 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007461}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007462
Guido van Rossumb6775db1994-08-01 11:34:53 +00007463#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007464
Larry Hastings2f936352014-08-05 14:04:04 +10007465#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7466
7467static PyObject *
7468win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7469{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007470 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007471 DWORD n_bytes_returned;
7472 DWORD io_result;
7473 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007474 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007475 HANDLE reparse_point_handle;
7476
Martin Panter70214ad2016-08-04 02:38:59 +00007477 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7478 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007479 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007480
7481 static char *keywords[] = {"path", "dir_fd", NULL};
7482
7483 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7484 &po,
7485 dir_fd_unavailable, &dir_fd
7486 ))
7487 return NULL;
7488
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007489 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007490 if (path == NULL)
7491 return NULL;
7492
7493 /* First get a handle to the reparse point */
7494 Py_BEGIN_ALLOW_THREADS
7495 reparse_point_handle = CreateFileW(
7496 path,
7497 0,
7498 0,
7499 0,
7500 OPEN_EXISTING,
7501 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7502 0);
7503 Py_END_ALLOW_THREADS
7504
7505 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7506 return win32_error_object("readlink", po);
7507
7508 Py_BEGIN_ALLOW_THREADS
7509 /* New call DeviceIoControl to read the reparse point */
7510 io_result = DeviceIoControl(
7511 reparse_point_handle,
7512 FSCTL_GET_REPARSE_POINT,
7513 0, 0, /* in buffer */
7514 target_buffer, sizeof(target_buffer),
7515 &n_bytes_returned,
7516 0 /* we're not using OVERLAPPED_IO */
7517 );
7518 CloseHandle(reparse_point_handle);
7519 Py_END_ALLOW_THREADS
7520
7521 if (io_result==0)
7522 return win32_error_object("readlink", po);
7523
7524 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7525 {
7526 PyErr_SetString(PyExc_ValueError,
7527 "not a symbolic link");
7528 return NULL;
7529 }
SSE43c34aad2018-02-13 00:10:35 +07007530 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7531 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007532
7533 result = PyUnicode_FromWideChar(print_name,
SSE43c34aad2018-02-13 00:10:35 +07007534 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
Larry Hastings2f936352014-08-05 14:04:04 +10007535 return result;
7536}
7537
7538#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7539
7540
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007541
Larry Hastings9cf065c2012-06-22 16:30:09 -07007542#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007543
7544#if defined(MS_WINDOWS)
7545
7546/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Steve Dower6921e732018-03-05 14:26:08 -08007547static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007548
Larry Hastings9cf065c2012-06-22 16:30:09 -07007549static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007550check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007551{
7552 HINSTANCE hKernel32;
7553 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007554 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007555 return 1;
7556 hKernel32 = GetModuleHandleW(L"KERNEL32");
7557 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7558 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007559 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007560}
7561
Steve Dower6921e732018-03-05 14:26:08 -08007562/* Remove the last portion of the path - return 0 on success */
7563static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007564_dirnameW(WCHAR *path)
7565{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007566 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007567 size_t length = wcsnlen_s(path, MAX_PATH);
7568 if (length == MAX_PATH) {
7569 return -1;
7570 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007571
7572 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007573 for(ptr = path + length; ptr != path; ptr--) {
7574 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007575 break;
Steve Dower6921e732018-03-05 14:26:08 -08007576 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007577 }
7578 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007579 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007580}
7581
Victor Stinner31b3b922013-06-05 01:49:17 +02007582/* Is this path absolute? */
7583static int
7584_is_absW(const WCHAR *path)
7585{
Steve Dower6921e732018-03-05 14:26:08 -08007586 return path[0] == L'\\' || path[0] == L'/' ||
7587 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007588}
7589
Steve Dower6921e732018-03-05 14:26:08 -08007590/* join root and rest with a backslash - return 0 on success */
7591static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007592_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7593{
Victor Stinner31b3b922013-06-05 01:49:17 +02007594 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007595 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007596 }
7597
Steve Dower6921e732018-03-05 14:26:08 -08007598 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7599 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007600 }
Steve Dower6921e732018-03-05 14:26:08 -08007601
7602 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7603 return -1;
7604 }
7605
7606 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007607}
7608
Victor Stinner31b3b922013-06-05 01:49:17 +02007609/* Return True if the path at src relative to dest is a directory */
7610static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007611_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007612{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007613 WIN32_FILE_ATTRIBUTE_DATA src_info;
7614 WCHAR dest_parent[MAX_PATH];
7615 WCHAR src_resolved[MAX_PATH] = L"";
7616
7617 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007618 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7619 _dirnameW(dest_parent)) {
7620 return 0;
7621 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007622 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007623 if (_joinW(src_resolved, dest_parent, src)) {
7624 return 0;
7625 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007626 return (
7627 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7628 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7629 );
7630}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007631#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007632
Larry Hastings2f936352014-08-05 14:04:04 +10007633
7634/*[clinic input]
7635os.symlink
7636 src: path_t
7637 dst: path_t
7638 target_is_directory: bool = False
7639 *
7640 dir_fd: dir_fd(requires='symlinkat')=None
7641
7642# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7643
7644Create a symbolic link pointing to src named dst.
7645
7646target_is_directory is required on Windows if the target is to be
7647 interpreted as a directory. (On Windows, symlink requires
7648 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7649 target_is_directory is ignored on non-Windows platforms.
7650
7651If dir_fd is not None, it should be a file descriptor open to a directory,
7652 and path should be relative; path will then be relative to that directory.
7653dir_fd may not be implemented on your platform.
7654 If it is unavailable, using it will raise a NotImplementedError.
7655
7656[clinic start generated code]*/
7657
Larry Hastings2f936352014-08-05 14:04:04 +10007658static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007659os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007660 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007661/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007662{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007663#ifdef MS_WINDOWS
7664 DWORD result;
7665#else
7666 int result;
7667#endif
7668
Larry Hastings9cf065c2012-06-22 16:30:09 -07007669#ifdef MS_WINDOWS
7670 if (!check_CreateSymbolicLink()) {
7671 PyErr_SetString(PyExc_NotImplementedError,
7672 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007673 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007674 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007675 if (!win32_can_symlink) {
7676 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007677 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007678 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007679#endif
7680
Larry Hastings9cf065c2012-06-22 16:30:09 -07007681#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007682
Larry Hastings9cf065c2012-06-22 16:30:09 -07007683 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007684 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007685 /* if src is a directory, ensure target_is_directory==1 */
7686 target_is_directory |= _check_dirW(src->wide, dst->wide);
7687 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7688 target_is_directory);
Steve Dower6921e732018-03-05 14:26:08 -08007689 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007690 Py_END_ALLOW_THREADS
7691
Larry Hastings2f936352014-08-05 14:04:04 +10007692 if (!result)
7693 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007694
7695#else
7696
Steve Dower6921e732018-03-05 14:26:08 -08007697 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7698 PyErr_SetString(PyExc_ValueError,
7699 "symlink: src and dst must be the same type");
7700 return NULL;
7701 }
7702
Larry Hastings9cf065c2012-06-22 16:30:09 -07007703 Py_BEGIN_ALLOW_THREADS
7704#if HAVE_SYMLINKAT
7705 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007706 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007707 else
7708#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007709 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007710 Py_END_ALLOW_THREADS
7711
Larry Hastings2f936352014-08-05 14:04:04 +10007712 if (result)
7713 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007714#endif
7715
Larry Hastings2f936352014-08-05 14:04:04 +10007716 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007717}
7718#endif /* HAVE_SYMLINK */
7719
Larry Hastings9cf065c2012-06-22 16:30:09 -07007720
Brian Curtind40e6f72010-07-08 21:39:08 +00007721
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007722
Larry Hastings605a62d2012-06-24 04:33:36 -07007723static PyStructSequence_Field times_result_fields[] = {
7724 {"user", "user time"},
7725 {"system", "system time"},
7726 {"children_user", "user time of children"},
7727 {"children_system", "system time of children"},
7728 {"elapsed", "elapsed time since an arbitrary point in the past"},
7729 {NULL}
7730};
7731
7732PyDoc_STRVAR(times_result__doc__,
7733"times_result: Result from os.times().\n\n\
7734This object may be accessed either as a tuple of\n\
7735 (user, system, children_user, children_system, elapsed),\n\
7736or via the attributes user, system, children_user, children_system,\n\
7737and elapsed.\n\
7738\n\
7739See os.times for more information.");
7740
7741static PyStructSequence_Desc times_result_desc = {
7742 "times_result", /* name */
7743 times_result__doc__, /* doc */
7744 times_result_fields,
7745 5
7746};
7747
7748static PyTypeObject TimesResultType;
7749
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007750#ifdef MS_WINDOWS
7751#define HAVE_TIMES /* mandatory, for the method table */
7752#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007753
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007754#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007755
7756static PyObject *
7757build_times_result(double user, double system,
7758 double children_user, double children_system,
7759 double elapsed)
7760{
7761 PyObject *value = PyStructSequence_New(&TimesResultType);
7762 if (value == NULL)
7763 return NULL;
7764
7765#define SET(i, field) \
7766 { \
7767 PyObject *o = PyFloat_FromDouble(field); \
7768 if (!o) { \
7769 Py_DECREF(value); \
7770 return NULL; \
7771 } \
7772 PyStructSequence_SET_ITEM(value, i, o); \
7773 } \
7774
7775 SET(0, user);
7776 SET(1, system);
7777 SET(2, children_user);
7778 SET(3, children_system);
7779 SET(4, elapsed);
7780
7781#undef SET
7782
7783 return value;
7784}
7785
Larry Hastings605a62d2012-06-24 04:33:36 -07007786
Larry Hastings2f936352014-08-05 14:04:04 +10007787#ifndef MS_WINDOWS
7788#define NEED_TICKS_PER_SECOND
7789static long ticks_per_second = -1;
7790#endif /* MS_WINDOWS */
7791
7792/*[clinic input]
7793os.times
7794
7795Return a collection containing process timing information.
7796
7797The object returned behaves like a named tuple with these fields:
7798 (utime, stime, cutime, cstime, elapsed_time)
7799All fields are floating point numbers.
7800[clinic start generated code]*/
7801
Larry Hastings2f936352014-08-05 14:04:04 +10007802static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007803os_times_impl(PyObject *module)
7804/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007805#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007806{
Victor Stinner8c62be82010-05-06 00:08:46 +00007807 FILETIME create, exit, kernel, user;
7808 HANDLE hProc;
7809 hProc = GetCurrentProcess();
7810 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7811 /* The fields of a FILETIME structure are the hi and lo part
7812 of a 64-bit value expressed in 100 nanosecond units.
7813 1e7 is one second in such units; 1e-7 the inverse.
7814 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7815 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007816 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007817 (double)(user.dwHighDateTime*429.4967296 +
7818 user.dwLowDateTime*1e-7),
7819 (double)(kernel.dwHighDateTime*429.4967296 +
7820 kernel.dwLowDateTime*1e-7),
7821 (double)0,
7822 (double)0,
7823 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007824}
Larry Hastings2f936352014-08-05 14:04:04 +10007825#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007826{
Larry Hastings2f936352014-08-05 14:04:04 +10007827
7828
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007829 struct tms t;
7830 clock_t c;
7831 errno = 0;
7832 c = times(&t);
7833 if (c == (clock_t) -1)
7834 return posix_error();
7835 return build_times_result(
7836 (double)t.tms_utime / ticks_per_second,
7837 (double)t.tms_stime / ticks_per_second,
7838 (double)t.tms_cutime / ticks_per_second,
7839 (double)t.tms_cstime / ticks_per_second,
7840 (double)c / ticks_per_second);
7841}
Larry Hastings2f936352014-08-05 14:04:04 +10007842#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007843#endif /* HAVE_TIMES */
7844
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007845
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007846#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007847/*[clinic input]
7848os.getsid
7849
7850 pid: pid_t
7851 /
7852
7853Call the system call getsid(pid) and return the result.
7854[clinic start generated code]*/
7855
Larry Hastings2f936352014-08-05 14:04:04 +10007856static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007857os_getsid_impl(PyObject *module, pid_t pid)
7858/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007859{
Victor Stinner8c62be82010-05-06 00:08:46 +00007860 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007861 sid = getsid(pid);
7862 if (sid < 0)
7863 return posix_error();
7864 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007865}
7866#endif /* HAVE_GETSID */
7867
7868
Guido van Rossumb6775db1994-08-01 11:34:53 +00007869#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007870/*[clinic input]
7871os.setsid
7872
7873Call the system call setsid().
7874[clinic start generated code]*/
7875
Larry Hastings2f936352014-08-05 14:04:04 +10007876static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007877os_setsid_impl(PyObject *module)
7878/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007879{
Victor Stinner8c62be82010-05-06 00:08:46 +00007880 if (setsid() < 0)
7881 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007882 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007883}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007884#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007885
Larry Hastings2f936352014-08-05 14:04:04 +10007886
Guido van Rossumb6775db1994-08-01 11:34:53 +00007887#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007888/*[clinic input]
7889os.setpgid
7890
7891 pid: pid_t
7892 pgrp: pid_t
7893 /
7894
7895Call the system call setpgid(pid, pgrp).
7896[clinic start generated code]*/
7897
Larry Hastings2f936352014-08-05 14:04:04 +10007898static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007899os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7900/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007901{
Victor Stinner8c62be82010-05-06 00:08:46 +00007902 if (setpgid(pid, pgrp) < 0)
7903 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007904 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007905}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007906#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007908
Guido van Rossumb6775db1994-08-01 11:34:53 +00007909#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007910/*[clinic input]
7911os.tcgetpgrp
7912
7913 fd: int
7914 /
7915
7916Return the process group associated with the terminal specified by fd.
7917[clinic start generated code]*/
7918
Larry Hastings2f936352014-08-05 14:04:04 +10007919static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007920os_tcgetpgrp_impl(PyObject *module, int fd)
7921/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007922{
7923 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 if (pgid < 0)
7925 return posix_error();
7926 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007927}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007928#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007929
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007930
Guido van Rossumb6775db1994-08-01 11:34:53 +00007931#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007932/*[clinic input]
7933os.tcsetpgrp
7934
7935 fd: int
7936 pgid: pid_t
7937 /
7938
7939Set the process group associated with the terminal specified by fd.
7940[clinic start generated code]*/
7941
Larry Hastings2f936352014-08-05 14:04:04 +10007942static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007943os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7944/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007945{
Victor Stinner8c62be82010-05-06 00:08:46 +00007946 if (tcsetpgrp(fd, pgid) < 0)
7947 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007948 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007949}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007950#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007951
Guido van Rossum687dd131993-05-17 08:34:16 +00007952/* Functions acting on file descriptors */
7953
Victor Stinnerdaf45552013-08-28 00:53:59 +02007954#ifdef O_CLOEXEC
7955extern int _Py_open_cloexec_works;
7956#endif
7957
Larry Hastings2f936352014-08-05 14:04:04 +10007958
7959/*[clinic input]
7960os.open -> int
7961 path: path_t
7962 flags: int
7963 mode: int = 0o777
7964 *
7965 dir_fd: dir_fd(requires='openat') = None
7966
7967# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7968
7969Open a file for low level IO. Returns a file descriptor (integer).
7970
7971If dir_fd is not None, it should be a file descriptor open to a directory,
7972 and path should be relative; path will then be relative to that directory.
7973dir_fd may not be implemented on your platform.
7974 If it is unavailable, using it will raise a NotImplementedError.
7975[clinic start generated code]*/
7976
Larry Hastings2f936352014-08-05 14:04:04 +10007977static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007978os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7979/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007980{
7981 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007982 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007983
Victor Stinnerdaf45552013-08-28 00:53:59 +02007984#ifdef O_CLOEXEC
7985 int *atomic_flag_works = &_Py_open_cloexec_works;
7986#elif !defined(MS_WINDOWS)
7987 int *atomic_flag_works = NULL;
7988#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007989
Victor Stinnerdaf45552013-08-28 00:53:59 +02007990#ifdef MS_WINDOWS
7991 flags |= O_NOINHERIT;
7992#elif defined(O_CLOEXEC)
7993 flags |= O_CLOEXEC;
7994#endif
7995
Steve Dower8fc89802015-04-12 00:26:27 -04007996 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007997 do {
7998 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007999#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008000 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008001#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008002#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008003 if (dir_fd != DEFAULT_DIR_FD)
8004 fd = openat(dir_fd, path->narrow, flags, mode);
8005 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008006#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008007 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008008#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008009 Py_END_ALLOW_THREADS
8010 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008011 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008012
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008013 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008014 if (!async_err)
8015 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008016 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008017 }
8018
Victor Stinnerdaf45552013-08-28 00:53:59 +02008019#ifndef MS_WINDOWS
8020 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8021 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008022 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008023 }
8024#endif
8025
Larry Hastings2f936352014-08-05 14:04:04 +10008026 return fd;
8027}
8028
8029
8030/*[clinic input]
8031os.close
8032
8033 fd: int
8034
8035Close a file descriptor.
8036[clinic start generated code]*/
8037
Barry Warsaw53699e91996-12-10 23:23:01 +00008038static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008039os_close_impl(PyObject *module, int fd)
8040/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008041{
Larry Hastings2f936352014-08-05 14:04:04 +10008042 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008043 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8044 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8045 * for more details.
8046 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008047 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008048 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008049 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008050 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008051 Py_END_ALLOW_THREADS
8052 if (res < 0)
8053 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008054 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008055}
8056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008057
Larry Hastings2f936352014-08-05 14:04:04 +10008058/*[clinic input]
8059os.closerange
8060
8061 fd_low: int
8062 fd_high: int
8063 /
8064
8065Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8066[clinic start generated code]*/
8067
Larry Hastings2f936352014-08-05 14:04:04 +10008068static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008069os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8070/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008071{
8072 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008073 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008074 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008075 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008076 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008077 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008078 Py_END_ALLOW_THREADS
8079 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008080}
8081
8082
Larry Hastings2f936352014-08-05 14:04:04 +10008083/*[clinic input]
8084os.dup -> int
8085
8086 fd: int
8087 /
8088
8089Return a duplicate of a file descriptor.
8090[clinic start generated code]*/
8091
Larry Hastings2f936352014-08-05 14:04:04 +10008092static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008093os_dup_impl(PyObject *module, int fd)
8094/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008095{
8096 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008097}
8098
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008099
Larry Hastings2f936352014-08-05 14:04:04 +10008100/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008101os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008102 fd: int
8103 fd2: int
8104 inheritable: bool=True
8105
8106Duplicate file descriptor.
8107[clinic start generated code]*/
8108
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008109static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008110os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008111/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008112{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008113 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008114#if defined(HAVE_DUP3) && \
8115 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8116 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008117 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008118#endif
8119
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008120 if (fd < 0 || fd2 < 0) {
8121 posix_error();
8122 return -1;
8123 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008124
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008125 /* dup2() can fail with EINTR if the target FD is already open, because it
8126 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8127 * upon close(), and therefore below.
8128 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008129#ifdef MS_WINDOWS
8130 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008131 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008132 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008133 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008134 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008135 if (res < 0) {
8136 posix_error();
8137 return -1;
8138 }
8139 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008140
8141 /* Character files like console cannot be make non-inheritable */
8142 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8143 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008144 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008145 }
8146
8147#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8148 Py_BEGIN_ALLOW_THREADS
8149 if (!inheritable)
8150 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8151 else
8152 res = dup2(fd, fd2);
8153 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008154 if (res < 0) {
8155 posix_error();
8156 return -1;
8157 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008158
8159#else
8160
8161#ifdef HAVE_DUP3
8162 if (!inheritable && dup3_works != 0) {
8163 Py_BEGIN_ALLOW_THREADS
8164 res = dup3(fd, fd2, O_CLOEXEC);
8165 Py_END_ALLOW_THREADS
8166 if (res < 0) {
8167 if (dup3_works == -1)
8168 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008169 if (dup3_works) {
8170 posix_error();
8171 return -1;
8172 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008173 }
8174 }
8175
8176 if (inheritable || dup3_works == 0)
8177 {
8178#endif
8179 Py_BEGIN_ALLOW_THREADS
8180 res = dup2(fd, fd2);
8181 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008182 if (res < 0) {
8183 posix_error();
8184 return -1;
8185 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008186
8187 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8188 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008189 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008190 }
8191#ifdef HAVE_DUP3
8192 }
8193#endif
8194
8195#endif
8196
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008197 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008198}
8199
Larry Hastings2f936352014-08-05 14:04:04 +10008200
Ross Lagerwall7807c352011-03-17 20:20:30 +02008201#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008202/*[clinic input]
8203os.lockf
8204
8205 fd: int
8206 An open file descriptor.
8207 command: int
8208 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8209 length: Py_off_t
8210 The number of bytes to lock, starting at the current position.
8211 /
8212
8213Apply, test or remove a POSIX lock on an open file descriptor.
8214
8215[clinic start generated code]*/
8216
Larry Hastings2f936352014-08-05 14:04:04 +10008217static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008218os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8219/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008220{
8221 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008222
8223 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008224 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008225 Py_END_ALLOW_THREADS
8226
8227 if (res < 0)
8228 return posix_error();
8229
8230 Py_RETURN_NONE;
8231}
Larry Hastings2f936352014-08-05 14:04:04 +10008232#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008233
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008234
Larry Hastings2f936352014-08-05 14:04:04 +10008235/*[clinic input]
8236os.lseek -> Py_off_t
8237
8238 fd: int
8239 position: Py_off_t
8240 how: int
8241 /
8242
8243Set the position of a file descriptor. Return the new position.
8244
8245Return the new cursor position in number of bytes
8246relative to the beginning of the file.
8247[clinic start generated code]*/
8248
Larry Hastings2f936352014-08-05 14:04:04 +10008249static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008250os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8251/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008252{
8253 Py_off_t result;
8254
Guido van Rossum687dd131993-05-17 08:34:16 +00008255#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008256 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8257 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008258 case 0: how = SEEK_SET; break;
8259 case 1: how = SEEK_CUR; break;
8260 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008261 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008262#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008263
Victor Stinner8c62be82010-05-06 00:08:46 +00008264 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008265 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008266#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008267 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008268#else
Larry Hastings2f936352014-08-05 14:04:04 +10008269 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008270#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008271 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008272 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008273 if (result < 0)
8274 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008275
Larry Hastings2f936352014-08-05 14:04:04 +10008276 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008277}
8278
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008279
Larry Hastings2f936352014-08-05 14:04:04 +10008280/*[clinic input]
8281os.read
8282 fd: int
8283 length: Py_ssize_t
8284 /
8285
8286Read from a file descriptor. Returns a bytes object.
8287[clinic start generated code]*/
8288
Larry Hastings2f936352014-08-05 14:04:04 +10008289static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008290os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8291/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008292{
Victor Stinner8c62be82010-05-06 00:08:46 +00008293 Py_ssize_t n;
8294 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008295
8296 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008297 errno = EINVAL;
8298 return posix_error();
8299 }
Larry Hastings2f936352014-08-05 14:04:04 +10008300
8301#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008302 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008303 if (length > INT_MAX)
8304 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008305#endif
8306
8307 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008308 if (buffer == NULL)
8309 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008310
Victor Stinner66aab0c2015-03-19 22:53:20 +01008311 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8312 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008313 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008314 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008315 }
Larry Hastings2f936352014-08-05 14:04:04 +10008316
8317 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008318 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008319
Victor Stinner8c62be82010-05-06 00:08:46 +00008320 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008321}
8322
Ross Lagerwall7807c352011-03-17 20:20:30 +02008323#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8324 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008325static Py_ssize_t
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008326iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008327{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008328 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008329 Py_ssize_t blen, total = 0;
8330
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008331 *iov = PyMem_New(struct iovec, cnt);
8332 if (*iov == NULL) {
8333 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008334 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008335 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008336
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008337 *buf = PyMem_New(Py_buffer, cnt);
8338 if (*buf == NULL) {
8339 PyMem_Del(*iov);
8340 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008341 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008342 }
8343
8344 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008345 PyObject *item = PySequence_GetItem(seq, i);
8346 if (item == NULL)
8347 goto fail;
8348 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8349 Py_DECREF(item);
8350 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008351 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008352 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008353 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008354 blen = (*buf)[i].len;
8355 (*iov)[i].iov_len = blen;
8356 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008357 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008358 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008359
8360fail:
8361 PyMem_Del(*iov);
8362 for (j = 0; j < i; j++) {
8363 PyBuffer_Release(&(*buf)[j]);
8364 }
8365 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008366 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008367}
8368
8369static void
8370iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8371{
8372 int i;
8373 PyMem_Del(iov);
8374 for (i = 0; i < cnt; i++) {
8375 PyBuffer_Release(&buf[i]);
8376 }
8377 PyMem_Del(buf);
8378}
8379#endif
8380
Larry Hastings2f936352014-08-05 14:04:04 +10008381
Ross Lagerwall7807c352011-03-17 20:20:30 +02008382#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008383/*[clinic input]
8384os.readv -> Py_ssize_t
8385
8386 fd: int
8387 buffers: object
8388 /
8389
8390Read from a file descriptor fd into an iterable of buffers.
8391
8392The buffers should be mutable buffers accepting bytes.
8393readv will transfer data into each buffer until it is full
8394and then move on to the next buffer in the sequence to hold
8395the rest of the data.
8396
8397readv returns the total number of bytes read,
8398which may be less than the total capacity of all the buffers.
8399[clinic start generated code]*/
8400
Larry Hastings2f936352014-08-05 14:04:04 +10008401static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008402os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8403/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008404{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008405 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008406 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008407 struct iovec *iov;
8408 Py_buffer *buf;
8409
Larry Hastings2f936352014-08-05 14:04:04 +10008410 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008411 PyErr_SetString(PyExc_TypeError,
8412 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008413 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008414 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008415
Larry Hastings2f936352014-08-05 14:04:04 +10008416 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008417 if (cnt < 0)
8418 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008419
8420 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8421 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008422
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008423 do {
8424 Py_BEGIN_ALLOW_THREADS
8425 n = readv(fd, iov, cnt);
8426 Py_END_ALLOW_THREADS
8427 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008428
8429 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008430 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008431 if (!async_err)
8432 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008433 return -1;
8434 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008435
Larry Hastings2f936352014-08-05 14:04:04 +10008436 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008437}
Larry Hastings2f936352014-08-05 14:04:04 +10008438#endif /* HAVE_READV */
8439
Ross Lagerwall7807c352011-03-17 20:20:30 +02008440
8441#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008442/*[clinic input]
8443# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8444os.pread
8445
8446 fd: int
8447 length: int
8448 offset: Py_off_t
8449 /
8450
8451Read a number of bytes from a file descriptor starting at a particular offset.
8452
8453Read length bytes from file descriptor fd, starting at offset bytes from
8454the beginning of the file. The file offset remains unchanged.
8455[clinic start generated code]*/
8456
Larry Hastings2f936352014-08-05 14:04:04 +10008457static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008458os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8459/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008460{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008461 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008462 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008463 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008464
Larry Hastings2f936352014-08-05 14:04:04 +10008465 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008466 errno = EINVAL;
8467 return posix_error();
8468 }
Larry Hastings2f936352014-08-05 14:04:04 +10008469 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008470 if (buffer == NULL)
8471 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008472
8473 do {
8474 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008475 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008476 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008477 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008478 Py_END_ALLOW_THREADS
8479 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8480
Ross Lagerwall7807c352011-03-17 20:20:30 +02008481 if (n < 0) {
8482 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008483 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008484 }
Larry Hastings2f936352014-08-05 14:04:04 +10008485 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008486 _PyBytes_Resize(&buffer, n);
8487 return buffer;
8488}
Larry Hastings2f936352014-08-05 14:04:04 +10008489#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008490
Pablo Galindo4defba32018-01-27 16:16:37 +00008491#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8492/*[clinic input]
8493os.preadv -> Py_ssize_t
8494
8495 fd: int
8496 buffers: object
8497 offset: Py_off_t
8498 flags: int = 0
8499 /
8500
8501Reads from a file descriptor into a number of mutable bytes-like objects.
8502
8503Combines the functionality of readv() and pread(). As readv(), it will
8504transfer data into each buffer until it is full and then move on to the next
8505buffer in the sequence to hold the rest of the data. Its fourth argument,
8506specifies the file offset at which the input operation is to be performed. It
8507will return the total number of bytes read (which can be less than the total
8508capacity of all the objects).
8509
8510The flags argument contains a bitwise OR of zero or more of the following flags:
8511
8512- RWF_HIPRI
8513- RWF_NOWAIT
8514
8515Using non-zero flags requires Linux 4.6 or newer.
8516[clinic start generated code]*/
8517
8518static Py_ssize_t
8519os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8520 int flags)
8521/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8522{
8523 Py_ssize_t cnt, n;
8524 int async_err = 0;
8525 struct iovec *iov;
8526 Py_buffer *buf;
8527
8528 if (!PySequence_Check(buffers)) {
8529 PyErr_SetString(PyExc_TypeError,
8530 "preadv2() arg 2 must be a sequence");
8531 return -1;
8532 }
8533
8534 cnt = PySequence_Size(buffers);
8535 if (cnt < 0) {
8536 return -1;
8537 }
8538
8539#ifndef HAVE_PREADV2
8540 if(flags != 0) {
8541 argument_unavailable_error("preadv2", "flags");
8542 return -1;
8543 }
8544#endif
8545
8546 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8547 return -1;
8548 }
8549#ifdef HAVE_PREADV2
8550 do {
8551 Py_BEGIN_ALLOW_THREADS
8552 _Py_BEGIN_SUPPRESS_IPH
8553 n = preadv2(fd, iov, cnt, offset, flags);
8554 _Py_END_SUPPRESS_IPH
8555 Py_END_ALLOW_THREADS
8556 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8557#else
8558 do {
8559 Py_BEGIN_ALLOW_THREADS
8560 _Py_BEGIN_SUPPRESS_IPH
8561 n = preadv(fd, iov, cnt, offset);
8562 _Py_END_SUPPRESS_IPH
8563 Py_END_ALLOW_THREADS
8564 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8565#endif
8566
8567 iov_cleanup(iov, buf, cnt);
8568 if (n < 0) {
8569 if (!async_err) {
8570 posix_error();
8571 }
8572 return -1;
8573 }
8574
8575 return n;
8576}
8577#endif /* HAVE_PREADV */
8578
Larry Hastings2f936352014-08-05 14:04:04 +10008579
8580/*[clinic input]
8581os.write -> Py_ssize_t
8582
8583 fd: int
8584 data: Py_buffer
8585 /
8586
8587Write a bytes object to a file descriptor.
8588[clinic start generated code]*/
8589
Larry Hastings2f936352014-08-05 14:04:04 +10008590static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008591os_write_impl(PyObject *module, int fd, Py_buffer *data)
8592/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008593{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008594 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008595}
8596
8597#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008598PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008599"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008600sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008601 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008602Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008603
Larry Hastings2f936352014-08-05 14:04:04 +10008604/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008605static PyObject *
8606posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8607{
8608 int in, out;
8609 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008610 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008611 off_t offset;
8612
8613#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8614#ifndef __APPLE__
8615 Py_ssize_t len;
8616#endif
8617 PyObject *headers = NULL, *trailers = NULL;
8618 Py_buffer *hbuf, *tbuf;
8619 off_t sbytes;
8620 struct sf_hdtr sf;
8621 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008622 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008623 static char *keywords[] = {"out", "in",
8624 "offset", "count",
8625 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008626
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008627 sf.headers = NULL;
8628 sf.trailers = NULL;
8629
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008630#ifdef __APPLE__
8631 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008632 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008633#else
8634 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008635 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008636#endif
8637 &headers, &trailers, &flags))
8638 return NULL;
8639 if (headers != NULL) {
8640 if (!PySequence_Check(headers)) {
8641 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008642 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008643 return NULL;
8644 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008645 Py_ssize_t i = PySequence_Size(headers);
8646 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008647 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008648 if (i > INT_MAX) {
8649 PyErr_SetString(PyExc_OverflowError,
8650 "sendfile() header is too large");
8651 return NULL;
8652 }
8653 if (i > 0) {
8654 sf.hdr_cnt = (int)i;
8655 i = iov_setup(&(sf.headers), &hbuf,
8656 headers, sf.hdr_cnt, PyBUF_SIMPLE);
8657 if (i < 0)
8658 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008659#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008660 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008661#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008662 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008663 }
8664 }
8665 if (trailers != NULL) {
8666 if (!PySequence_Check(trailers)) {
8667 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008668 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008669 return NULL;
8670 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008671 Py_ssize_t i = PySequence_Size(trailers);
8672 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008673 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008674 if (i > INT_MAX) {
8675 PyErr_SetString(PyExc_OverflowError,
8676 "sendfile() trailer is too large");
8677 return NULL;
8678 }
8679 if (i > 0) {
8680 sf.trl_cnt = (int)i;
8681 i = iov_setup(&(sf.trailers), &tbuf,
8682 trailers, sf.trl_cnt, PyBUF_SIMPLE);
8683 if (i < 0)
8684 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008685#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008686 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008687#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008688 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008689 }
8690 }
8691
Steve Dower8fc89802015-04-12 00:26:27 -04008692 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008693 do {
8694 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008695#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008696 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008697#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008698 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008699#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008700 Py_END_ALLOW_THREADS
8701 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008702 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008703
8704 if (sf.headers != NULL)
8705 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8706 if (sf.trailers != NULL)
8707 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8708
8709 if (ret < 0) {
8710 if ((errno == EAGAIN) || (errno == EBUSY)) {
8711 if (sbytes != 0) {
8712 // some data has been sent
8713 goto done;
8714 }
8715 else {
8716 // no data has been sent; upper application is supposed
8717 // to retry on EAGAIN or EBUSY
8718 return posix_error();
8719 }
8720 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008721 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008722 }
8723 goto done;
8724
8725done:
8726 #if !defined(HAVE_LARGEFILE_SUPPORT)
8727 return Py_BuildValue("l", sbytes);
8728 #else
8729 return Py_BuildValue("L", sbytes);
8730 #endif
8731
8732#else
8733 Py_ssize_t count;
8734 PyObject *offobj;
8735 static char *keywords[] = {"out", "in",
8736 "offset", "count", NULL};
8737 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8738 keywords, &out, &in, &offobj, &count))
8739 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008740#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008741 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008742 do {
8743 Py_BEGIN_ALLOW_THREADS
8744 ret = sendfile(out, in, NULL, count);
8745 Py_END_ALLOW_THREADS
8746 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008747 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008748 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008749 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008750 }
8751#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008752 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008753 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008754
8755 do {
8756 Py_BEGIN_ALLOW_THREADS
8757 ret = sendfile(out, in, &offset, count);
8758 Py_END_ALLOW_THREADS
8759 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008760 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008761 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008762 return Py_BuildValue("n", ret);
8763#endif
8764}
Larry Hastings2f936352014-08-05 14:04:04 +10008765#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008766
Larry Hastings2f936352014-08-05 14:04:04 +10008767
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008768#if defined(__APPLE__)
8769/*[clinic input]
8770os._fcopyfile
8771
8772 infd: int
8773 outfd: int
8774 flags: int
8775 /
8776
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008777Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008778[clinic start generated code]*/
8779
8780static PyObject *
8781os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008782/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008783{
8784 int ret;
8785
8786 Py_BEGIN_ALLOW_THREADS
8787 ret = fcopyfile(infd, outfd, NULL, flags);
8788 Py_END_ALLOW_THREADS
8789 if (ret < 0)
8790 return posix_error();
8791 Py_RETURN_NONE;
8792}
8793#endif
8794
8795
Larry Hastings2f936352014-08-05 14:04:04 +10008796/*[clinic input]
8797os.fstat
8798
8799 fd : int
8800
8801Perform a stat system call on the given file descriptor.
8802
8803Like stat(), but for an open file descriptor.
8804Equivalent to os.stat(fd).
8805[clinic start generated code]*/
8806
Larry Hastings2f936352014-08-05 14:04:04 +10008807static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008808os_fstat_impl(PyObject *module, int fd)
8809/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008810{
Victor Stinner8c62be82010-05-06 00:08:46 +00008811 STRUCT_STAT st;
8812 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008813 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008814
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008815 do {
8816 Py_BEGIN_ALLOW_THREADS
8817 res = FSTAT(fd, &st);
8818 Py_END_ALLOW_THREADS
8819 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008820 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008821#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008822 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008823#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008824 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008825#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008826 }
Tim Peters5aa91602002-01-30 05:46:57 +00008827
Victor Stinner4195b5c2012-02-08 23:03:19 +01008828 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008829}
8830
Larry Hastings2f936352014-08-05 14:04:04 +10008831
8832/*[clinic input]
8833os.isatty -> bool
8834 fd: int
8835 /
8836
8837Return True if the fd is connected to a terminal.
8838
8839Return True if the file descriptor is an open file descriptor
8840connected to the slave end of a terminal.
8841[clinic start generated code]*/
8842
Larry Hastings2f936352014-08-05 14:04:04 +10008843static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008844os_isatty_impl(PyObject *module, int fd)
8845/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008846{
Steve Dower8fc89802015-04-12 00:26:27 -04008847 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008848 _Py_BEGIN_SUPPRESS_IPH
8849 return_value = isatty(fd);
8850 _Py_END_SUPPRESS_IPH
8851 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008852}
8853
8854
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008855#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008856/*[clinic input]
8857os.pipe
8858
8859Create a pipe.
8860
8861Returns a tuple of two file descriptors:
8862 (read_fd, write_fd)
8863[clinic start generated code]*/
8864
Larry Hastings2f936352014-08-05 14:04:04 +10008865static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008866os_pipe_impl(PyObject *module)
8867/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008868{
Victor Stinner8c62be82010-05-06 00:08:46 +00008869 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008870#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008871 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008872 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008873 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008874#else
8875 int res;
8876#endif
8877
8878#ifdef MS_WINDOWS
8879 attr.nLength = sizeof(attr);
8880 attr.lpSecurityDescriptor = NULL;
8881 attr.bInheritHandle = FALSE;
8882
8883 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008884 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008885 ok = CreatePipe(&read, &write, &attr, 0);
8886 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008887 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8888 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008889 if (fds[0] == -1 || fds[1] == -1) {
8890 CloseHandle(read);
8891 CloseHandle(write);
8892 ok = 0;
8893 }
8894 }
Steve Dowerc3630612016-11-19 18:41:16 -08008895 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008896 Py_END_ALLOW_THREADS
8897
Victor Stinner8c62be82010-05-06 00:08:46 +00008898 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008899 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008900#else
8901
8902#ifdef HAVE_PIPE2
8903 Py_BEGIN_ALLOW_THREADS
8904 res = pipe2(fds, O_CLOEXEC);
8905 Py_END_ALLOW_THREADS
8906
8907 if (res != 0 && errno == ENOSYS)
8908 {
8909#endif
8910 Py_BEGIN_ALLOW_THREADS
8911 res = pipe(fds);
8912 Py_END_ALLOW_THREADS
8913
8914 if (res == 0) {
8915 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8916 close(fds[0]);
8917 close(fds[1]);
8918 return NULL;
8919 }
8920 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8921 close(fds[0]);
8922 close(fds[1]);
8923 return NULL;
8924 }
8925 }
8926#ifdef HAVE_PIPE2
8927 }
8928#endif
8929
8930 if (res != 0)
8931 return PyErr_SetFromErrno(PyExc_OSError);
8932#endif /* !MS_WINDOWS */
8933 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008934}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008935#endif /* HAVE_PIPE */
8936
Larry Hastings2f936352014-08-05 14:04:04 +10008937
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008938#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008939/*[clinic input]
8940os.pipe2
8941
8942 flags: int
8943 /
8944
8945Create a pipe with flags set atomically.
8946
8947Returns a tuple of two file descriptors:
8948 (read_fd, write_fd)
8949
8950flags can be constructed by ORing together one or more of these values:
8951O_NONBLOCK, O_CLOEXEC.
8952[clinic start generated code]*/
8953
Larry Hastings2f936352014-08-05 14:04:04 +10008954static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008955os_pipe2_impl(PyObject *module, int flags)
8956/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008957{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008958 int fds[2];
8959 int res;
8960
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008961 res = pipe2(fds, flags);
8962 if (res != 0)
8963 return posix_error();
8964 return Py_BuildValue("(ii)", fds[0], fds[1]);
8965}
8966#endif /* HAVE_PIPE2 */
8967
Larry Hastings2f936352014-08-05 14:04:04 +10008968
Ross Lagerwall7807c352011-03-17 20:20:30 +02008969#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008970/*[clinic input]
8971os.writev -> Py_ssize_t
8972 fd: int
8973 buffers: object
8974 /
8975
8976Iterate over buffers, and write the contents of each to a file descriptor.
8977
8978Returns the total number of bytes written.
8979buffers must be a sequence of bytes-like objects.
8980[clinic start generated code]*/
8981
Larry Hastings2f936352014-08-05 14:04:04 +10008982static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008983os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8984/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008985{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008986 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008987 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008988 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008989 struct iovec *iov;
8990 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008991
8992 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008993 PyErr_SetString(PyExc_TypeError,
8994 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008995 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008996 }
Larry Hastings2f936352014-08-05 14:04:04 +10008997 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008998 if (cnt < 0)
8999 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009000
Larry Hastings2f936352014-08-05 14:04:04 +10009001 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9002 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009003 }
9004
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009005 do {
9006 Py_BEGIN_ALLOW_THREADS
9007 result = writev(fd, iov, cnt);
9008 Py_END_ALLOW_THREADS
9009 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009010
9011 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009012 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009013 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009014
Georg Brandl306336b2012-06-24 12:55:33 +02009015 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009016}
Larry Hastings2f936352014-08-05 14:04:04 +10009017#endif /* HAVE_WRITEV */
9018
9019
9020#ifdef HAVE_PWRITE
9021/*[clinic input]
9022os.pwrite -> Py_ssize_t
9023
9024 fd: int
9025 buffer: Py_buffer
9026 offset: Py_off_t
9027 /
9028
9029Write bytes to a file descriptor starting at a particular offset.
9030
9031Write buffer to fd, starting at offset bytes from the beginning of
9032the file. Returns the number of bytes writte. Does not change the
9033current file offset.
9034[clinic start generated code]*/
9035
Larry Hastings2f936352014-08-05 14:04:04 +10009036static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009037os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9038/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009039{
9040 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009041 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009042
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009043 do {
9044 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009045 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009046 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009047 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009048 Py_END_ALLOW_THREADS
9049 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009050
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009051 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009052 posix_error();
9053 return size;
9054}
9055#endif /* HAVE_PWRITE */
9056
Pablo Galindo4defba32018-01-27 16:16:37 +00009057#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9058/*[clinic input]
9059os.pwritev -> Py_ssize_t
9060
9061 fd: int
9062 buffers: object
9063 offset: Py_off_t
9064 flags: int = 0
9065 /
9066
9067Writes the contents of bytes-like objects to a file descriptor at a given offset.
9068
9069Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9070of bytes-like objects. Buffers are processed in array order. Entire contents of first
9071buffer is written before proceeding to second, and so on. The operating system may
9072set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9073This function writes the contents of each object to the file descriptor and returns
9074the total number of bytes written.
9075
9076The flags argument contains a bitwise OR of zero or more of the following flags:
9077
9078- RWF_DSYNC
9079- RWF_SYNC
9080
9081Using non-zero flags requires Linux 4.7 or newer.
9082[clinic start generated code]*/
9083
9084static Py_ssize_t
9085os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9086 int flags)
9087/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9088{
9089 Py_ssize_t cnt;
9090 Py_ssize_t result;
9091 int async_err = 0;
9092 struct iovec *iov;
9093 Py_buffer *buf;
9094
9095 if (!PySequence_Check(buffers)) {
9096 PyErr_SetString(PyExc_TypeError,
9097 "pwritev() arg 2 must be a sequence");
9098 return -1;
9099 }
9100
9101 cnt = PySequence_Size(buffers);
9102 if (cnt < 0) {
9103 return -1;
9104 }
9105
9106#ifndef HAVE_PWRITEV2
9107 if(flags != 0) {
9108 argument_unavailable_error("pwritev2", "flags");
9109 return -1;
9110 }
9111#endif
9112
9113 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9114 return -1;
9115 }
9116#ifdef HAVE_PWRITEV2
9117 do {
9118 Py_BEGIN_ALLOW_THREADS
9119 _Py_BEGIN_SUPPRESS_IPH
9120 result = pwritev2(fd, iov, cnt, offset, flags);
9121 _Py_END_SUPPRESS_IPH
9122 Py_END_ALLOW_THREADS
9123 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9124#else
9125 do {
9126 Py_BEGIN_ALLOW_THREADS
9127 _Py_BEGIN_SUPPRESS_IPH
9128 result = pwritev(fd, iov, cnt, offset);
9129 _Py_END_SUPPRESS_IPH
9130 Py_END_ALLOW_THREADS
9131 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9132#endif
9133
9134 iov_cleanup(iov, buf, cnt);
9135 if (result < 0) {
9136 if (!async_err) {
9137 posix_error();
9138 }
9139 return -1;
9140 }
9141
9142 return result;
9143}
9144#endif /* HAVE_PWRITEV */
9145
9146
9147
Larry Hastings2f936352014-08-05 14:04:04 +10009148
9149#ifdef HAVE_MKFIFO
9150/*[clinic input]
9151os.mkfifo
9152
9153 path: path_t
9154 mode: int=0o666
9155 *
9156 dir_fd: dir_fd(requires='mkfifoat')=None
9157
9158Create a "fifo" (a POSIX named pipe).
9159
9160If dir_fd is not None, it should be a file descriptor open to a directory,
9161 and path should be relative; path will then be relative to that directory.
9162dir_fd may not be implemented on your platform.
9163 If it is unavailable, using it will raise a NotImplementedError.
9164[clinic start generated code]*/
9165
Larry Hastings2f936352014-08-05 14:04:04 +10009166static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009167os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9168/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009169{
9170 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009171 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009172
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009173 do {
9174 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009175#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009176 if (dir_fd != DEFAULT_DIR_FD)
9177 result = mkfifoat(dir_fd, path->narrow, mode);
9178 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009179#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009180 result = mkfifo(path->narrow, mode);
9181 Py_END_ALLOW_THREADS
9182 } while (result != 0 && errno == EINTR &&
9183 !(async_err = PyErr_CheckSignals()));
9184 if (result != 0)
9185 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009186
9187 Py_RETURN_NONE;
9188}
9189#endif /* HAVE_MKFIFO */
9190
9191
9192#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9193/*[clinic input]
9194os.mknod
9195
9196 path: path_t
9197 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009198 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009199 *
9200 dir_fd: dir_fd(requires='mknodat')=None
9201
9202Create a node in the file system.
9203
9204Create a node in the file system (file, device special file or named pipe)
9205at path. mode specifies both the permissions to use and the
9206type of node to be created, being combined (bitwise OR) with one of
9207S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9208device defines the newly created device special file (probably using
9209os.makedev()). Otherwise device is ignored.
9210
9211If dir_fd is not None, it should be a file descriptor open to a directory,
9212 and path should be relative; path will then be relative to that directory.
9213dir_fd may not be implemented on your platform.
9214 If it is unavailable, using it will raise a NotImplementedError.
9215[clinic start generated code]*/
9216
Larry Hastings2f936352014-08-05 14:04:04 +10009217static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009218os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009219 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009220/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009221{
9222 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009223 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009224
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009225 do {
9226 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009227#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009228 if (dir_fd != DEFAULT_DIR_FD)
9229 result = mknodat(dir_fd, path->narrow, mode, device);
9230 else
Larry Hastings2f936352014-08-05 14:04:04 +10009231#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009232 result = mknod(path->narrow, mode, device);
9233 Py_END_ALLOW_THREADS
9234 } while (result != 0 && errno == EINTR &&
9235 !(async_err = PyErr_CheckSignals()));
9236 if (result != 0)
9237 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009238
9239 Py_RETURN_NONE;
9240}
9241#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9242
9243
9244#ifdef HAVE_DEVICE_MACROS
9245/*[clinic input]
9246os.major -> unsigned_int
9247
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009248 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009249 /
9250
9251Extracts a device major number from a raw device number.
9252[clinic start generated code]*/
9253
Larry Hastings2f936352014-08-05 14:04:04 +10009254static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009255os_major_impl(PyObject *module, dev_t device)
9256/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009257{
9258 return major(device);
9259}
9260
9261
9262/*[clinic input]
9263os.minor -> unsigned_int
9264
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009265 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009266 /
9267
9268Extracts a device minor number from a raw device number.
9269[clinic start generated code]*/
9270
Larry Hastings2f936352014-08-05 14:04:04 +10009271static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009272os_minor_impl(PyObject *module, dev_t device)
9273/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009274{
9275 return minor(device);
9276}
9277
9278
9279/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009280os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009281
9282 major: int
9283 minor: int
9284 /
9285
9286Composes a raw device number from the major and minor device numbers.
9287[clinic start generated code]*/
9288
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009289static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009290os_makedev_impl(PyObject *module, int major, int minor)
9291/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009292{
9293 return makedev(major, minor);
9294}
9295#endif /* HAVE_DEVICE_MACROS */
9296
9297
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009298#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009299/*[clinic input]
9300os.ftruncate
9301
9302 fd: int
9303 length: Py_off_t
9304 /
9305
9306Truncate a file, specified by file descriptor, to a specific length.
9307[clinic start generated code]*/
9308
Larry Hastings2f936352014-08-05 14:04:04 +10009309static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009310os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9311/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009312{
9313 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009314 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009315
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009316 do {
9317 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009318 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009319#ifdef MS_WINDOWS
9320 result = _chsize_s(fd, length);
9321#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009322 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009323#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009324 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009325 Py_END_ALLOW_THREADS
9326 } while (result != 0 && errno == EINTR &&
9327 !(async_err = PyErr_CheckSignals()));
9328 if (result != 0)
9329 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009330 Py_RETURN_NONE;
9331}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009332#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009333
9334
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009335#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009336/*[clinic input]
9337os.truncate
9338 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9339 length: Py_off_t
9340
9341Truncate a file, specified by path, to a specific length.
9342
9343On some platforms, path may also be specified as an open file descriptor.
9344 If this functionality is unavailable, using it raises an exception.
9345[clinic start generated code]*/
9346
Larry Hastings2f936352014-08-05 14:04:04 +10009347static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009348os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9349/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009350{
9351 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009352#ifdef MS_WINDOWS
9353 int fd;
9354#endif
9355
9356 if (path->fd != -1)
9357 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009358
9359 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009360 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009361#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009362 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009363 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009364 result = -1;
9365 else {
9366 result = _chsize_s(fd, length);
9367 close(fd);
9368 if (result < 0)
9369 errno = result;
9370 }
9371#else
9372 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009373#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009374 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009375 Py_END_ALLOW_THREADS
9376 if (result < 0)
9377 return path_error(path);
9378
9379 Py_RETURN_NONE;
9380}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009381#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009382
Ross Lagerwall7807c352011-03-17 20:20:30 +02009383
Victor Stinnerd6b17692014-09-30 12:20:05 +02009384/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9385 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9386 defined, which is the case in Python on AIX. AIX bug report:
9387 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9388#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9389# define POSIX_FADVISE_AIX_BUG
9390#endif
9391
Victor Stinnerec39e262014-09-30 12:35:58 +02009392
Victor Stinnerd6b17692014-09-30 12:20:05 +02009393#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009394/*[clinic input]
9395os.posix_fallocate
9396
9397 fd: int
9398 offset: Py_off_t
9399 length: Py_off_t
9400 /
9401
9402Ensure a file has allocated at least a particular number of bytes on disk.
9403
9404Ensure that the file specified by fd encompasses a range of bytes
9405starting at offset bytes from the beginning and continuing for length bytes.
9406[clinic start generated code]*/
9407
Larry Hastings2f936352014-08-05 14:04:04 +10009408static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009409os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009410 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009411/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009412{
9413 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009414 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009415
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009416 do {
9417 Py_BEGIN_ALLOW_THREADS
9418 result = posix_fallocate(fd, offset, length);
9419 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009420 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9421
9422 if (result == 0)
9423 Py_RETURN_NONE;
9424
9425 if (async_err)
9426 return NULL;
9427
9428 errno = result;
9429 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009430}
Victor Stinnerec39e262014-09-30 12:35:58 +02009431#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009432
Ross Lagerwall7807c352011-03-17 20:20:30 +02009433
Victor Stinnerd6b17692014-09-30 12:20:05 +02009434#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009435/*[clinic input]
9436os.posix_fadvise
9437
9438 fd: int
9439 offset: Py_off_t
9440 length: Py_off_t
9441 advice: int
9442 /
9443
9444Announce an intention to access data in a specific pattern.
9445
9446Announce an intention to access data in a specific pattern, thus allowing
9447the kernel to make optimizations.
9448The advice applies to the region of the file specified by fd starting at
9449offset and continuing for length bytes.
9450advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9451POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9452POSIX_FADV_DONTNEED.
9453[clinic start generated code]*/
9454
Larry Hastings2f936352014-08-05 14:04:04 +10009455static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009456os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009457 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009458/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009459{
9460 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009461 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009462
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009463 do {
9464 Py_BEGIN_ALLOW_THREADS
9465 result = posix_fadvise(fd, offset, length, advice);
9466 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009467 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9468
9469 if (result == 0)
9470 Py_RETURN_NONE;
9471
9472 if (async_err)
9473 return NULL;
9474
9475 errno = result;
9476 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009477}
Victor Stinnerec39e262014-09-30 12:35:58 +02009478#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009479
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009480#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009481
Fred Drake762e2061999-08-26 17:23:54 +00009482/* Save putenv() parameters as values here, so we can collect them when they
9483 * get re-set with another call for the same key. */
9484static PyObject *posix_putenv_garbage;
9485
Larry Hastings2f936352014-08-05 14:04:04 +10009486static void
9487posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009488{
Larry Hastings2f936352014-08-05 14:04:04 +10009489 /* Install the first arg and newstr in posix_putenv_garbage;
9490 * this will cause previous value to be collected. This has to
9491 * happen after the real putenv() call because the old value
9492 * was still accessible until then. */
9493 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9494 /* really not much we can do; just leak */
9495 PyErr_Clear();
9496 else
9497 Py_DECREF(value);
9498}
9499
9500
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009501#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009502/*[clinic input]
9503os.putenv
9504
9505 name: unicode
9506 value: unicode
9507 /
9508
9509Change or add an environment variable.
9510[clinic start generated code]*/
9511
Larry Hastings2f936352014-08-05 14:04:04 +10009512static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009513os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9514/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009515{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009516 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009517 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009518
Serhiy Storchaka77703942017-06-25 07:33:01 +03009519 /* Search from index 1 because on Windows starting '=' is allowed for
9520 defining hidden environment variables. */
9521 if (PyUnicode_GET_LENGTH(name) == 0 ||
9522 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9523 {
9524 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9525 return NULL;
9526 }
Larry Hastings2f936352014-08-05 14:04:04 +10009527 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9528 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009529 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009530 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009531
9532 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9533 if (env == NULL)
9534 goto error;
9535 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009536 PyErr_Format(PyExc_ValueError,
9537 "the environment variable is longer than %u characters",
9538 _MAX_ENV);
9539 goto error;
9540 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009541 if (wcslen(env) != (size_t)size) {
9542 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009543 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009544 }
9545
Larry Hastings2f936352014-08-05 14:04:04 +10009546 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009548 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009550
Larry Hastings2f936352014-08-05 14:04:04 +10009551 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009552 Py_RETURN_NONE;
9553
9554error:
Larry Hastings2f936352014-08-05 14:04:04 +10009555 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009556 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009557}
Larry Hastings2f936352014-08-05 14:04:04 +10009558#else /* MS_WINDOWS */
9559/*[clinic input]
9560os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009561
Larry Hastings2f936352014-08-05 14:04:04 +10009562 name: FSConverter
9563 value: FSConverter
9564 /
9565
9566Change or add an environment variable.
9567[clinic start generated code]*/
9568
Larry Hastings2f936352014-08-05 14:04:04 +10009569static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009570os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9571/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009572{
9573 PyObject *bytes = NULL;
9574 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009575 const char *name_string = PyBytes_AS_STRING(name);
9576 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009577
Serhiy Storchaka77703942017-06-25 07:33:01 +03009578 if (strchr(name_string, '=') != NULL) {
9579 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9580 return NULL;
9581 }
Larry Hastings2f936352014-08-05 14:04:04 +10009582 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9583 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009584 return NULL;
9585 }
9586
9587 env = PyBytes_AS_STRING(bytes);
9588 if (putenv(env)) {
9589 Py_DECREF(bytes);
9590 return posix_error();
9591 }
9592
9593 posix_putenv_garbage_setitem(name, bytes);
9594 Py_RETURN_NONE;
9595}
9596#endif /* MS_WINDOWS */
9597#endif /* HAVE_PUTENV */
9598
9599
9600#ifdef HAVE_UNSETENV
9601/*[clinic input]
9602os.unsetenv
9603 name: FSConverter
9604 /
9605
9606Delete an environment variable.
9607[clinic start generated code]*/
9608
Larry Hastings2f936352014-08-05 14:04:04 +10009609static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009610os_unsetenv_impl(PyObject *module, PyObject *name)
9611/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009612{
Victor Stinner984890f2011-11-24 13:53:38 +01009613#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009614 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009615#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009616
Victor Stinner984890f2011-11-24 13:53:38 +01009617#ifdef HAVE_BROKEN_UNSETENV
9618 unsetenv(PyBytes_AS_STRING(name));
9619#else
Victor Stinner65170952011-11-22 22:16:17 +01009620 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009621 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009622 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009623#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009624
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 /* Remove the key from posix_putenv_garbage;
9626 * this will cause it to be collected. This has to
9627 * happen after the real unsetenv() call because the
9628 * old value was still accessible until then.
9629 */
Victor Stinner65170952011-11-22 22:16:17 +01009630 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 /* really not much we can do; just leak */
9632 PyErr_Clear();
9633 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009634 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009635}
Larry Hastings2f936352014-08-05 14:04:04 +10009636#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009637
Larry Hastings2f936352014-08-05 14:04:04 +10009638
9639/*[clinic input]
9640os.strerror
9641
9642 code: int
9643 /
9644
9645Translate an error code to a message string.
9646[clinic start generated code]*/
9647
Larry Hastings2f936352014-08-05 14:04:04 +10009648static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009649os_strerror_impl(PyObject *module, int code)
9650/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009651{
9652 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 if (message == NULL) {
9654 PyErr_SetString(PyExc_ValueError,
9655 "strerror() argument out of range");
9656 return NULL;
9657 }
Victor Stinner1b579672011-12-17 05:47:23 +01009658 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009659}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009660
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009661
Guido van Rossumc9641791998-08-04 15:26:23 +00009662#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009663#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009664/*[clinic input]
9665os.WCOREDUMP -> bool
9666
9667 status: int
9668 /
9669
9670Return True if the process returning status was dumped to a core file.
9671[clinic start generated code]*/
9672
Larry Hastings2f936352014-08-05 14:04:04 +10009673static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009674os_WCOREDUMP_impl(PyObject *module, int status)
9675/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009676{
9677 WAIT_TYPE wait_status;
9678 WAIT_STATUS_INT(wait_status) = status;
9679 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009680}
9681#endif /* WCOREDUMP */
9682
Larry Hastings2f936352014-08-05 14:04:04 +10009683
Fred Drake106c1a02002-04-23 15:58:02 +00009684#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009685/*[clinic input]
9686os.WIFCONTINUED -> bool
9687
9688 status: int
9689
9690Return True if a particular process was continued from a job control stop.
9691
9692Return True if the process returning status was continued from a
9693job control stop.
9694[clinic start generated code]*/
9695
Larry Hastings2f936352014-08-05 14:04:04 +10009696static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009697os_WIFCONTINUED_impl(PyObject *module, int status)
9698/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009699{
9700 WAIT_TYPE wait_status;
9701 WAIT_STATUS_INT(wait_status) = status;
9702 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009703}
9704#endif /* WIFCONTINUED */
9705
Larry Hastings2f936352014-08-05 14:04:04 +10009706
Guido van Rossumc9641791998-08-04 15:26:23 +00009707#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009708/*[clinic input]
9709os.WIFSTOPPED -> bool
9710
9711 status: int
9712
9713Return True if the process returning status was stopped.
9714[clinic start generated code]*/
9715
Larry Hastings2f936352014-08-05 14:04:04 +10009716static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009717os_WIFSTOPPED_impl(PyObject *module, int status)
9718/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009719{
9720 WAIT_TYPE wait_status;
9721 WAIT_STATUS_INT(wait_status) = status;
9722 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009723}
9724#endif /* WIFSTOPPED */
9725
Larry Hastings2f936352014-08-05 14:04:04 +10009726
Guido van Rossumc9641791998-08-04 15:26:23 +00009727#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009728/*[clinic input]
9729os.WIFSIGNALED -> bool
9730
9731 status: int
9732
9733Return True if the process returning status was terminated by a signal.
9734[clinic start generated code]*/
9735
Larry Hastings2f936352014-08-05 14:04:04 +10009736static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009737os_WIFSIGNALED_impl(PyObject *module, int status)
9738/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009739{
9740 WAIT_TYPE wait_status;
9741 WAIT_STATUS_INT(wait_status) = status;
9742 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009743}
9744#endif /* WIFSIGNALED */
9745
Larry Hastings2f936352014-08-05 14:04:04 +10009746
Guido van Rossumc9641791998-08-04 15:26:23 +00009747#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009748/*[clinic input]
9749os.WIFEXITED -> bool
9750
9751 status: int
9752
9753Return True if the process returning status exited via the exit() system call.
9754[clinic start generated code]*/
9755
Larry Hastings2f936352014-08-05 14:04:04 +10009756static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009757os_WIFEXITED_impl(PyObject *module, int status)
9758/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009759{
9760 WAIT_TYPE wait_status;
9761 WAIT_STATUS_INT(wait_status) = status;
9762 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009763}
9764#endif /* WIFEXITED */
9765
Larry Hastings2f936352014-08-05 14:04:04 +10009766
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009767#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009768/*[clinic input]
9769os.WEXITSTATUS -> int
9770
9771 status: int
9772
9773Return the process return code from status.
9774[clinic start generated code]*/
9775
Larry Hastings2f936352014-08-05 14:04:04 +10009776static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009777os_WEXITSTATUS_impl(PyObject *module, int status)
9778/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009779{
9780 WAIT_TYPE wait_status;
9781 WAIT_STATUS_INT(wait_status) = status;
9782 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009783}
9784#endif /* WEXITSTATUS */
9785
Larry Hastings2f936352014-08-05 14:04:04 +10009786
Guido van Rossumc9641791998-08-04 15:26:23 +00009787#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009788/*[clinic input]
9789os.WTERMSIG -> int
9790
9791 status: int
9792
9793Return the signal that terminated the process that provided the status value.
9794[clinic start generated code]*/
9795
Larry Hastings2f936352014-08-05 14:04:04 +10009796static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009797os_WTERMSIG_impl(PyObject *module, int status)
9798/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009799{
9800 WAIT_TYPE wait_status;
9801 WAIT_STATUS_INT(wait_status) = status;
9802 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009803}
9804#endif /* WTERMSIG */
9805
Larry Hastings2f936352014-08-05 14:04:04 +10009806
Guido van Rossumc9641791998-08-04 15:26:23 +00009807#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009808/*[clinic input]
9809os.WSTOPSIG -> int
9810
9811 status: int
9812
9813Return the signal that stopped the process that provided the status value.
9814[clinic start generated code]*/
9815
Larry Hastings2f936352014-08-05 14:04:04 +10009816static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009817os_WSTOPSIG_impl(PyObject *module, int status)
9818/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009819{
9820 WAIT_TYPE wait_status;
9821 WAIT_STATUS_INT(wait_status) = status;
9822 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009823}
9824#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009825#endif /* HAVE_SYS_WAIT_H */
9826
9827
Thomas Wouters477c8d52006-05-27 19:21:47 +00009828#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009829#ifdef _SCO_DS
9830/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9831 needed definitions in sys/statvfs.h */
9832#define _SVID3
9833#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009834#include <sys/statvfs.h>
9835
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009836static PyObject*
9837_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9839 if (v == NULL)
9840 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009841
9842#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9844 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9845 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9846 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9847 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9848 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9849 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9850 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9851 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9852 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009853#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009854 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9855 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9856 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009857 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009859 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009861 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009863 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009865 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009867 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9869 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009870#endif
Michael Felt502d5512018-01-05 13:01:58 +01009871/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9872 * (issue #32390). */
9873#if defined(_AIX) && defined(_ALL_SOURCE)
9874 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9875#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009876 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009877#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009878 if (PyErr_Occurred()) {
9879 Py_DECREF(v);
9880 return NULL;
9881 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009882
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009884}
9885
Larry Hastings2f936352014-08-05 14:04:04 +10009886
9887/*[clinic input]
9888os.fstatvfs
9889 fd: int
9890 /
9891
9892Perform an fstatvfs system call on the given fd.
9893
9894Equivalent to statvfs(fd).
9895[clinic start generated code]*/
9896
Larry Hastings2f936352014-08-05 14:04:04 +10009897static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009898os_fstatvfs_impl(PyObject *module, int fd)
9899/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009900{
9901 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009902 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009904
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009905 do {
9906 Py_BEGIN_ALLOW_THREADS
9907 result = fstatvfs(fd, &st);
9908 Py_END_ALLOW_THREADS
9909 } while (result != 0 && errno == EINTR &&
9910 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009911 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009912 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009913
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009915}
Larry Hastings2f936352014-08-05 14:04:04 +10009916#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009917
9918
Thomas Wouters477c8d52006-05-27 19:21:47 +00009919#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009920#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009921/*[clinic input]
9922os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009923
Larry Hastings2f936352014-08-05 14:04:04 +10009924 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9925
9926Perform a statvfs system call on the given path.
9927
9928path may always be specified as a string.
9929On some platforms, path may also be specified as an open file descriptor.
9930 If this functionality is unavailable, using it raises an exception.
9931[clinic start generated code]*/
9932
Larry Hastings2f936352014-08-05 14:04:04 +10009933static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009934os_statvfs_impl(PyObject *module, path_t *path)
9935/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009936{
9937 int result;
9938 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009939
9940 Py_BEGIN_ALLOW_THREADS
9941#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009942 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009943#ifdef __APPLE__
9944 /* handle weak-linking on Mac OS X 10.3 */
9945 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009946 fd_specified("statvfs", path->fd);
9947 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009948 }
9949#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009950 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009951 }
9952 else
9953#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009954 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009955 Py_END_ALLOW_THREADS
9956
9957 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009958 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009959 }
9960
Larry Hastings2f936352014-08-05 14:04:04 +10009961 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009962}
Larry Hastings2f936352014-08-05 14:04:04 +10009963#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9964
Guido van Rossum94f6f721999-01-06 18:42:14 +00009965
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009966#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009967/*[clinic input]
9968os._getdiskusage
9969
Steve Dower23ad6d02018-02-22 10:39:10 -08009970 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10009971
9972Return disk usage statistics about the given path as a (total, free) tuple.
9973[clinic start generated code]*/
9974
Larry Hastings2f936352014-08-05 14:04:04 +10009975static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08009976os__getdiskusage_impl(PyObject *module, path_t *path)
9977/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009978{
9979 BOOL retval;
9980 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009981
9982 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08009983 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009984 Py_END_ALLOW_THREADS
9985 if (retval == 0)
9986 return PyErr_SetFromWindowsErr(0);
9987
9988 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9989}
Larry Hastings2f936352014-08-05 14:04:04 +10009990#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009991
9992
Fred Drakec9680921999-12-13 16:37:25 +00009993/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9994 * It maps strings representing configuration variable names to
9995 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009996 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009997 * rarely-used constants. There are three separate tables that use
9998 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009999 *
10000 * This code is always included, even if none of the interfaces that
10001 * need it are included. The #if hackery needed to avoid it would be
10002 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010003 */
10004struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010005 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010006 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010007};
10008
Fred Drake12c6e2d1999-12-14 21:25:03 +000010009static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010010conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010011 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010012{
Christian Heimes217cfd12007-12-02 14:31:20 +000010013 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010014 int value = _PyLong_AsInt(arg);
10015 if (value == -1 && PyErr_Occurred())
10016 return 0;
10017 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010018 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010019 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010020 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010021 /* look up the value in the table using a binary search */
10022 size_t lo = 0;
10023 size_t mid;
10024 size_t hi = tablesize;
10025 int cmp;
10026 const char *confname;
10027 if (!PyUnicode_Check(arg)) {
10028 PyErr_SetString(PyExc_TypeError,
10029 "configuration names must be strings or integers");
10030 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010032 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010033 if (confname == NULL)
10034 return 0;
10035 while (lo < hi) {
10036 mid = (lo + hi) / 2;
10037 cmp = strcmp(confname, table[mid].name);
10038 if (cmp < 0)
10039 hi = mid;
10040 else if (cmp > 0)
10041 lo = mid + 1;
10042 else {
10043 *valuep = table[mid].value;
10044 return 1;
10045 }
10046 }
10047 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10048 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010050}
10051
10052
10053#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10054static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010055#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010057#endif
10058#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010060#endif
Fred Drakec9680921999-12-13 16:37:25 +000010061#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010106#ifdef _PC_ACL_ENABLED
10107 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10108#endif
10109#ifdef _PC_MIN_HOLE_SIZE
10110 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10111#endif
10112#ifdef _PC_ALLOC_SIZE_MIN
10113 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10114#endif
10115#ifdef _PC_REC_INCR_XFER_SIZE
10116 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10117#endif
10118#ifdef _PC_REC_MAX_XFER_SIZE
10119 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10120#endif
10121#ifdef _PC_REC_MIN_XFER_SIZE
10122 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10123#endif
10124#ifdef _PC_REC_XFER_ALIGN
10125 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10126#endif
10127#ifdef _PC_SYMLINK_MAX
10128 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10129#endif
10130#ifdef _PC_XATTR_ENABLED
10131 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10132#endif
10133#ifdef _PC_XATTR_EXISTS
10134 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10135#endif
10136#ifdef _PC_TIMESTAMP_RESOLUTION
10137 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10138#endif
Fred Drakec9680921999-12-13 16:37:25 +000010139};
10140
Fred Drakec9680921999-12-13 16:37:25 +000010141static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010142conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010143{
10144 return conv_confname(arg, valuep, posix_constants_pathconf,
10145 sizeof(posix_constants_pathconf)
10146 / sizeof(struct constdef));
10147}
10148#endif
10149
Larry Hastings2f936352014-08-05 14:04:04 +100010150
Fred Drakec9680921999-12-13 16:37:25 +000010151#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010152/*[clinic input]
10153os.fpathconf -> long
10154
10155 fd: int
10156 name: path_confname
10157 /
10158
10159Return the configuration limit name for the file descriptor fd.
10160
10161If there is no limit, return -1.
10162[clinic start generated code]*/
10163
Larry Hastings2f936352014-08-05 14:04:04 +100010164static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010165os_fpathconf_impl(PyObject *module, int fd, int name)
10166/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010167{
10168 long limit;
10169
10170 errno = 0;
10171 limit = fpathconf(fd, name);
10172 if (limit == -1 && errno != 0)
10173 posix_error();
10174
10175 return limit;
10176}
10177#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010178
10179
10180#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010181/*[clinic input]
10182os.pathconf -> long
10183 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10184 name: path_confname
10185
10186Return the configuration limit name for the file or directory path.
10187
10188If there is no limit, return -1.
10189On some platforms, path may also be specified as an open file descriptor.
10190 If this functionality is unavailable, using it raises an exception.
10191[clinic start generated code]*/
10192
Larry Hastings2f936352014-08-05 14:04:04 +100010193static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010194os_pathconf_impl(PyObject *module, path_t *path, int name)
10195/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010196{
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010198
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010200#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010201 if (path->fd != -1)
10202 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010203 else
10204#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010205 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 if (limit == -1 && errno != 0) {
10207 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010208 /* could be a path or name problem */
10209 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010210 else
Larry Hastings2f936352014-08-05 14:04:04 +100010211 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 }
Larry Hastings2f936352014-08-05 14:04:04 +100010213
10214 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010215}
Larry Hastings2f936352014-08-05 14:04:04 +100010216#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010217
10218#ifdef HAVE_CONFSTR
10219static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010220#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010222#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010223#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010225#endif
10226#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010228#endif
Fred Draked86ed291999-12-15 15:34:33 +000010229#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010231#endif
10232#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010234#endif
10235#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010237#endif
10238#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010240#endif
Fred Drakec9680921999-12-13 16:37:25 +000010241#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
10259#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
10262#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
Fred Draked86ed291999-12-15 15:34:33 +000010265#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010267#endif
Fred Drakec9680921999-12-13 16:37:25 +000010268#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
Fred Draked86ed291999-12-15 15:34:33 +000010271#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010273#endif
10274#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010276#endif
10277#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010279#endif
10280#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010282#endif
Fred Drakec9680921999-12-13 16:37:25 +000010283#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010285#endif
10286#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
10289#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010291#endif
10292#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010294#endif
10295#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010303#endif
10304#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010306#endif
10307#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010309#endif
10310#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010312#endif
10313#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010315#endif
10316#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
10319#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010321#endif
10322#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010324#endif
10325#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
10328#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010330#endif
Fred Draked86ed291999-12-15 15:34:33 +000010331#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010333#endif
10334#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010336#endif
10337#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010339#endif
10340#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010342#endif
10343#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010345#endif
10346#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010348#endif
10349#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010351#endif
10352#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010354#endif
10355#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010357#endif
10358#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010360#endif
10361#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010363#endif
10364#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010366#endif
10367#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010369#endif
Fred Drakec9680921999-12-13 16:37:25 +000010370};
10371
10372static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010373conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010374{
10375 return conv_confname(arg, valuep, posix_constants_confstr,
10376 sizeof(posix_constants_confstr)
10377 / sizeof(struct constdef));
10378}
10379
Larry Hastings2f936352014-08-05 14:04:04 +100010380
10381/*[clinic input]
10382os.confstr
10383
10384 name: confstr_confname
10385 /
10386
10387Return a string-valued system configuration variable.
10388[clinic start generated code]*/
10389
Larry Hastings2f936352014-08-05 14:04:04 +100010390static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010391os_confstr_impl(PyObject *module, int name)
10392/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010393{
10394 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010395 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010396 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010397
Victor Stinnercb043522010-09-10 23:49:04 +000010398 errno = 0;
10399 len = confstr(name, buffer, sizeof(buffer));
10400 if (len == 0) {
10401 if (errno) {
10402 posix_error();
10403 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010404 }
10405 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010406 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010407 }
10408 }
Victor Stinnercb043522010-09-10 23:49:04 +000010409
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010410 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010411 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010412 char *buf = PyMem_Malloc(len);
10413 if (buf == NULL)
10414 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010415 len2 = confstr(name, buf, len);
10416 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010417 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010418 PyMem_Free(buf);
10419 }
10420 else
10421 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010422 return result;
10423}
Larry Hastings2f936352014-08-05 14:04:04 +100010424#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010425
10426
10427#ifdef HAVE_SYSCONF
10428static struct constdef posix_constants_sysconf[] = {
10429#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010430 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010431#endif
10432#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010433 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010434#endif
10435#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010436 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010437#endif
10438#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010440#endif
10441#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010443#endif
10444#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010445 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010446#endif
10447#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010448 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010449#endif
10450#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010452#endif
10453#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010455#endif
10456#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010458#endif
Fred Draked86ed291999-12-15 15:34:33 +000010459#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010461#endif
10462#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010463 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010464#endif
Fred Drakec9680921999-12-13 16:37:25 +000010465#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010467#endif
Fred Drakec9680921999-12-13 16:37:25 +000010468#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010470#endif
10471#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010473#endif
10474#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010475 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010476#endif
10477#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010479#endif
10480#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010482#endif
Fred Draked86ed291999-12-15 15:34:33 +000010483#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010485#endif
Fred Drakec9680921999-12-13 16:37:25 +000010486#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010488#endif
10489#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010491#endif
10492#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010493 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010494#endif
10495#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010496 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010497#endif
10498#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010500#endif
Fred Draked86ed291999-12-15 15:34:33 +000010501#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010502 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010503#endif
Fred Drakec9680921999-12-13 16:37:25 +000010504#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010506#endif
10507#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010509#endif
10510#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010511 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010512#endif
10513#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010514 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010515#endif
10516#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010517 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010518#endif
10519#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010521#endif
10522#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010524#endif
10525#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010527#endif
10528#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010529 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010530#endif
10531#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010532 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010533#endif
10534#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010535 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010536#endif
10537#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010538 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010539#endif
10540#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010542#endif
10543#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010545#endif
10546#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010547 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010548#endif
10549#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010550 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010551#endif
10552#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010554#endif
10555#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010556 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010557#endif
10558#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010560#endif
10561#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010562 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010563#endif
10564#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010566#endif
10567#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010569#endif
10570#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010572#endif
Fred Draked86ed291999-12-15 15:34:33 +000010573#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010574 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010575#endif
Fred Drakec9680921999-12-13 16:37:25 +000010576#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010578#endif
10579#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010580 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010581#endif
10582#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010583 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010584#endif
Fred Draked86ed291999-12-15 15:34:33 +000010585#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010586 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010587#endif
Fred Drakec9680921999-12-13 16:37:25 +000010588#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010589 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010590#endif
Fred Draked86ed291999-12-15 15:34:33 +000010591#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010592 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010593#endif
10594#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010596#endif
Fred Drakec9680921999-12-13 16:37:25 +000010597#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010598 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010599#endif
10600#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010602#endif
10603#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010605#endif
10606#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010608#endif
Fred Draked86ed291999-12-15 15:34:33 +000010609#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010610 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010611#endif
Fred Drakec9680921999-12-13 16:37:25 +000010612#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010613 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010614#endif
10615#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010616 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010617#endif
10618#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010619 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010620#endif
10621#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010622 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010623#endif
10624#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010625 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010626#endif
10627#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010628 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010629#endif
10630#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010631 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010632#endif
Fred Draked86ed291999-12-15 15:34:33 +000010633#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010634 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010635#endif
Fred Drakec9680921999-12-13 16:37:25 +000010636#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010637 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010638#endif
10639#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010640 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010641#endif
Fred Draked86ed291999-12-15 15:34:33 +000010642#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010643 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010644#endif
Fred Drakec9680921999-12-13 16:37:25 +000010645#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010646 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010647#endif
10648#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010649 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010650#endif
10651#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010652 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010653#endif
10654#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010655 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010656#endif
10657#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010658 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010659#endif
10660#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010661 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010662#endif
10663#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010664 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010665#endif
10666#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010667 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010668#endif
10669#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010670 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010671#endif
Fred Draked86ed291999-12-15 15:34:33 +000010672#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010673 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010674#endif
10675#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010676 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010677#endif
Fred Drakec9680921999-12-13 16:37:25 +000010678#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010680#endif
10681#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010682 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010683#endif
10684#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010686#endif
10687#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010688 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010689#endif
10690#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010691 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010692#endif
10693#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010694 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010695#endif
10696#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010697 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010698#endif
10699#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010700 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010701#endif
10702#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010703 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010704#endif
10705#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010706 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010707#endif
10708#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010709 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010710#endif
10711#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010712 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010713#endif
10714#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010715 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010716#endif
10717#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010718 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010719#endif
10720#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010721 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010722#endif
10723#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010724 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010725#endif
10726#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010727 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010728#endif
10729#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010730 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010731#endif
10732#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010733 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010734#endif
10735#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010736 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010737#endif
10738#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010739 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010740#endif
10741#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010742 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010743#endif
10744#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010745 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010746#endif
10747#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010748 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010749#endif
10750#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010751 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010752#endif
10753#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010754 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010755#endif
10756#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010757 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010758#endif
10759#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010760 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010761#endif
10762#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010763 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010764#endif
10765#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010766 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010767#endif
10768#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010769 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010770#endif
10771#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010772 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010773#endif
10774#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010775 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010776#endif
10777#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010778 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010779#endif
10780#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010781 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010782#endif
Fred Draked86ed291999-12-15 15:34:33 +000010783#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010785#endif
Fred Drakec9680921999-12-13 16:37:25 +000010786#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010788#endif
10789#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010791#endif
10792#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010794#endif
10795#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010797#endif
10798#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010800#endif
10801#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010802 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010803#endif
10804#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010806#endif
10807#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010809#endif
10810#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010812#endif
10813#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010815#endif
10816#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010818#endif
10819#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010821#endif
10822#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010824#endif
10825#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010826 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010827#endif
10828#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010829 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010830#endif
10831#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010832 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010833#endif
10834#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010835 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010836#endif
10837#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010838 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010839#endif
10840#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010841 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010842#endif
10843#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010844 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010845#endif
10846#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010847 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010848#endif
10849#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010851#endif
10852#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010853 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010854#endif
10855#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010856 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010857#endif
10858#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010859 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010860#endif
10861#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010862 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010863#endif
10864#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010865 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010866#endif
10867#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010868 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010869#endif
10870#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010871 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010872#endif
10873#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010874 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010875#endif
10876#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010877 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010878#endif
10879#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010880 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010881#endif
10882#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010883 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010884#endif
10885#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010886 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010887#endif
10888#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010889 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010890#endif
10891#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010892 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010893#endif
10894#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010895 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010896#endif
10897#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010898 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010899#endif
10900#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010901 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010902#endif
10903#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010905#endif
10906#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010908#endif
10909#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010910 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010911#endif
10912#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010914#endif
10915#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010917#endif
10918#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010919 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010920#endif
10921};
10922
10923static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010924conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010925{
10926 return conv_confname(arg, valuep, posix_constants_sysconf,
10927 sizeof(posix_constants_sysconf)
10928 / sizeof(struct constdef));
10929}
10930
Larry Hastings2f936352014-08-05 14:04:04 +100010931
10932/*[clinic input]
10933os.sysconf -> long
10934 name: sysconf_confname
10935 /
10936
10937Return an integer-valued system configuration variable.
10938[clinic start generated code]*/
10939
Larry Hastings2f936352014-08-05 14:04:04 +100010940static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010941os_sysconf_impl(PyObject *module, int name)
10942/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010943{
10944 long value;
10945
10946 errno = 0;
10947 value = sysconf(name);
10948 if (value == -1 && errno != 0)
10949 posix_error();
10950 return value;
10951}
10952#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010953
10954
Fred Drakebec628d1999-12-15 18:31:10 +000010955/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010956 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010957 * the exported dictionaries that are used to publish information about the
10958 * names available on the host platform.
10959 *
10960 * Sorting the table at runtime ensures that the table is properly ordered
10961 * when used, even for platforms we're not able to test on. It also makes
10962 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010963 */
Fred Drakebec628d1999-12-15 18:31:10 +000010964
10965static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010966cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010967{
10968 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010969 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010970 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010971 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010972
10973 return strcmp(c1->name, c2->name);
10974}
10975
10976static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010977setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010978 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010979{
Fred Drakebec628d1999-12-15 18:31:10 +000010980 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010981 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010982
10983 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10984 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010985 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010986 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010987
Barry Warsaw3155db32000-04-13 15:20:40 +000010988 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010989 PyObject *o = PyLong_FromLong(table[i].value);
10990 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10991 Py_XDECREF(o);
10992 Py_DECREF(d);
10993 return -1;
10994 }
10995 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010996 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010997 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010998}
10999
Fred Drakebec628d1999-12-15 18:31:10 +000011000/* Return -1 on failure, 0 on success. */
11001static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011002setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011003{
11004#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011005 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011006 sizeof(posix_constants_pathconf)
11007 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011008 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011009 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011010#endif
11011#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011012 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011013 sizeof(posix_constants_confstr)
11014 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011015 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011016 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011017#endif
11018#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011019 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011020 sizeof(posix_constants_sysconf)
11021 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011022 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011023 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011024#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011025 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011026}
Fred Draked86ed291999-12-15 15:34:33 +000011027
11028
Larry Hastings2f936352014-08-05 14:04:04 +100011029/*[clinic input]
11030os.abort
11031
11032Abort the interpreter immediately.
11033
11034This function 'dumps core' or otherwise fails in the hardest way possible
11035on the hosting operating system. This function never returns.
11036[clinic start generated code]*/
11037
Larry Hastings2f936352014-08-05 14:04:04 +100011038static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011039os_abort_impl(PyObject *module)
11040/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011041{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011042 abort();
11043 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011044#ifndef __clang__
11045 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11046 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11047 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011048 Py_FatalError("abort() called from Python code didn't abort!");
11049 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011050#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011051}
Fred Drakebec628d1999-12-15 18:31:10 +000011052
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011053#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011054/* Grab ShellExecute dynamically from shell32 */
11055static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011056static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11057 LPCWSTR, INT);
11058static int
11059check_ShellExecute()
11060{
11061 HINSTANCE hShell32;
11062
11063 /* only recheck */
11064 if (-1 == has_ShellExecute) {
11065 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011066 /* Security note: this call is not vulnerable to "DLL hijacking".
11067 SHELL32 is part of "KnownDLLs" and so Windows always load
11068 the system SHELL32.DLL, even if there is another SHELL32.DLL
11069 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011070 hShell32 = LoadLibraryW(L"SHELL32");
11071 Py_END_ALLOW_THREADS
11072 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011073 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11074 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011075 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011076 } else {
11077 has_ShellExecute = 0;
11078 }
11079 }
11080 return has_ShellExecute;
11081}
11082
11083
Steve Dowercc16be82016-09-08 10:35:16 -070011084/*[clinic input]
11085os.startfile
11086 filepath: path_t
11087 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011088
Steve Dowercc16be82016-09-08 10:35:16 -070011089startfile(filepath [, operation])
11090
11091Start a file with its associated application.
11092
11093When "operation" is not specified or "open", this acts like
11094double-clicking the file in Explorer, or giving the file name as an
11095argument to the DOS "start" command: the file is opened with whatever
11096application (if any) its extension is associated.
11097When another "operation" is given, it specifies what should be done with
11098the file. A typical operation is "print".
11099
11100startfile returns as soon as the associated application is launched.
11101There is no option to wait for the application to close, and no way
11102to retrieve the application's exit status.
11103
11104The filepath is relative to the current directory. If you want to use
11105an absolute path, make sure the first character is not a slash ("/");
11106the underlying Win32 ShellExecute function doesn't work if it is.
11107[clinic start generated code]*/
11108
11109static PyObject *
11110os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
11111/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
11112{
11113 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011114
11115 if(!check_ShellExecute()) {
11116 /* If the OS doesn't have ShellExecute, return a
11117 NotImplementedError. */
11118 return PyErr_Format(PyExc_NotImplementedError,
11119 "startfile not available on this platform");
11120 }
11121
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011123 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011124 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 Py_END_ALLOW_THREADS
11126
Victor Stinner8c62be82010-05-06 00:08:46 +000011127 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011128 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011129 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011130 }
Steve Dowercc16be82016-09-08 10:35:16 -070011131 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011132}
Larry Hastings2f936352014-08-05 14:04:04 +100011133#endif /* MS_WINDOWS */
11134
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011135
Martin v. Löwis438b5342002-12-27 10:16:42 +000011136#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011137/*[clinic input]
11138os.getloadavg
11139
11140Return average recent system load information.
11141
11142Return the number of processes in the system run queue averaged over
11143the last 1, 5, and 15 minutes as a tuple of three floats.
11144Raises OSError if the load average was unobtainable.
11145[clinic start generated code]*/
11146
Larry Hastings2f936352014-08-05 14:04:04 +100011147static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011148os_getloadavg_impl(PyObject *module)
11149/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011150{
11151 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011152 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011153 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11154 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011155 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011156 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011157}
Larry Hastings2f936352014-08-05 14:04:04 +100011158#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011159
Larry Hastings2f936352014-08-05 14:04:04 +100011160
11161/*[clinic input]
11162os.device_encoding
11163 fd: int
11164
11165Return a string describing the encoding of a terminal's file descriptor.
11166
11167The file descriptor must be attached to a terminal.
11168If the device is not a terminal, return None.
11169[clinic start generated code]*/
11170
Larry Hastings2f936352014-08-05 14:04:04 +100011171static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011172os_device_encoding_impl(PyObject *module, int fd)
11173/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011174{
Brett Cannonefb00c02012-02-29 18:31:31 -050011175 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011176}
11177
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011178
Larry Hastings2f936352014-08-05 14:04:04 +100011179#ifdef HAVE_SETRESUID
11180/*[clinic input]
11181os.setresuid
11182
11183 ruid: uid_t
11184 euid: uid_t
11185 suid: uid_t
11186 /
11187
11188Set the current process's real, effective, and saved user ids.
11189[clinic start generated code]*/
11190
Larry Hastings2f936352014-08-05 14:04:04 +100011191static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011192os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11193/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011194{
Victor Stinner8c62be82010-05-06 00:08:46 +000011195 if (setresuid(ruid, euid, suid) < 0)
11196 return posix_error();
11197 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011198}
Larry Hastings2f936352014-08-05 14:04:04 +100011199#endif /* HAVE_SETRESUID */
11200
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011201
11202#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011203/*[clinic input]
11204os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011205
Larry Hastings2f936352014-08-05 14:04:04 +100011206 rgid: gid_t
11207 egid: gid_t
11208 sgid: gid_t
11209 /
11210
11211Set the current process's real, effective, and saved group ids.
11212[clinic start generated code]*/
11213
Larry Hastings2f936352014-08-05 14:04:04 +100011214static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011215os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11216/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011217{
Victor Stinner8c62be82010-05-06 00:08:46 +000011218 if (setresgid(rgid, egid, sgid) < 0)
11219 return posix_error();
11220 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011221}
Larry Hastings2f936352014-08-05 14:04:04 +100011222#endif /* HAVE_SETRESGID */
11223
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011224
11225#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011226/*[clinic input]
11227os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011228
Larry Hastings2f936352014-08-05 14:04:04 +100011229Return a tuple of the current process's real, effective, and saved user ids.
11230[clinic start generated code]*/
11231
Larry Hastings2f936352014-08-05 14:04:04 +100011232static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011233os_getresuid_impl(PyObject *module)
11234/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011235{
Victor Stinner8c62be82010-05-06 00:08:46 +000011236 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011237 if (getresuid(&ruid, &euid, &suid) < 0)
11238 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011239 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11240 _PyLong_FromUid(euid),
11241 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011242}
Larry Hastings2f936352014-08-05 14:04:04 +100011243#endif /* HAVE_GETRESUID */
11244
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011245
11246#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011247/*[clinic input]
11248os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011249
Larry Hastings2f936352014-08-05 14:04:04 +100011250Return a tuple of the current process's real, effective, and saved group ids.
11251[clinic start generated code]*/
11252
Larry Hastings2f936352014-08-05 14:04:04 +100011253static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011254os_getresgid_impl(PyObject *module)
11255/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011256{
11257 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011258 if (getresgid(&rgid, &egid, &sgid) < 0)
11259 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011260 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11261 _PyLong_FromGid(egid),
11262 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011263}
Larry Hastings2f936352014-08-05 14:04:04 +100011264#endif /* HAVE_GETRESGID */
11265
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011266
Benjamin Peterson9428d532011-09-14 11:45:52 -040011267#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011268/*[clinic input]
11269os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011270
Larry Hastings2f936352014-08-05 14:04:04 +100011271 path: path_t(allow_fd=True)
11272 attribute: path_t
11273 *
11274 follow_symlinks: bool = True
11275
11276Return the value of extended attribute attribute on path.
11277
11278path may be either a string or an open file descriptor.
11279If follow_symlinks is False, and the last element of the path is a symbolic
11280 link, getxattr will examine the symbolic link itself instead of the file
11281 the link points to.
11282
11283[clinic start generated code]*/
11284
Larry Hastings2f936352014-08-05 14:04:04 +100011285static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011286os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011287 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011288/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011289{
11290 Py_ssize_t i;
11291 PyObject *buffer = NULL;
11292
11293 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11294 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011295
Larry Hastings9cf065c2012-06-22 16:30:09 -070011296 for (i = 0; ; i++) {
11297 void *ptr;
11298 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011299 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011300 Py_ssize_t buffer_size = buffer_sizes[i];
11301 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011302 path_error(path);
11303 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011304 }
11305 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11306 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011307 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011308 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011309
Larry Hastings9cf065c2012-06-22 16:30:09 -070011310 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011311 if (path->fd >= 0)
11312 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011313 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011314 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011315 else
Larry Hastings2f936352014-08-05 14:04:04 +100011316 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011317 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011318
Larry Hastings9cf065c2012-06-22 16:30:09 -070011319 if (result < 0) {
11320 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011321 if (errno == ERANGE)
11322 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011323 path_error(path);
11324 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011325 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011326
Larry Hastings9cf065c2012-06-22 16:30:09 -070011327 if (result != buffer_size) {
11328 /* Can only shrink. */
11329 _PyBytes_Resize(&buffer, result);
11330 }
11331 break;
11332 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011333
Larry Hastings9cf065c2012-06-22 16:30:09 -070011334 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011335}
11336
Larry Hastings2f936352014-08-05 14:04:04 +100011337
11338/*[clinic input]
11339os.setxattr
11340
11341 path: path_t(allow_fd=True)
11342 attribute: path_t
11343 value: Py_buffer
11344 flags: int = 0
11345 *
11346 follow_symlinks: bool = True
11347
11348Set extended attribute attribute on path to value.
11349
11350path may be either a string or an open file descriptor.
11351If follow_symlinks is False, and the last element of the path is a symbolic
11352 link, setxattr will modify the symbolic link itself instead of the file
11353 the link points to.
11354
11355[clinic start generated code]*/
11356
Benjamin Peterson799bd802011-08-31 22:15:17 -040011357static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011358os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011359 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011360/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011361{
Larry Hastings2f936352014-08-05 14:04:04 +100011362 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011363
Larry Hastings2f936352014-08-05 14:04:04 +100011364 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011365 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011366
Benjamin Peterson799bd802011-08-31 22:15:17 -040011367 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011368 if (path->fd > -1)
11369 result = fsetxattr(path->fd, attribute->narrow,
11370 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011371 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011372 result = setxattr(path->narrow, attribute->narrow,
11373 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011374 else
Larry Hastings2f936352014-08-05 14:04:04 +100011375 result = lsetxattr(path->narrow, attribute->narrow,
11376 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011377 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011378
Larry Hastings9cf065c2012-06-22 16:30:09 -070011379 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011380 path_error(path);
11381 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011382 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011383
Larry Hastings2f936352014-08-05 14:04:04 +100011384 Py_RETURN_NONE;
11385}
11386
11387
11388/*[clinic input]
11389os.removexattr
11390
11391 path: path_t(allow_fd=True)
11392 attribute: path_t
11393 *
11394 follow_symlinks: bool = True
11395
11396Remove extended attribute attribute on path.
11397
11398path may be either a string or an open file descriptor.
11399If follow_symlinks is False, and the last element of the path is a symbolic
11400 link, removexattr will modify the symbolic link itself instead of the file
11401 the link points to.
11402
11403[clinic start generated code]*/
11404
Larry Hastings2f936352014-08-05 14:04:04 +100011405static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011406os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011407 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011408/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011409{
11410 ssize_t result;
11411
11412 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11413 return NULL;
11414
11415 Py_BEGIN_ALLOW_THREADS;
11416 if (path->fd > -1)
11417 result = fremovexattr(path->fd, attribute->narrow);
11418 else if (follow_symlinks)
11419 result = removexattr(path->narrow, attribute->narrow);
11420 else
11421 result = lremovexattr(path->narrow, attribute->narrow);
11422 Py_END_ALLOW_THREADS;
11423
11424 if (result) {
11425 return path_error(path);
11426 }
11427
11428 Py_RETURN_NONE;
11429}
11430
11431
11432/*[clinic input]
11433os.listxattr
11434
11435 path: path_t(allow_fd=True, nullable=True) = None
11436 *
11437 follow_symlinks: bool = True
11438
11439Return a list of extended attributes on path.
11440
11441path may be either None, a string, or an open file descriptor.
11442if path is None, listxattr will examine the current directory.
11443If follow_symlinks is False, and the last element of the path is a symbolic
11444 link, listxattr will examine the symbolic link itself instead of the file
11445 the link points to.
11446[clinic start generated code]*/
11447
Larry Hastings2f936352014-08-05 14:04:04 +100011448static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011449os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
11450/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011451{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011452 Py_ssize_t i;
11453 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011454 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011455 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011456
Larry Hastings2f936352014-08-05 14:04:04 +100011457 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011458 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011459
Larry Hastings2f936352014-08-05 14:04:04 +100011460 name = path->narrow ? path->narrow : ".";
11461
Larry Hastings9cf065c2012-06-22 16:30:09 -070011462 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011463 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011464 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011465 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011466 Py_ssize_t buffer_size = buffer_sizes[i];
11467 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011468 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011469 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011470 break;
11471 }
11472 buffer = PyMem_MALLOC(buffer_size);
11473 if (!buffer) {
11474 PyErr_NoMemory();
11475 break;
11476 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011477
Larry Hastings9cf065c2012-06-22 16:30:09 -070011478 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011479 if (path->fd > -1)
11480 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011481 else if (follow_symlinks)
11482 length = listxattr(name, buffer, buffer_size);
11483 else
11484 length = llistxattr(name, buffer, buffer_size);
11485 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011486
Larry Hastings9cf065c2012-06-22 16:30:09 -070011487 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011488 if (errno == ERANGE) {
11489 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011490 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011491 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011492 }
Larry Hastings2f936352014-08-05 14:04:04 +100011493 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011494 break;
11495 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011496
Larry Hastings9cf065c2012-06-22 16:30:09 -070011497 result = PyList_New(0);
11498 if (!result) {
11499 goto exit;
11500 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011501
Larry Hastings9cf065c2012-06-22 16:30:09 -070011502 end = buffer + length;
11503 for (trace = start = buffer; trace != end; trace++) {
11504 if (!*trace) {
11505 int error;
11506 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11507 trace - start);
11508 if (!attribute) {
11509 Py_DECREF(result);
11510 result = NULL;
11511 goto exit;
11512 }
11513 error = PyList_Append(result, attribute);
11514 Py_DECREF(attribute);
11515 if (error) {
11516 Py_DECREF(result);
11517 result = NULL;
11518 goto exit;
11519 }
11520 start = trace + 1;
11521 }
11522 }
11523 break;
11524 }
11525exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011526 if (buffer)
11527 PyMem_FREE(buffer);
11528 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011529}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011530#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011531
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011532
Larry Hastings2f936352014-08-05 14:04:04 +100011533/*[clinic input]
11534os.urandom
11535
11536 size: Py_ssize_t
11537 /
11538
11539Return a bytes object containing random bytes suitable for cryptographic use.
11540[clinic start generated code]*/
11541
Larry Hastings2f936352014-08-05 14:04:04 +100011542static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011543os_urandom_impl(PyObject *module, Py_ssize_t size)
11544/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011545{
11546 PyObject *bytes;
11547 int result;
11548
Georg Brandl2fb477c2012-02-21 00:33:36 +010011549 if (size < 0)
11550 return PyErr_Format(PyExc_ValueError,
11551 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011552 bytes = PyBytes_FromStringAndSize(NULL, size);
11553 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011554 return NULL;
11555
Victor Stinnere66987e2016-09-06 16:33:52 -070011556 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011557 if (result == -1) {
11558 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011559 return NULL;
11560 }
Larry Hastings2f936352014-08-05 14:04:04 +100011561 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011562}
11563
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011564/* Terminal size querying */
11565
11566static PyTypeObject TerminalSizeType;
11567
11568PyDoc_STRVAR(TerminalSize_docstring,
11569 "A tuple of (columns, lines) for holding terminal window size");
11570
11571static PyStructSequence_Field TerminalSize_fields[] = {
11572 {"columns", "width of the terminal window in characters"},
11573 {"lines", "height of the terminal window in characters"},
11574 {NULL, NULL}
11575};
11576
11577static PyStructSequence_Desc TerminalSize_desc = {
11578 "os.terminal_size",
11579 TerminalSize_docstring,
11580 TerminalSize_fields,
11581 2,
11582};
11583
11584#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011585/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011586PyDoc_STRVAR(termsize__doc__,
11587 "Return the size of the terminal window as (columns, lines).\n" \
11588 "\n" \
11589 "The optional argument fd (default standard output) specifies\n" \
11590 "which file descriptor should be queried.\n" \
11591 "\n" \
11592 "If the file descriptor is not connected to a terminal, an OSError\n" \
11593 "is thrown.\n" \
11594 "\n" \
11595 "This function will only be defined if an implementation is\n" \
11596 "available for this system.\n" \
11597 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080011598 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011599 "normally be used, os.get_terminal_size is the low-level implementation.");
11600
11601static PyObject*
11602get_terminal_size(PyObject *self, PyObject *args)
11603{
11604 int columns, lines;
11605 PyObject *termsize;
11606
11607 int fd = fileno(stdout);
11608 /* Under some conditions stdout may not be connected and
11609 * fileno(stdout) may point to an invalid file descriptor. For example
11610 * GUI apps don't have valid standard streams by default.
11611 *
11612 * If this happens, and the optional fd argument is not present,
11613 * the ioctl below will fail returning EBADF. This is what we want.
11614 */
11615
11616 if (!PyArg_ParseTuple(args, "|i", &fd))
11617 return NULL;
11618
11619#ifdef TERMSIZE_USE_IOCTL
11620 {
11621 struct winsize w;
11622 if (ioctl(fd, TIOCGWINSZ, &w))
11623 return PyErr_SetFromErrno(PyExc_OSError);
11624 columns = w.ws_col;
11625 lines = w.ws_row;
11626 }
11627#endif /* TERMSIZE_USE_IOCTL */
11628
11629#ifdef TERMSIZE_USE_CONIO
11630 {
11631 DWORD nhandle;
11632 HANDLE handle;
11633 CONSOLE_SCREEN_BUFFER_INFO csbi;
11634 switch (fd) {
11635 case 0: nhandle = STD_INPUT_HANDLE;
11636 break;
11637 case 1: nhandle = STD_OUTPUT_HANDLE;
11638 break;
11639 case 2: nhandle = STD_ERROR_HANDLE;
11640 break;
11641 default:
11642 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11643 }
11644 handle = GetStdHandle(nhandle);
11645 if (handle == NULL)
11646 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11647 if (handle == INVALID_HANDLE_VALUE)
11648 return PyErr_SetFromWindowsErr(0);
11649
11650 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11651 return PyErr_SetFromWindowsErr(0);
11652
11653 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11654 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11655 }
11656#endif /* TERMSIZE_USE_CONIO */
11657
11658 termsize = PyStructSequence_New(&TerminalSizeType);
11659 if (termsize == NULL)
11660 return NULL;
11661 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11662 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11663 if (PyErr_Occurred()) {
11664 Py_DECREF(termsize);
11665 return NULL;
11666 }
11667 return termsize;
11668}
11669#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11670
Larry Hastings2f936352014-08-05 14:04:04 +100011671
11672/*[clinic input]
11673os.cpu_count
11674
Charles-François Natali80d62e62015-08-13 20:37:08 +010011675Return the number of CPUs in the system; return None if indeterminable.
11676
11677This number is not equivalent to the number of CPUs the current process can
11678use. The number of usable CPUs can be obtained with
11679``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011680[clinic start generated code]*/
11681
Larry Hastings2f936352014-08-05 14:04:04 +100011682static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011683os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011684/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011685{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011686 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011687#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011688 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11689 Need to fallback to Vista behavior if this call isn't present */
11690 HINSTANCE hKernel32;
11691 hKernel32 = GetModuleHandleW(L"KERNEL32");
11692
11693 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11694 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11695 "GetMaximumProcessorCount");
11696 if (_GetMaximumProcessorCount != NULL) {
11697 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11698 }
11699 else {
11700 SYSTEM_INFO sysinfo;
11701 GetSystemInfo(&sysinfo);
11702 ncpu = sysinfo.dwNumberOfProcessors;
11703 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011704#elif defined(__hpux)
11705 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11706#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11707 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011708#elif defined(__DragonFly__) || \
11709 defined(__OpenBSD__) || \
11710 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011711 defined(__NetBSD__) || \
11712 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011713 int mib[2];
11714 size_t len = sizeof(ncpu);
11715 mib[0] = CTL_HW;
11716 mib[1] = HW_NCPU;
11717 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11718 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011719#endif
11720 if (ncpu >= 1)
11721 return PyLong_FromLong(ncpu);
11722 else
11723 Py_RETURN_NONE;
11724}
11725
Victor Stinnerdaf45552013-08-28 00:53:59 +020011726
Larry Hastings2f936352014-08-05 14:04:04 +100011727/*[clinic input]
11728os.get_inheritable -> bool
11729
11730 fd: int
11731 /
11732
11733Get the close-on-exe flag of the specified file descriptor.
11734[clinic start generated code]*/
11735
Larry Hastings2f936352014-08-05 14:04:04 +100011736static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011737os_get_inheritable_impl(PyObject *module, int fd)
11738/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011739{
Steve Dower8fc89802015-04-12 00:26:27 -040011740 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011741 _Py_BEGIN_SUPPRESS_IPH
11742 return_value = _Py_get_inheritable(fd);
11743 _Py_END_SUPPRESS_IPH
11744 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011745}
11746
11747
11748/*[clinic input]
11749os.set_inheritable
11750 fd: int
11751 inheritable: int
11752 /
11753
11754Set the inheritable flag of the specified file descriptor.
11755[clinic start generated code]*/
11756
Larry Hastings2f936352014-08-05 14:04:04 +100011757static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011758os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11759/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011760{
Steve Dower8fc89802015-04-12 00:26:27 -040011761 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011762
Steve Dower8fc89802015-04-12 00:26:27 -040011763 _Py_BEGIN_SUPPRESS_IPH
11764 result = _Py_set_inheritable(fd, inheritable, NULL);
11765 _Py_END_SUPPRESS_IPH
11766 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011767 return NULL;
11768 Py_RETURN_NONE;
11769}
11770
11771
11772#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011773/*[clinic input]
11774os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011775 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011776 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011777
Larry Hastings2f936352014-08-05 14:04:04 +100011778Get the close-on-exe flag of the specified file descriptor.
11779[clinic start generated code]*/
11780
Larry Hastings2f936352014-08-05 14:04:04 +100011781static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011782os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011783/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011784{
11785 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011786
11787 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11788 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011789 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011790 }
11791
Larry Hastings2f936352014-08-05 14:04:04 +100011792 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011793}
11794
Victor Stinnerdaf45552013-08-28 00:53:59 +020011795
Larry Hastings2f936352014-08-05 14:04:04 +100011796/*[clinic input]
11797os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011798 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011799 inheritable: bool
11800 /
11801
11802Set the inheritable flag of the specified handle.
11803[clinic start generated code]*/
11804
Larry Hastings2f936352014-08-05 14:04:04 +100011805static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011806os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011807 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011808/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011809{
11810 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011811 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11812 PyErr_SetFromWindowsErr(0);
11813 return NULL;
11814 }
11815 Py_RETURN_NONE;
11816}
Larry Hastings2f936352014-08-05 14:04:04 +100011817#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011818
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011819#ifndef MS_WINDOWS
11820PyDoc_STRVAR(get_blocking__doc__,
11821 "get_blocking(fd) -> bool\n" \
11822 "\n" \
11823 "Get the blocking mode of the file descriptor:\n" \
11824 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11825
11826static PyObject*
11827posix_get_blocking(PyObject *self, PyObject *args)
11828{
11829 int fd;
11830 int blocking;
11831
11832 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11833 return NULL;
11834
Steve Dower8fc89802015-04-12 00:26:27 -040011835 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011836 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011837 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011838 if (blocking < 0)
11839 return NULL;
11840 return PyBool_FromLong(blocking);
11841}
11842
11843PyDoc_STRVAR(set_blocking__doc__,
11844 "set_blocking(fd, blocking)\n" \
11845 "\n" \
11846 "Set the blocking mode of the specified file descriptor.\n" \
11847 "Set the O_NONBLOCK flag if blocking is False,\n" \
11848 "clear the O_NONBLOCK flag otherwise.");
11849
11850static PyObject*
11851posix_set_blocking(PyObject *self, PyObject *args)
11852{
Steve Dower8fc89802015-04-12 00:26:27 -040011853 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011854
11855 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11856 return NULL;
11857
Steve Dower8fc89802015-04-12 00:26:27 -040011858 _Py_BEGIN_SUPPRESS_IPH
11859 result = _Py_set_blocking(fd, blocking);
11860 _Py_END_SUPPRESS_IPH
11861 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011862 return NULL;
11863 Py_RETURN_NONE;
11864}
11865#endif /* !MS_WINDOWS */
11866
11867
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011868/*[clinic input]
11869class os.DirEntry "DirEntry *" "&DirEntryType"
11870[clinic start generated code]*/
11871/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011872
11873typedef struct {
11874 PyObject_HEAD
11875 PyObject *name;
11876 PyObject *path;
11877 PyObject *stat;
11878 PyObject *lstat;
11879#ifdef MS_WINDOWS
11880 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011881 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011882 int got_file_index;
11883#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011884#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011885 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011886#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011887 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011888 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011889#endif
11890} DirEntry;
11891
11892static void
11893DirEntry_dealloc(DirEntry *entry)
11894{
11895 Py_XDECREF(entry->name);
11896 Py_XDECREF(entry->path);
11897 Py_XDECREF(entry->stat);
11898 Py_XDECREF(entry->lstat);
11899 Py_TYPE(entry)->tp_free((PyObject *)entry);
11900}
11901
11902/* Forward reference */
11903static int
11904DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11905
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011906/*[clinic input]
11907os.DirEntry.is_symlink -> bool
11908
11909Return True if the entry is a symbolic link; cached per entry.
11910[clinic start generated code]*/
11911
Victor Stinner6036e442015-03-08 01:58:04 +010011912static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011913os_DirEntry_is_symlink_impl(DirEntry *self)
11914/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011915{
11916#ifdef MS_WINDOWS
11917 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011918#elif defined(HAVE_DIRENT_D_TYPE)
11919 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011920 if (self->d_type != DT_UNKNOWN)
11921 return self->d_type == DT_LNK;
11922 else
11923 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011924#else
11925 /* POSIX without d_type */
11926 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011927#endif
11928}
11929
11930static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011931DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11932{
11933 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011934 STRUCT_STAT st;
11935 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011936
11937#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011938 if (!PyUnicode_FSDecoder(self->path, &ub))
11939 return NULL;
11940 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011941#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011942 if (!PyUnicode_FSConverter(self->path, &ub))
11943 return NULL;
11944 const char *path = PyBytes_AS_STRING(ub);
11945 if (self->dir_fd != DEFAULT_DIR_FD) {
11946#ifdef HAVE_FSTATAT
11947 result = fstatat(self->dir_fd, path, &st,
11948 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11949#else
11950 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11951 return NULL;
11952#endif /* HAVE_FSTATAT */
11953 }
11954 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011955#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011956 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011957 if (follow_symlinks)
11958 result = STAT(path, &st);
11959 else
11960 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011961 }
11962 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011963
11964 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011965 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011966
11967 return _pystat_fromstructstat(&st);
11968}
11969
11970static PyObject *
11971DirEntry_get_lstat(DirEntry *self)
11972{
11973 if (!self->lstat) {
11974#ifdef MS_WINDOWS
11975 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11976#else /* POSIX */
11977 self->lstat = DirEntry_fetch_stat(self, 0);
11978#endif
11979 }
11980 Py_XINCREF(self->lstat);
11981 return self->lstat;
11982}
11983
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011984/*[clinic input]
11985os.DirEntry.stat
11986 *
11987 follow_symlinks: bool = True
11988
11989Return stat_result object for the entry; cached per entry.
11990[clinic start generated code]*/
11991
Victor Stinner6036e442015-03-08 01:58:04 +010011992static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011993os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11994/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011995{
11996 if (!follow_symlinks)
11997 return DirEntry_get_lstat(self);
11998
11999 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012000 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012001 if (result == -1)
12002 return NULL;
12003 else if (result)
12004 self->stat = DirEntry_fetch_stat(self, 1);
12005 else
12006 self->stat = DirEntry_get_lstat(self);
12007 }
12008
12009 Py_XINCREF(self->stat);
12010 return self->stat;
12011}
12012
Victor Stinner6036e442015-03-08 01:58:04 +010012013/* Set exception and return -1 on error, 0 for False, 1 for True */
12014static int
12015DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12016{
12017 PyObject *stat = NULL;
12018 PyObject *st_mode = NULL;
12019 long mode;
12020 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012021#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012022 int is_symlink;
12023 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012024#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012025#ifdef MS_WINDOWS
12026 unsigned long dir_bits;
12027#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012028 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012029
12030#ifdef MS_WINDOWS
12031 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12032 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012033#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012034 is_symlink = self->d_type == DT_LNK;
12035 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12036#endif
12037
Victor Stinner35a97c02015-03-08 02:59:09 +010012038#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012039 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012040#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012041 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012042 if (!stat) {
12043 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12044 /* If file doesn't exist (anymore), then return False
12045 (i.e., say it's not a file/directory) */
12046 PyErr_Clear();
12047 return 0;
12048 }
12049 goto error;
12050 }
12051 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12052 if (!st_mode)
12053 goto error;
12054
12055 mode = PyLong_AsLong(st_mode);
12056 if (mode == -1 && PyErr_Occurred())
12057 goto error;
12058 Py_CLEAR(st_mode);
12059 Py_CLEAR(stat);
12060 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012061#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012062 }
12063 else if (is_symlink) {
12064 assert(mode_bits != S_IFLNK);
12065 result = 0;
12066 }
12067 else {
12068 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12069#ifdef MS_WINDOWS
12070 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12071 if (mode_bits == S_IFDIR)
12072 result = dir_bits != 0;
12073 else
12074 result = dir_bits == 0;
12075#else /* POSIX */
12076 if (mode_bits == S_IFDIR)
12077 result = self->d_type == DT_DIR;
12078 else
12079 result = self->d_type == DT_REG;
12080#endif
12081 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012082#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012083
12084 return result;
12085
12086error:
12087 Py_XDECREF(st_mode);
12088 Py_XDECREF(stat);
12089 return -1;
12090}
12091
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012092/*[clinic input]
12093os.DirEntry.is_dir -> bool
12094 *
12095 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012096
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012097Return True if the entry is a directory; cached per entry.
12098[clinic start generated code]*/
12099
12100static int
12101os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12102/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12103{
12104 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012105}
12106
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012107/*[clinic input]
12108os.DirEntry.is_file -> bool
12109 *
12110 follow_symlinks: bool = True
12111
12112Return True if the entry is a file; cached per entry.
12113[clinic start generated code]*/
12114
12115static int
12116os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12117/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012118{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012119 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012120}
12121
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012122/*[clinic input]
12123os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012124
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012125Return inode of the entry; cached per entry.
12126[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012127
12128static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012129os_DirEntry_inode_impl(DirEntry *self)
12130/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012131{
12132#ifdef MS_WINDOWS
12133 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012134 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012135 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012136 STRUCT_STAT stat;
12137 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012138
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012139 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012140 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012141 path = PyUnicode_AsUnicode(unicode);
12142 result = LSTAT(path, &stat);
12143 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012144
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012145 if (result != 0)
12146 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012147
12148 self->win32_file_index = stat.st_ino;
12149 self->got_file_index = 1;
12150 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012151 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12152 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012153#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012154 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12155 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012156#endif
12157}
12158
12159static PyObject *
12160DirEntry_repr(DirEntry *self)
12161{
12162 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12163}
12164
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012165/*[clinic input]
12166os.DirEntry.__fspath__
12167
12168Returns the path for the entry.
12169[clinic start generated code]*/
12170
Brett Cannon96881cd2016-06-10 14:37:21 -070012171static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012172os_DirEntry___fspath___impl(DirEntry *self)
12173/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012174{
12175 Py_INCREF(self->path);
12176 return self->path;
12177}
12178
Victor Stinner6036e442015-03-08 01:58:04 +010012179static PyMemberDef DirEntry_members[] = {
12180 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12181 "the entry's base filename, relative to scandir() \"path\" argument"},
12182 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12183 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12184 {NULL}
12185};
12186
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012187#include "clinic/posixmodule.c.h"
12188
Victor Stinner6036e442015-03-08 01:58:04 +010012189static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012190 OS_DIRENTRY_IS_DIR_METHODDEF
12191 OS_DIRENTRY_IS_FILE_METHODDEF
12192 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12193 OS_DIRENTRY_STAT_METHODDEF
12194 OS_DIRENTRY_INODE_METHODDEF
12195 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012196 {NULL}
12197};
12198
Benjamin Peterson5646de42015-04-12 17:56:34 -040012199static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012200 PyVarObject_HEAD_INIT(NULL, 0)
12201 MODNAME ".DirEntry", /* tp_name */
12202 sizeof(DirEntry), /* tp_basicsize */
12203 0, /* tp_itemsize */
12204 /* methods */
12205 (destructor)DirEntry_dealloc, /* tp_dealloc */
12206 0, /* tp_print */
12207 0, /* tp_getattr */
12208 0, /* tp_setattr */
12209 0, /* tp_compare */
12210 (reprfunc)DirEntry_repr, /* tp_repr */
12211 0, /* tp_as_number */
12212 0, /* tp_as_sequence */
12213 0, /* tp_as_mapping */
12214 0, /* tp_hash */
12215 0, /* tp_call */
12216 0, /* tp_str */
12217 0, /* tp_getattro */
12218 0, /* tp_setattro */
12219 0, /* tp_as_buffer */
12220 Py_TPFLAGS_DEFAULT, /* tp_flags */
12221 0, /* tp_doc */
12222 0, /* tp_traverse */
12223 0, /* tp_clear */
12224 0, /* tp_richcompare */
12225 0, /* tp_weaklistoffset */
12226 0, /* tp_iter */
12227 0, /* tp_iternext */
12228 DirEntry_methods, /* tp_methods */
12229 DirEntry_members, /* tp_members */
12230};
12231
12232#ifdef MS_WINDOWS
12233
12234static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012235join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012236{
12237 Py_ssize_t path_len;
12238 Py_ssize_t size;
12239 wchar_t *result;
12240 wchar_t ch;
12241
12242 if (!path_wide) { /* Default arg: "." */
12243 path_wide = L".";
12244 path_len = 1;
12245 }
12246 else {
12247 path_len = wcslen(path_wide);
12248 }
12249
12250 /* The +1's are for the path separator and the NUL */
12251 size = path_len + 1 + wcslen(filename) + 1;
12252 result = PyMem_New(wchar_t, size);
12253 if (!result) {
12254 PyErr_NoMemory();
12255 return NULL;
12256 }
12257 wcscpy(result, path_wide);
12258 if (path_len > 0) {
12259 ch = result[path_len - 1];
12260 if (ch != SEP && ch != ALTSEP && ch != L':')
12261 result[path_len++] = SEP;
12262 wcscpy(result + path_len, filename);
12263 }
12264 return result;
12265}
12266
12267static PyObject *
12268DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12269{
12270 DirEntry *entry;
12271 BY_HANDLE_FILE_INFORMATION file_info;
12272 ULONG reparse_tag;
12273 wchar_t *joined_path;
12274
12275 entry = PyObject_New(DirEntry, &DirEntryType);
12276 if (!entry)
12277 return NULL;
12278 entry->name = NULL;
12279 entry->path = NULL;
12280 entry->stat = NULL;
12281 entry->lstat = NULL;
12282 entry->got_file_index = 0;
12283
12284 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12285 if (!entry->name)
12286 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012287 if (path->narrow) {
12288 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12289 if (!entry->name)
12290 goto error;
12291 }
Victor Stinner6036e442015-03-08 01:58:04 +010012292
12293 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12294 if (!joined_path)
12295 goto error;
12296
12297 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12298 PyMem_Free(joined_path);
12299 if (!entry->path)
12300 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012301 if (path->narrow) {
12302 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12303 if (!entry->path)
12304 goto error;
12305 }
Victor Stinner6036e442015-03-08 01:58:04 +010012306
Steve Dowercc16be82016-09-08 10:35:16 -070012307 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012308 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12309
12310 return (PyObject *)entry;
12311
12312error:
12313 Py_DECREF(entry);
12314 return NULL;
12315}
12316
12317#else /* POSIX */
12318
12319static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012320join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012321{
12322 Py_ssize_t path_len;
12323 Py_ssize_t size;
12324 char *result;
12325
12326 if (!path_narrow) { /* Default arg: "." */
12327 path_narrow = ".";
12328 path_len = 1;
12329 }
12330 else {
12331 path_len = strlen(path_narrow);
12332 }
12333
12334 if (filename_len == -1)
12335 filename_len = strlen(filename);
12336
12337 /* The +1's are for the path separator and the NUL */
12338 size = path_len + 1 + filename_len + 1;
12339 result = PyMem_New(char, size);
12340 if (!result) {
12341 PyErr_NoMemory();
12342 return NULL;
12343 }
12344 strcpy(result, path_narrow);
12345 if (path_len > 0 && result[path_len - 1] != '/')
12346 result[path_len++] = '/';
12347 strcpy(result + path_len, filename);
12348 return result;
12349}
12350
12351static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012352DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012353 ino_t d_ino
12354#ifdef HAVE_DIRENT_D_TYPE
12355 , unsigned char d_type
12356#endif
12357 )
Victor Stinner6036e442015-03-08 01:58:04 +010012358{
12359 DirEntry *entry;
12360 char *joined_path;
12361
12362 entry = PyObject_New(DirEntry, &DirEntryType);
12363 if (!entry)
12364 return NULL;
12365 entry->name = NULL;
12366 entry->path = NULL;
12367 entry->stat = NULL;
12368 entry->lstat = NULL;
12369
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012370 if (path->fd != -1) {
12371 entry->dir_fd = path->fd;
12372 joined_path = NULL;
12373 }
12374 else {
12375 entry->dir_fd = DEFAULT_DIR_FD;
12376 joined_path = join_path_filename(path->narrow, name, name_len);
12377 if (!joined_path)
12378 goto error;
12379 }
Victor Stinner6036e442015-03-08 01:58:04 +010012380
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012381 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012382 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012383 if (joined_path)
12384 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012385 }
12386 else {
12387 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012388 if (joined_path)
12389 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012390 }
12391 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012392 if (!entry->name)
12393 goto error;
12394
12395 if (path->fd != -1) {
12396 entry->path = entry->name;
12397 Py_INCREF(entry->path);
12398 }
12399 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012400 goto error;
12401
Victor Stinner35a97c02015-03-08 02:59:09 +010012402#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012403 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012404#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012405 entry->d_ino = d_ino;
12406
12407 return (PyObject *)entry;
12408
12409error:
12410 Py_XDECREF(entry);
12411 return NULL;
12412}
12413
12414#endif
12415
12416
12417typedef struct {
12418 PyObject_HEAD
12419 path_t path;
12420#ifdef MS_WINDOWS
12421 HANDLE handle;
12422 WIN32_FIND_DATAW file_data;
12423 int first_time;
12424#else /* POSIX */
12425 DIR *dirp;
12426#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012427#ifdef HAVE_FDOPENDIR
12428 int fd;
12429#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012430} ScandirIterator;
12431
12432#ifdef MS_WINDOWS
12433
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012434static int
12435ScandirIterator_is_closed(ScandirIterator *iterator)
12436{
12437 return iterator->handle == INVALID_HANDLE_VALUE;
12438}
12439
Victor Stinner6036e442015-03-08 01:58:04 +010012440static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012441ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012442{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012443 HANDLE handle = iterator->handle;
12444
12445 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012446 return;
12447
Victor Stinner6036e442015-03-08 01:58:04 +010012448 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012449 Py_BEGIN_ALLOW_THREADS
12450 FindClose(handle);
12451 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012452}
12453
12454static PyObject *
12455ScandirIterator_iternext(ScandirIterator *iterator)
12456{
12457 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12458 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012459 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012460
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012461 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012462 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012463 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012464
12465 while (1) {
12466 if (!iterator->first_time) {
12467 Py_BEGIN_ALLOW_THREADS
12468 success = FindNextFileW(iterator->handle, file_data);
12469 Py_END_ALLOW_THREADS
12470 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012471 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012472 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012473 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012474 break;
12475 }
12476 }
12477 iterator->first_time = 0;
12478
12479 /* Skip over . and .. */
12480 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012481 wcscmp(file_data->cFileName, L"..") != 0) {
12482 entry = DirEntry_from_find_data(&iterator->path, file_data);
12483 if (!entry)
12484 break;
12485 return entry;
12486 }
Victor Stinner6036e442015-03-08 01:58:04 +010012487
12488 /* Loop till we get a non-dot directory or finish iterating */
12489 }
12490
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012491 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012492 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012493 return NULL;
12494}
12495
12496#else /* POSIX */
12497
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012498static int
12499ScandirIterator_is_closed(ScandirIterator *iterator)
12500{
12501 return !iterator->dirp;
12502}
12503
Victor Stinner6036e442015-03-08 01:58:04 +010012504static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012505ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012506{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012507 DIR *dirp = iterator->dirp;
12508
12509 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012510 return;
12511
Victor Stinner6036e442015-03-08 01:58:04 +010012512 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012513 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012514#ifdef HAVE_FDOPENDIR
12515 if (iterator->path.fd != -1)
12516 rewinddir(dirp);
12517#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012518 closedir(dirp);
12519 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012520 return;
12521}
12522
12523static PyObject *
12524ScandirIterator_iternext(ScandirIterator *iterator)
12525{
12526 struct dirent *direntp;
12527 Py_ssize_t name_len;
12528 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012529 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012530
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012531 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012532 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012533 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012534
12535 while (1) {
12536 errno = 0;
12537 Py_BEGIN_ALLOW_THREADS
12538 direntp = readdir(iterator->dirp);
12539 Py_END_ALLOW_THREADS
12540
12541 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012542 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012543 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012544 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012545 break;
12546 }
12547
12548 /* Skip over . and .. */
12549 name_len = NAMLEN(direntp);
12550 is_dot = direntp->d_name[0] == '.' &&
12551 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12552 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012553 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012554 name_len, direntp->d_ino
12555#ifdef HAVE_DIRENT_D_TYPE
12556 , direntp->d_type
12557#endif
12558 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012559 if (!entry)
12560 break;
12561 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012562 }
12563
12564 /* Loop till we get a non-dot directory or finish iterating */
12565 }
12566
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012567 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012568 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012569 return NULL;
12570}
12571
12572#endif
12573
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012574static PyObject *
12575ScandirIterator_close(ScandirIterator *self, PyObject *args)
12576{
12577 ScandirIterator_closedir(self);
12578 Py_RETURN_NONE;
12579}
12580
12581static PyObject *
12582ScandirIterator_enter(PyObject *self, PyObject *args)
12583{
12584 Py_INCREF(self);
12585 return self;
12586}
12587
12588static PyObject *
12589ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12590{
12591 ScandirIterator_closedir(self);
12592 Py_RETURN_NONE;
12593}
12594
Victor Stinner6036e442015-03-08 01:58:04 +010012595static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012596ScandirIterator_finalize(ScandirIterator *iterator)
12597{
12598 PyObject *error_type, *error_value, *error_traceback;
12599
12600 /* Save the current exception, if any. */
12601 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12602
12603 if (!ScandirIterator_is_closed(iterator)) {
12604 ScandirIterator_closedir(iterator);
12605
12606 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12607 "unclosed scandir iterator %R", iterator)) {
12608 /* Spurious errors can appear at shutdown */
12609 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12610 PyErr_WriteUnraisable((PyObject *) iterator);
12611 }
12612 }
12613 }
12614
Victor Stinner7bfa4092016-03-23 00:43:54 +010012615 path_cleanup(&iterator->path);
12616
12617 /* Restore the saved exception. */
12618 PyErr_Restore(error_type, error_value, error_traceback);
12619}
12620
12621static void
Victor Stinner6036e442015-03-08 01:58:04 +010012622ScandirIterator_dealloc(ScandirIterator *iterator)
12623{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012624 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12625 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012626
Victor Stinner6036e442015-03-08 01:58:04 +010012627 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12628}
12629
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012630static PyMethodDef ScandirIterator_methods[] = {
12631 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12632 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12633 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12634 {NULL}
12635};
12636
Benjamin Peterson5646de42015-04-12 17:56:34 -040012637static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012638 PyVarObject_HEAD_INIT(NULL, 0)
12639 MODNAME ".ScandirIterator", /* tp_name */
12640 sizeof(ScandirIterator), /* tp_basicsize */
12641 0, /* tp_itemsize */
12642 /* methods */
12643 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12644 0, /* tp_print */
12645 0, /* tp_getattr */
12646 0, /* tp_setattr */
12647 0, /* tp_compare */
12648 0, /* tp_repr */
12649 0, /* tp_as_number */
12650 0, /* tp_as_sequence */
12651 0, /* tp_as_mapping */
12652 0, /* tp_hash */
12653 0, /* tp_call */
12654 0, /* tp_str */
12655 0, /* tp_getattro */
12656 0, /* tp_setattro */
12657 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012658 Py_TPFLAGS_DEFAULT
12659 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012660 0, /* tp_doc */
12661 0, /* tp_traverse */
12662 0, /* tp_clear */
12663 0, /* tp_richcompare */
12664 0, /* tp_weaklistoffset */
12665 PyObject_SelfIter, /* tp_iter */
12666 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012667 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012668 0, /* tp_members */
12669 0, /* tp_getset */
12670 0, /* tp_base */
12671 0, /* tp_dict */
12672 0, /* tp_descr_get */
12673 0, /* tp_descr_set */
12674 0, /* tp_dictoffset */
12675 0, /* tp_init */
12676 0, /* tp_alloc */
12677 0, /* tp_new */
12678 0, /* tp_free */
12679 0, /* tp_is_gc */
12680 0, /* tp_bases */
12681 0, /* tp_mro */
12682 0, /* tp_cache */
12683 0, /* tp_subclasses */
12684 0, /* tp_weaklist */
12685 0, /* tp_del */
12686 0, /* tp_version_tag */
12687 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012688};
12689
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012690/*[clinic input]
12691os.scandir
12692
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012693 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012694
12695Return an iterator of DirEntry objects for given path.
12696
12697path can be specified as either str, bytes or path-like object. If path
12698is bytes, the names of yielded DirEntry objects will also be bytes; in
12699all other circumstances they will be str.
12700
12701If path is None, uses the path='.'.
12702[clinic start generated code]*/
12703
Victor Stinner6036e442015-03-08 01:58:04 +010012704static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012705os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012706/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012707{
12708 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012709#ifdef MS_WINDOWS
12710 wchar_t *path_strW;
12711#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012712 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012713#ifdef HAVE_FDOPENDIR
12714 int fd = -1;
12715#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012716#endif
12717
12718 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12719 if (!iterator)
12720 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012721
12722#ifdef MS_WINDOWS
12723 iterator->handle = INVALID_HANDLE_VALUE;
12724#else
12725 iterator->dirp = NULL;
12726#endif
12727
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012728 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012729 /* Move the ownership to iterator->path */
12730 path->object = NULL;
12731 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012732
12733#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012734 iterator->first_time = 1;
12735
12736 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12737 if (!path_strW)
12738 goto error;
12739
12740 Py_BEGIN_ALLOW_THREADS
12741 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12742 Py_END_ALLOW_THREADS
12743
12744 PyMem_Free(path_strW);
12745
12746 if (iterator->handle == INVALID_HANDLE_VALUE) {
12747 path_error(&iterator->path);
12748 goto error;
12749 }
12750#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012751 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012752#ifdef HAVE_FDOPENDIR
12753 if (path->fd != -1) {
12754 /* closedir() closes the FD, so we duplicate it */
12755 fd = _Py_dup(path->fd);
12756 if (fd == -1)
12757 goto error;
12758
12759 Py_BEGIN_ALLOW_THREADS
12760 iterator->dirp = fdopendir(fd);
12761 Py_END_ALLOW_THREADS
12762 }
12763 else
12764#endif
12765 {
12766 if (iterator->path.narrow)
12767 path_str = iterator->path.narrow;
12768 else
12769 path_str = ".";
12770
12771 Py_BEGIN_ALLOW_THREADS
12772 iterator->dirp = opendir(path_str);
12773 Py_END_ALLOW_THREADS
12774 }
Victor Stinner6036e442015-03-08 01:58:04 +010012775
12776 if (!iterator->dirp) {
12777 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012778#ifdef HAVE_FDOPENDIR
12779 if (fd != -1) {
12780 Py_BEGIN_ALLOW_THREADS
12781 close(fd);
12782 Py_END_ALLOW_THREADS
12783 }
12784#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012785 goto error;
12786 }
12787#endif
12788
12789 return (PyObject *)iterator;
12790
12791error:
12792 Py_DECREF(iterator);
12793 return NULL;
12794}
12795
Ethan Furman410ef8e2016-06-04 12:06:26 -070012796/*
12797 Return the file system path representation of the object.
12798
12799 If the object is str or bytes, then allow it to pass through with
12800 an incremented refcount. If the object defines __fspath__(), then
12801 return the result of that method. All other types raise a TypeError.
12802*/
12803PyObject *
12804PyOS_FSPath(PyObject *path)
12805{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012806 /* For error message reasons, this function is manually inlined in
12807 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012808 _Py_IDENTIFIER(__fspath__);
12809 PyObject *func = NULL;
12810 PyObject *path_repr = NULL;
12811
12812 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12813 Py_INCREF(path);
12814 return path;
12815 }
12816
12817 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12818 if (NULL == func) {
12819 return PyErr_Format(PyExc_TypeError,
12820 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012821 "not %.200s",
12822 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012823 }
12824
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012825 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012826 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012827 if (NULL == path_repr) {
12828 return NULL;
12829 }
12830
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012831 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12832 PyErr_Format(PyExc_TypeError,
12833 "expected %.200s.__fspath__() to return str or bytes, "
12834 "not %.200s", Py_TYPE(path)->tp_name,
12835 Py_TYPE(path_repr)->tp_name);
12836 Py_DECREF(path_repr);
12837 return NULL;
12838 }
12839
Ethan Furman410ef8e2016-06-04 12:06:26 -070012840 return path_repr;
12841}
12842
12843/*[clinic input]
12844os.fspath
12845
12846 path: object
12847
12848Return the file system path representation of the object.
12849
Brett Cannonb4f43e92016-06-09 14:32:08 -070012850If the object is str or bytes, then allow it to pass through as-is. If the
12851object defines __fspath__(), then return the result of that method. All other
12852types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012853[clinic start generated code]*/
12854
12855static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012856os_fspath_impl(PyObject *module, PyObject *path)
12857/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012858{
12859 return PyOS_FSPath(path);
12860}
Victor Stinner6036e442015-03-08 01:58:04 +010012861
Victor Stinner9b1f4742016-09-06 16:18:52 -070012862#ifdef HAVE_GETRANDOM_SYSCALL
12863/*[clinic input]
12864os.getrandom
12865
12866 size: Py_ssize_t
12867 flags: int=0
12868
12869Obtain a series of random bytes.
12870[clinic start generated code]*/
12871
12872static PyObject *
12873os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12874/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12875{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012876 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012877 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012878
12879 if (size < 0) {
12880 errno = EINVAL;
12881 return posix_error();
12882 }
12883
Victor Stinnerec2319c2016-09-20 23:00:59 +020012884 bytes = PyBytes_FromStringAndSize(NULL, size);
12885 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012886 PyErr_NoMemory();
12887 return NULL;
12888 }
12889
12890 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012891 n = syscall(SYS_getrandom,
12892 PyBytes_AS_STRING(bytes),
12893 PyBytes_GET_SIZE(bytes),
12894 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012895 if (n < 0 && errno == EINTR) {
12896 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012897 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012898 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012899
12900 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012901 continue;
12902 }
12903 break;
12904 }
12905
12906 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012907 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012908 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012909 }
12910
Victor Stinnerec2319c2016-09-20 23:00:59 +020012911 if (n != size) {
12912 _PyBytes_Resize(&bytes, n);
12913 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012914
12915 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012916
12917error:
12918 Py_DECREF(bytes);
12919 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012920}
12921#endif /* HAVE_GETRANDOM_SYSCALL */
12922
Larry Hastings31826802013-10-19 00:09:25 -070012923
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012924static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012925
12926 OS_STAT_METHODDEF
12927 OS_ACCESS_METHODDEF
12928 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012929 OS_CHDIR_METHODDEF
12930 OS_CHFLAGS_METHODDEF
12931 OS_CHMOD_METHODDEF
12932 OS_FCHMOD_METHODDEF
12933 OS_LCHMOD_METHODDEF
12934 OS_CHOWN_METHODDEF
12935 OS_FCHOWN_METHODDEF
12936 OS_LCHOWN_METHODDEF
12937 OS_LCHFLAGS_METHODDEF
12938 OS_CHROOT_METHODDEF
12939 OS_CTERMID_METHODDEF
12940 OS_GETCWD_METHODDEF
12941 OS_GETCWDB_METHODDEF
12942 OS_LINK_METHODDEF
12943 OS_LISTDIR_METHODDEF
12944 OS_LSTAT_METHODDEF
12945 OS_MKDIR_METHODDEF
12946 OS_NICE_METHODDEF
12947 OS_GETPRIORITY_METHODDEF
12948 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000012949 OS_POSIX_SPAWN_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012950#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012951 {"readlink", (PyCFunction)posix_readlink,
12952 METH_VARARGS | METH_KEYWORDS,
12953 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012954#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012955#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012956 {"readlink", (PyCFunction)win_readlink,
12957 METH_VARARGS | METH_KEYWORDS,
12958 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012959#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012960 OS_RENAME_METHODDEF
12961 OS_REPLACE_METHODDEF
12962 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012963 OS_SYMLINK_METHODDEF
12964 OS_SYSTEM_METHODDEF
12965 OS_UMASK_METHODDEF
12966 OS_UNAME_METHODDEF
12967 OS_UNLINK_METHODDEF
12968 OS_REMOVE_METHODDEF
12969 OS_UTIME_METHODDEF
12970 OS_TIMES_METHODDEF
12971 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020012972 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012973 OS_EXECV_METHODDEF
12974 OS_EXECVE_METHODDEF
12975 OS_SPAWNV_METHODDEF
12976 OS_SPAWNVE_METHODDEF
12977 OS_FORK1_METHODDEF
12978 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012979 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012980 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12981 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12982 OS_SCHED_GETPARAM_METHODDEF
12983 OS_SCHED_GETSCHEDULER_METHODDEF
12984 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12985 OS_SCHED_SETPARAM_METHODDEF
12986 OS_SCHED_SETSCHEDULER_METHODDEF
12987 OS_SCHED_YIELD_METHODDEF
12988 OS_SCHED_SETAFFINITY_METHODDEF
12989 OS_SCHED_GETAFFINITY_METHODDEF
12990 OS_OPENPTY_METHODDEF
12991 OS_FORKPTY_METHODDEF
12992 OS_GETEGID_METHODDEF
12993 OS_GETEUID_METHODDEF
12994 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012995#ifdef HAVE_GETGROUPLIST
12996 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12997#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012998 OS_GETGROUPS_METHODDEF
12999 OS_GETPID_METHODDEF
13000 OS_GETPGRP_METHODDEF
13001 OS_GETPPID_METHODDEF
13002 OS_GETUID_METHODDEF
13003 OS_GETLOGIN_METHODDEF
13004 OS_KILL_METHODDEF
13005 OS_KILLPG_METHODDEF
13006 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013007#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013008 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013009#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013010 OS_SETUID_METHODDEF
13011 OS_SETEUID_METHODDEF
13012 OS_SETREUID_METHODDEF
13013 OS_SETGID_METHODDEF
13014 OS_SETEGID_METHODDEF
13015 OS_SETREGID_METHODDEF
13016 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013017#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013018 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013019#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013020 OS_GETPGID_METHODDEF
13021 OS_SETPGRP_METHODDEF
13022 OS_WAIT_METHODDEF
13023 OS_WAIT3_METHODDEF
13024 OS_WAIT4_METHODDEF
13025 OS_WAITID_METHODDEF
13026 OS_WAITPID_METHODDEF
13027 OS_GETSID_METHODDEF
13028 OS_SETSID_METHODDEF
13029 OS_SETPGID_METHODDEF
13030 OS_TCGETPGRP_METHODDEF
13031 OS_TCSETPGRP_METHODDEF
13032 OS_OPEN_METHODDEF
13033 OS_CLOSE_METHODDEF
13034 OS_CLOSERANGE_METHODDEF
13035 OS_DEVICE_ENCODING_METHODDEF
13036 OS_DUP_METHODDEF
13037 OS_DUP2_METHODDEF
13038 OS_LOCKF_METHODDEF
13039 OS_LSEEK_METHODDEF
13040 OS_READ_METHODDEF
13041 OS_READV_METHODDEF
13042 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013043 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013044 OS_WRITE_METHODDEF
13045 OS_WRITEV_METHODDEF
13046 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013047 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013048#ifdef HAVE_SENDFILE
13049 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
13050 posix_sendfile__doc__},
13051#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013052 OS_FSTAT_METHODDEF
13053 OS_ISATTY_METHODDEF
13054 OS_PIPE_METHODDEF
13055 OS_PIPE2_METHODDEF
13056 OS_MKFIFO_METHODDEF
13057 OS_MKNOD_METHODDEF
13058 OS_MAJOR_METHODDEF
13059 OS_MINOR_METHODDEF
13060 OS_MAKEDEV_METHODDEF
13061 OS_FTRUNCATE_METHODDEF
13062 OS_TRUNCATE_METHODDEF
13063 OS_POSIX_FALLOCATE_METHODDEF
13064 OS_POSIX_FADVISE_METHODDEF
13065 OS_PUTENV_METHODDEF
13066 OS_UNSETENV_METHODDEF
13067 OS_STRERROR_METHODDEF
13068 OS_FCHDIR_METHODDEF
13069 OS_FSYNC_METHODDEF
13070 OS_SYNC_METHODDEF
13071 OS_FDATASYNC_METHODDEF
13072 OS_WCOREDUMP_METHODDEF
13073 OS_WIFCONTINUED_METHODDEF
13074 OS_WIFSTOPPED_METHODDEF
13075 OS_WIFSIGNALED_METHODDEF
13076 OS_WIFEXITED_METHODDEF
13077 OS_WEXITSTATUS_METHODDEF
13078 OS_WTERMSIG_METHODDEF
13079 OS_WSTOPSIG_METHODDEF
13080 OS_FSTATVFS_METHODDEF
13081 OS_STATVFS_METHODDEF
13082 OS_CONFSTR_METHODDEF
13083 OS_SYSCONF_METHODDEF
13084 OS_FPATHCONF_METHODDEF
13085 OS_PATHCONF_METHODDEF
13086 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013087 OS__GETFULLPATHNAME_METHODDEF
13088 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013089 OS__GETDISKUSAGE_METHODDEF
13090 OS__GETFINALPATHNAME_METHODDEF
13091 OS__GETVOLUMEPATHNAME_METHODDEF
13092 OS_GETLOADAVG_METHODDEF
13093 OS_URANDOM_METHODDEF
13094 OS_SETRESUID_METHODDEF
13095 OS_SETRESGID_METHODDEF
13096 OS_GETRESUID_METHODDEF
13097 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013098
Larry Hastings2f936352014-08-05 14:04:04 +100013099 OS_GETXATTR_METHODDEF
13100 OS_SETXATTR_METHODDEF
13101 OS_REMOVEXATTR_METHODDEF
13102 OS_LISTXATTR_METHODDEF
13103
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013104#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13105 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13106#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013107 OS_CPU_COUNT_METHODDEF
13108 OS_GET_INHERITABLE_METHODDEF
13109 OS_SET_INHERITABLE_METHODDEF
13110 OS_GET_HANDLE_INHERITABLE_METHODDEF
13111 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013112#ifndef MS_WINDOWS
13113 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
13114 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
13115#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013116 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013117 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013118 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000013119 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013120};
13121
13122
Brian Curtin52173d42010-12-02 18:29:18 +000013123#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013124static int
Brian Curtin52173d42010-12-02 18:29:18 +000013125enable_symlink()
13126{
13127 HANDLE tok;
13128 TOKEN_PRIVILEGES tok_priv;
13129 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000013130
13131 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013132 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013133
13134 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013135 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013136
13137 tok_priv.PrivilegeCount = 1;
13138 tok_priv.Privileges[0].Luid = luid;
13139 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
13140
13141 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
13142 sizeof(TOKEN_PRIVILEGES),
13143 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013144 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013145
Brian Curtin3b4499c2010-12-28 14:31:47 +000013146 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
13147 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000013148}
13149#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
13150
Barry Warsaw4a342091996-12-19 23:50:02 +000013151static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013152all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013153{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013154#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013155 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013156#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013157#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013158 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013159#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013160#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013161 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013162#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013163#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013164 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013165#endif
Fred Drakec9680921999-12-13 16:37:25 +000013166#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013167 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013168#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013169#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013170 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013171#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013172#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013173 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013174#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013175#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013176 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013177#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013178#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013179 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013180#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013181#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013182 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013183#endif
13184#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013185 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013186#endif
13187#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013188 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013189#endif
13190#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013191 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013192#endif
13193#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013194 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013195#endif
13196#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013197 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013198#endif
13199#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013200 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013201#endif
13202#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013203 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013204#endif
13205#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013206 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013207#endif
13208#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013209 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013210#endif
13211#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013212 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013213#endif
13214#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013215 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013216#endif
13217#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013218 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013219#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013220#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013221 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013222#endif
13223#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013224 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013225#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013226#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013227 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013228#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013229#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013230 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013231#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013232#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013233#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013234 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013235#endif
13236#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013237 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013238#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013239#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013240#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013241 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013242#endif
13243#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013244 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013245#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013246#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013247 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013248#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013249#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013250 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013251#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013252#ifdef O_TMPFILE
13253 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13254#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013255#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013256 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013257#endif
13258#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013259 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013260#endif
13261#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013262 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013263#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013264#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013265 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013266#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013267#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013268 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013269#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013270
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013271
Jesus Cea94363612012-06-22 18:32:07 +020013272#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013273 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013274#endif
13275#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013276 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013277#endif
13278
Tim Peters5aa91602002-01-30 05:46:57 +000013279/* MS Windows */
13280#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013281 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013282 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013283#endif
13284#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013285 /* Optimize for short life (keep in memory). */
13286 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013287 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013288#endif
13289#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013290 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013291 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013292#endif
13293#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013294 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013295 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013296#endif
13297#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013298 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013299 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013300#endif
13301
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013302/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013303#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013304 /* Send a SIGIO signal whenever input or output
13305 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013306 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013307#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013308#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013309 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013310 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013311#endif
13312#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013313 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013314 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013315#endif
13316#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013317 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013318 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013319#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013320#ifdef O_NOLINKS
13321 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013322 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013323#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013324#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013325 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013326 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013327#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013328
Victor Stinner8c62be82010-05-06 00:08:46 +000013329 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013330#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013331 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013332#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013333#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013334 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013335#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013336#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013337 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013338#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013339#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013340 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013341#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013342#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013343 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013344#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013345#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013346 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013347#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013348#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013349 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013350#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013351#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013352 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013353#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013354#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013355 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013356#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013357#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013358 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013359#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013360#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013361 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013362#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013363#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013364 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013365#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013366#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013367 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013368#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013369#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013370 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013371#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013372#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013373 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013374#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013375#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013376 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013377#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013378#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013379 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013380#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013381
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013382 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013383#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013384 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013385#endif /* ST_RDONLY */
13386#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013387 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013388#endif /* ST_NOSUID */
13389
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013390 /* GNU extensions */
13391#ifdef ST_NODEV
13392 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13393#endif /* ST_NODEV */
13394#ifdef ST_NOEXEC
13395 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13396#endif /* ST_NOEXEC */
13397#ifdef ST_SYNCHRONOUS
13398 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13399#endif /* ST_SYNCHRONOUS */
13400#ifdef ST_MANDLOCK
13401 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13402#endif /* ST_MANDLOCK */
13403#ifdef ST_WRITE
13404 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13405#endif /* ST_WRITE */
13406#ifdef ST_APPEND
13407 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13408#endif /* ST_APPEND */
13409#ifdef ST_NOATIME
13410 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13411#endif /* ST_NOATIME */
13412#ifdef ST_NODIRATIME
13413 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13414#endif /* ST_NODIRATIME */
13415#ifdef ST_RELATIME
13416 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13417#endif /* ST_RELATIME */
13418
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013419 /* FreeBSD sendfile() constants */
13420#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013421 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013422#endif
13423#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013424 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013425#endif
13426#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013427 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013428#endif
13429
Ross Lagerwall7807c352011-03-17 20:20:30 +020013430 /* constants for posix_fadvise */
13431#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013432 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013433#endif
13434#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013435 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013436#endif
13437#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013438 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013439#endif
13440#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013441 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013442#endif
13443#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013444 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013445#endif
13446#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013447 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013448#endif
13449
13450 /* constants for waitid */
13451#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013452 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13453 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13454 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013455#endif
13456#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013457 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013458#endif
13459#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013460 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013461#endif
13462#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013463 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013464#endif
13465#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013466 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013467#endif
13468#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013469 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013470#endif
13471#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013472 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013473#endif
13474#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013475 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013476#endif
13477
13478 /* constants for lockf */
13479#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013480 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013481#endif
13482#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013483 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013484#endif
13485#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013486 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013487#endif
13488#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013489 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013490#endif
13491
Pablo Galindo4defba32018-01-27 16:16:37 +000013492#ifdef RWF_DSYNC
13493 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13494#endif
13495#ifdef RWF_HIPRI
13496 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13497#endif
13498#ifdef RWF_SYNC
13499 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13500#endif
13501#ifdef RWF_NOWAIT
13502 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13503#endif
13504
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013505/* constants for posix_spawn */
13506#ifdef HAVE_POSIX_SPAWN
13507 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
13508 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
13509 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
13510#endif
13511
Guido van Rossum246bc171999-02-01 23:54:31 +000013512#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013513 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13514 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13515 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13516 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13517 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013518#endif
13519
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013520#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013521#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013522 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013523#endif
13524#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013525 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013526#endif
13527#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013528 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013529#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013530#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013531 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013532#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013533#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013534 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013535#endif
13536#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013537 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013538#endif
13539#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013540 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013541#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013542#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013543 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013544#endif
13545#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013546 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013547#endif
13548#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013549 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013550#endif
13551#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013552 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013553#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013554#endif
13555
Benjamin Peterson9428d532011-09-14 11:45:52 -040013556#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013557 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13558 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13559 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013560#endif
13561
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013562#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013563 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013564#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013565#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013566 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013567#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013568#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013569 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013570#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013571#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013572 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013573#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013574#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013575 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013576#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013577#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013578 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013579#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013580#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013581 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013582#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013583#if HAVE_DECL_RTLD_MEMBER
13584 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13585#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013586
Victor Stinner9b1f4742016-09-06 16:18:52 -070013587#ifdef HAVE_GETRANDOM_SYSCALL
13588 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13589 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13590#endif
13591
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013592#if defined(__APPLE__)
13593 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
13594#endif
13595
Victor Stinner8c62be82010-05-06 00:08:46 +000013596 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013597}
13598
13599
Martin v. Löwis1a214512008-06-11 05:26:20 +000013600static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013601 PyModuleDef_HEAD_INIT,
13602 MODNAME,
13603 posix__doc__,
13604 -1,
13605 posix_methods,
13606 NULL,
13607 NULL,
13608 NULL,
13609 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013610};
13611
13612
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013613static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013614
13615#ifdef HAVE_FACCESSAT
13616 "HAVE_FACCESSAT",
13617#endif
13618
13619#ifdef HAVE_FCHDIR
13620 "HAVE_FCHDIR",
13621#endif
13622
13623#ifdef HAVE_FCHMOD
13624 "HAVE_FCHMOD",
13625#endif
13626
13627#ifdef HAVE_FCHMODAT
13628 "HAVE_FCHMODAT",
13629#endif
13630
13631#ifdef HAVE_FCHOWN
13632 "HAVE_FCHOWN",
13633#endif
13634
Larry Hastings00964ed2013-08-12 13:49:30 -040013635#ifdef HAVE_FCHOWNAT
13636 "HAVE_FCHOWNAT",
13637#endif
13638
Larry Hastings9cf065c2012-06-22 16:30:09 -070013639#ifdef HAVE_FEXECVE
13640 "HAVE_FEXECVE",
13641#endif
13642
13643#ifdef HAVE_FDOPENDIR
13644 "HAVE_FDOPENDIR",
13645#endif
13646
Georg Brandl306336b2012-06-24 12:55:33 +020013647#ifdef HAVE_FPATHCONF
13648 "HAVE_FPATHCONF",
13649#endif
13650
Larry Hastings9cf065c2012-06-22 16:30:09 -070013651#ifdef HAVE_FSTATAT
13652 "HAVE_FSTATAT",
13653#endif
13654
13655#ifdef HAVE_FSTATVFS
13656 "HAVE_FSTATVFS",
13657#endif
13658
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013659#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013660 "HAVE_FTRUNCATE",
13661#endif
13662
Larry Hastings9cf065c2012-06-22 16:30:09 -070013663#ifdef HAVE_FUTIMENS
13664 "HAVE_FUTIMENS",
13665#endif
13666
13667#ifdef HAVE_FUTIMES
13668 "HAVE_FUTIMES",
13669#endif
13670
13671#ifdef HAVE_FUTIMESAT
13672 "HAVE_FUTIMESAT",
13673#endif
13674
13675#ifdef HAVE_LINKAT
13676 "HAVE_LINKAT",
13677#endif
13678
13679#ifdef HAVE_LCHFLAGS
13680 "HAVE_LCHFLAGS",
13681#endif
13682
13683#ifdef HAVE_LCHMOD
13684 "HAVE_LCHMOD",
13685#endif
13686
13687#ifdef HAVE_LCHOWN
13688 "HAVE_LCHOWN",
13689#endif
13690
13691#ifdef HAVE_LSTAT
13692 "HAVE_LSTAT",
13693#endif
13694
13695#ifdef HAVE_LUTIMES
13696 "HAVE_LUTIMES",
13697#endif
13698
13699#ifdef HAVE_MKDIRAT
13700 "HAVE_MKDIRAT",
13701#endif
13702
13703#ifdef HAVE_MKFIFOAT
13704 "HAVE_MKFIFOAT",
13705#endif
13706
13707#ifdef HAVE_MKNODAT
13708 "HAVE_MKNODAT",
13709#endif
13710
13711#ifdef HAVE_OPENAT
13712 "HAVE_OPENAT",
13713#endif
13714
13715#ifdef HAVE_READLINKAT
13716 "HAVE_READLINKAT",
13717#endif
13718
13719#ifdef HAVE_RENAMEAT
13720 "HAVE_RENAMEAT",
13721#endif
13722
13723#ifdef HAVE_SYMLINKAT
13724 "HAVE_SYMLINKAT",
13725#endif
13726
13727#ifdef HAVE_UNLINKAT
13728 "HAVE_UNLINKAT",
13729#endif
13730
13731#ifdef HAVE_UTIMENSAT
13732 "HAVE_UTIMENSAT",
13733#endif
13734
13735#ifdef MS_WINDOWS
13736 "MS_WINDOWS",
13737#endif
13738
13739 NULL
13740};
13741
13742
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013743PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013744INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013745{
Victor Stinner8c62be82010-05-06 00:08:46 +000013746 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013747 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013748 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013749
Brian Curtin52173d42010-12-02 18:29:18 +000013750#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013751 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013752#endif
13753
Victor Stinner8c62be82010-05-06 00:08:46 +000013754 m = PyModule_Create(&posixmodule);
13755 if (m == NULL)
13756 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013757
Victor Stinner8c62be82010-05-06 00:08:46 +000013758 /* Initialize environ dictionary */
13759 v = convertenviron();
13760 Py_XINCREF(v);
13761 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13762 return NULL;
13763 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013764
Victor Stinner8c62be82010-05-06 00:08:46 +000013765 if (all_ins(m))
13766 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013767
Victor Stinner8c62be82010-05-06 00:08:46 +000013768 if (setup_confname_tables(m))
13769 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013770
Victor Stinner8c62be82010-05-06 00:08:46 +000013771 Py_INCREF(PyExc_OSError);
13772 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013773
Guido van Rossumb3d39562000-01-31 18:41:26 +000013774#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013775 if (posix_putenv_garbage == NULL)
13776 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013777#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013778
Victor Stinner8c62be82010-05-06 00:08:46 +000013779 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013780#if defined(HAVE_WAITID) && !defined(__APPLE__)
13781 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013782 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13783 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013784#endif
13785
Christian Heimes25827622013-10-12 01:27:08 +020013786 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013787 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13788 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13789 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013790 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13791 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013792 structseq_new = StatResultType.tp_new;
13793 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013794
Christian Heimes25827622013-10-12 01:27:08 +020013795 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013796 if (PyStructSequence_InitType2(&StatVFSResultType,
13797 &statvfs_result_desc) < 0)
13798 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013799#ifdef NEED_TICKS_PER_SECOND
13800# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013801 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013802# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013803 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013804# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013805 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013806# endif
13807#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013808
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013809#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013810 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013811 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13812 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013813 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013814#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013815
13816 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013817 if (PyStructSequence_InitType2(&TerminalSizeType,
13818 &TerminalSize_desc) < 0)
13819 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013820
13821 /* initialize scandir types */
13822 if (PyType_Ready(&ScandirIteratorType) < 0)
13823 return NULL;
13824 if (PyType_Ready(&DirEntryType) < 0)
13825 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013826 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013827#if defined(HAVE_WAITID) && !defined(__APPLE__)
13828 Py_INCREF((PyObject*) &WaitidResultType);
13829 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13830#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013831 Py_INCREF((PyObject*) &StatResultType);
13832 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13833 Py_INCREF((PyObject*) &StatVFSResultType);
13834 PyModule_AddObject(m, "statvfs_result",
13835 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013836
13837#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013838 Py_INCREF(&SchedParamType);
13839 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013840#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013841
Larry Hastings605a62d2012-06-24 04:33:36 -070013842 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013843 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13844 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013845 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13846
13847 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013848 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13849 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013850 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13851
Thomas Wouters477c8d52006-05-27 19:21:47 +000013852#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013853 /*
13854 * Step 2 of weak-linking support on Mac OS X.
13855 *
13856 * The code below removes functions that are not available on the
13857 * currently active platform.
13858 *
13859 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013860 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013861 * OSX 10.4.
13862 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013863#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013864 if (fstatvfs == NULL) {
13865 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13866 return NULL;
13867 }
13868 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013869#endif /* HAVE_FSTATVFS */
13870
13871#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013872 if (statvfs == NULL) {
13873 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13874 return NULL;
13875 }
13876 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013877#endif /* HAVE_STATVFS */
13878
13879# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013880 if (lchown == NULL) {
13881 if (PyObject_DelAttrString(m, "lchown") == -1) {
13882 return NULL;
13883 }
13884 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013885#endif /* HAVE_LCHOWN */
13886
13887
13888#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013889
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013890 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013891 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13892
Larry Hastings6fe20b32012-04-19 15:07:49 -070013893 billion = PyLong_FromLong(1000000000);
13894 if (!billion)
13895 return NULL;
13896
Larry Hastings9cf065c2012-06-22 16:30:09 -070013897 /* suppress "function not used" warnings */
13898 {
13899 int ignored;
13900 fd_specified("", -1);
13901 follow_symlinks_specified("", 1);
13902 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13903 dir_fd_converter(Py_None, &ignored);
13904 dir_fd_unavailable(Py_None, &ignored);
13905 }
13906
13907 /*
13908 * provide list of locally available functions
13909 * so os.py can populate support_* lists
13910 */
13911 list = PyList_New(0);
13912 if (!list)
13913 return NULL;
13914 for (trace = have_functions; *trace; trace++) {
13915 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13916 if (!unicode)
13917 return NULL;
13918 if (PyList_Append(list, unicode))
13919 return NULL;
13920 Py_DECREF(unicode);
13921 }
13922 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013923
13924 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013925 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013926
13927 initialized = 1;
13928
Victor Stinner8c62be82010-05-06 00:08:46 +000013929 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013930}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013931
13932#ifdef __cplusplus
13933}
13934#endif