blob: a9b3917188c697fac26011e59de683a5185c4910 [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
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500100#ifdef HAVE_SCHED_H
101#include <sched.h>
102#endif
103
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500104#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500105#undef HAVE_SCHED_SETAFFINITY
106#endif
107
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200108#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400109#define USE_XATTRS
110#endif
111
112#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400113#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400114#endif
115
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000116#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
117#ifdef HAVE_SYS_SOCKET_H
118#include <sys/socket.h>
119#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000120#endif
121
Victor Stinner8b905bd2011-10-25 13:34:04 +0200122#ifdef HAVE_DLFCN_H
123#include <dlfcn.h>
124#endif
125
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200126#ifdef __hpux
127#include <sys/mpctl.h>
128#endif
129
130#if defined(__DragonFly__) || \
131 defined(__OpenBSD__) || \
132 defined(__FreeBSD__) || \
133 defined(__NetBSD__) || \
134 defined(__APPLE__)
135#include <sys/sysctl.h>
136#endif
137
Victor Stinner9b1f4742016-09-06 16:18:52 -0700138#ifdef HAVE_LINUX_RANDOM_H
139# include <linux/random.h>
140#endif
141#ifdef HAVE_GETRANDOM_SYSCALL
142# include <sys/syscall.h>
143#endif
144
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100145#if defined(MS_WINDOWS)
146# define TERMSIZE_USE_CONIO
147#elif defined(HAVE_SYS_IOCTL_H)
148# include <sys/ioctl.h>
149# if defined(HAVE_TERMIOS_H)
150# include <termios.h>
151# endif
152# if defined(TIOCGWINSZ)
153# define TERMSIZE_USE_IOCTL
154# endif
155#endif /* MS_WINDOWS */
156
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000158/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000161#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#include <process.h>
163#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000164#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000165#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000166#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700169#define HAVE_WSPAWNV 1
170#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000171#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000172#define HAVE_SYSTEM 1
173#define HAVE_CWAIT 1
174#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000175#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000176#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177/* Unix functions that the configure script doesn't check for */
178#define HAVE_EXECV 1
179#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000180#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000181#define HAVE_FORK1 1
182#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000183#define HAVE_GETEGID 1
184#define HAVE_GETEUID 1
185#define HAVE_GETGID 1
186#define HAVE_GETPPID 1
187#define HAVE_GETUID 1
188#define HAVE_KILL 1
189#define HAVE_OPENDIR 1
190#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000191#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000192#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000193#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000194#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000195#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000196
Victor Stinnera2f7c002012-02-08 03:36:25 +0100197
Larry Hastings61272b72014-01-07 12:41:53 -0800198/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000199# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800200module os
Larry Hastings61272b72014-01-07 12:41:53 -0800201[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000202/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100203
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000205
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000206#if defined(__sgi)&&_COMPILER_VERSION>=700
207/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
208 (default) */
209extern char *ctermid_r(char *);
210#endif
211
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000212#ifndef HAVE_UNISTD_H
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000213#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000214extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000216extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000217#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000218#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int chdir(char *);
220extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000221#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int chdir(const char *);
223extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000224#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000226/*#ifdef HAVE_FCHMOD
227extern int fchmod(int, mode_t);
228#endif*/
229/*#ifdef HAVE_LCHMOD
230extern int lchmod(const char *, mode_t);
231#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000232extern int chown(const char *, uid_t, gid_t);
233extern char *getcwd(char *, int);
234extern char *strerror(int);
235extern int link(const char *, const char *);
236extern int rename(const char *, const char *);
237extern int stat(const char *, struct stat *);
238extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000240extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000241#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000243extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000246
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000247#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000248
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000249#ifdef HAVE_POSIX_SPAWN
250#include <spawn.h>
251#endif
252
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253#ifdef HAVE_UTIME_H
254#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000255#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000257#ifdef HAVE_SYS_UTIME_H
258#include <sys/utime.h>
259#define HAVE_UTIME_H /* pretend we do for the rest of this file */
260#endif /* HAVE_SYS_UTIME_H */
261
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#ifdef HAVE_SYS_TIMES_H
263#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000264#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
266#ifdef HAVE_SYS_PARAM_H
267#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000268#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269
270#ifdef HAVE_SYS_UTSNAME_H
271#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000272#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#define NAMLEN(dirent) strlen((dirent)->d_name)
277#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000278#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000279#include <direct.h>
280#define NAMLEN(dirent) strlen((dirent)->d_name)
281#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000284#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000286#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000287#endif
288#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000289#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000290#endif
291#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000292#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000293#endif
294#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000295
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000296#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000298#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000299#endif
300#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000302#endif
303#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000304#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000305#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000306#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000307#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000308#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100309#ifndef IO_REPARSE_TAG_MOUNT_POINT
310#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
311#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000312#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000313#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000314#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000315#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000316#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000317#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
318#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000319static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000320#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000321#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000322
Tim Petersbc2e10e2002-03-03 23:17:02 +0000323#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324#if defined(PATH_MAX) && PATH_MAX > 1024
325#define MAXPATHLEN PATH_MAX
326#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000329#endif /* MAXPATHLEN */
330
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000331#ifdef UNION_WAIT
332/* Emulate some macros on systems that have a union instead of macros */
333
334#ifndef WIFEXITED
335#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
336#endif
337
338#ifndef WEXITSTATUS
339#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
340#endif
341
342#ifndef WTERMSIG
343#define WTERMSIG(u_wait) ((u_wait).w_termsig)
344#endif
345
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000346#define WAIT_TYPE union wait
347#define WAIT_STATUS_INT(s) (s.w_status)
348
349#else /* !UNION_WAIT */
350#define WAIT_TYPE int
351#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000352#endif /* UNION_WAIT */
353
Greg Wardb48bc172000-03-01 21:51:56 +0000354/* Don't use the "_r" form if we don't need it (also, won't have a
355 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200356#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000357#define USE_CTERMID_R
358#endif
359
Fred Drake699f3522000-06-29 21:12:41 +0000360/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000361#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000362#undef FSTAT
363#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200364#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000365# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700366# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200367# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800368# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000369#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000370# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700371# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000372# define FSTAT fstat
373# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000374#endif
375
Tim Peters11b23062003-04-23 02:39:17 +0000376#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000377#include <sys/mkdev.h>
378#else
379#if defined(MAJOR_IN_SYSMACROS)
380#include <sys/sysmacros.h>
381#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000382#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
383#include <sys/mkdev.h>
384#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000385#endif
Fred Drake699f3522000-06-29 21:12:41 +0000386
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200387#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100388#define INITFUNC PyInit_nt
389#define MODNAME "nt"
390#else
391#define INITFUNC PyInit_posix
392#define MODNAME "posix"
393#endif
394
jcea6c51d512018-01-28 14:00:08 +0100395#if defined(__sun)
396/* Something to implement in autoconf, not present in autoconf 2.69 */
397#define HAVE_STRUCT_STAT_ST_FSTYPE 1
398#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200399
400#ifdef HAVE_FORK
401static void
402run_at_forkers(PyObject *lst, int reverse)
403{
404 Py_ssize_t i;
405 PyObject *cpy;
406
407 if (lst != NULL) {
408 assert(PyList_CheckExact(lst));
409
410 /* Use a list copy in case register_at_fork() is called from
411 * one of the callbacks.
412 */
413 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
414 if (cpy == NULL)
415 PyErr_WriteUnraisable(lst);
416 else {
417 if (reverse)
418 PyList_Reverse(cpy);
419 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
420 PyObject *func, *res;
421 func = PyList_GET_ITEM(cpy, i);
422 res = PyObject_CallObject(func, NULL);
423 if (res == NULL)
424 PyErr_WriteUnraisable(func);
425 else
426 Py_DECREF(res);
427 }
428 Py_DECREF(cpy);
429 }
430 }
431}
432
433void
434PyOS_BeforeFork(void)
435{
436 run_at_forkers(PyThreadState_Get()->interp->before_forkers, 1);
437
438 _PyImport_AcquireLock();
439}
440
441void
442PyOS_AfterFork_Parent(void)
443{
444 if (_PyImport_ReleaseLock() <= 0)
445 Py_FatalError("failed releasing import lock after fork");
446
447 run_at_forkers(PyThreadState_Get()->interp->after_forkers_parent, 0);
448}
449
450void
451PyOS_AfterFork_Child(void)
452{
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200453 _PyGILState_Reinit();
454 PyEval_ReInitThreads();
455 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200456 _PySignal_AfterFork();
457
458 run_at_forkers(PyThreadState_Get()->interp->after_forkers_child, 0);
459}
460
461static int
462register_at_forker(PyObject **lst, PyObject *func)
463{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700464 if (func == NULL) /* nothing to register? do nothing. */
465 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200466 if (*lst == NULL) {
467 *lst = PyList_New(0);
468 if (*lst == NULL)
469 return -1;
470 }
471 return PyList_Append(*lst, func);
472}
473#endif
474
475/* Legacy wrapper */
476void
477PyOS_AfterFork(void)
478{
479#ifdef HAVE_FORK
480 PyOS_AfterFork_Child();
481#endif
482}
483
484
Victor Stinner6036e442015-03-08 01:58:04 +0100485#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200486/* defined in fileutils.c */
487PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
488PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
489 ULONG, struct _Py_stat_struct *);
490#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700491
492#ifdef MS_WINDOWS
493static int
494win32_warn_bytes_api()
495{
496 return PyErr_WarnEx(PyExc_DeprecationWarning,
497 "The Windows bytes API has been deprecated, "
498 "use Unicode filenames instead",
499 1);
500}
501#endif
502
503
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200504#ifndef MS_WINDOWS
505PyObject *
506_PyLong_FromUid(uid_t uid)
507{
508 if (uid == (uid_t)-1)
509 return PyLong_FromLong(-1);
510 return PyLong_FromUnsignedLong(uid);
511}
512
513PyObject *
514_PyLong_FromGid(gid_t gid)
515{
516 if (gid == (gid_t)-1)
517 return PyLong_FromLong(-1);
518 return PyLong_FromUnsignedLong(gid);
519}
520
521int
522_Py_Uid_Converter(PyObject *obj, void *p)
523{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524 uid_t uid;
525 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200526 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200527 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528 unsigned long uresult;
529
530 index = PyNumber_Index(obj);
531 if (index == NULL) {
532 PyErr_Format(PyExc_TypeError,
533 "uid should be integer, not %.200s",
534 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200535 return 0;
536 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700537
538 /*
539 * Handling uid_t is complicated for two reasons:
540 * * Although uid_t is (always?) unsigned, it still
541 * accepts -1.
542 * * We don't know its size in advance--it may be
543 * bigger than an int, or it may be smaller than
544 * a long.
545 *
546 * So a bit of defensive programming is in order.
547 * Start with interpreting the value passed
548 * in as a signed long and see if it works.
549 */
550
551 result = PyLong_AsLongAndOverflow(index, &overflow);
552
553 if (!overflow) {
554 uid = (uid_t)result;
555
556 if (result == -1) {
557 if (PyErr_Occurred())
558 goto fail;
559 /* It's a legitimate -1, we're done. */
560 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200561 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700562
563 /* Any other negative number is disallowed. */
564 if (result < 0)
565 goto underflow;
566
567 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200568 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700569 (long)uid != result)
570 goto underflow;
571 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200572 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700573
574 if (overflow < 0)
575 goto underflow;
576
577 /*
578 * Okay, the value overflowed a signed long. If it
579 * fits in an *unsigned* long, it may still be okay,
580 * as uid_t may be unsigned long on this platform.
581 */
582 uresult = PyLong_AsUnsignedLong(index);
583 if (PyErr_Occurred()) {
584 if (PyErr_ExceptionMatches(PyExc_OverflowError))
585 goto overflow;
586 goto fail;
587 }
588
589 uid = (uid_t)uresult;
590
591 /*
592 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
593 * but this value would get interpreted as (uid_t)-1 by chown
594 * and its siblings. That's not what the user meant! So we
595 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100596 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700597 */
598 if (uid == (uid_t)-1)
599 goto overflow;
600
601 /* Ensure the value wasn't truncated. */
602 if (sizeof(uid_t) < sizeof(long) &&
603 (unsigned long)uid != uresult)
604 goto overflow;
605 /* fallthrough */
606
607success:
608 Py_DECREF(index);
609 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200610 return 1;
611
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700612underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200613 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700614 "uid is less than minimum");
615 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200616
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700617overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200618 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700619 "uid is greater than maximum");
620 /* fallthrough */
621
622fail:
623 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200624 return 0;
625}
626
627int
628_Py_Gid_Converter(PyObject *obj, void *p)
629{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700630 gid_t gid;
631 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200632 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200633 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700634 unsigned long uresult;
635
636 index = PyNumber_Index(obj);
637 if (index == NULL) {
638 PyErr_Format(PyExc_TypeError,
639 "gid should be integer, not %.200s",
640 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200641 return 0;
642 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700643
644 /*
645 * Handling gid_t is complicated for two reasons:
646 * * Although gid_t is (always?) unsigned, it still
647 * accepts -1.
648 * * We don't know its size in advance--it may be
649 * bigger than an int, or it may be smaller than
650 * a long.
651 *
652 * So a bit of defensive programming is in order.
653 * Start with interpreting the value passed
654 * in as a signed long and see if it works.
655 */
656
657 result = PyLong_AsLongAndOverflow(index, &overflow);
658
659 if (!overflow) {
660 gid = (gid_t)result;
661
662 if (result == -1) {
663 if (PyErr_Occurred())
664 goto fail;
665 /* It's a legitimate -1, we're done. */
666 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200667 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700668
669 /* Any other negative number is disallowed. */
670 if (result < 0) {
671 goto underflow;
672 }
673
674 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200675 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700676 (long)gid != result)
677 goto underflow;
678 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200679 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680
681 if (overflow < 0)
682 goto underflow;
683
684 /*
685 * Okay, the value overflowed a signed long. If it
686 * fits in an *unsigned* long, it may still be okay,
687 * as gid_t may be unsigned long on this platform.
688 */
689 uresult = PyLong_AsUnsignedLong(index);
690 if (PyErr_Occurred()) {
691 if (PyErr_ExceptionMatches(PyExc_OverflowError))
692 goto overflow;
693 goto fail;
694 }
695
696 gid = (gid_t)uresult;
697
698 /*
699 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
700 * but this value would get interpreted as (gid_t)-1 by chown
701 * and its siblings. That's not what the user meant! So we
702 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100703 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700704 */
705 if (gid == (gid_t)-1)
706 goto overflow;
707
708 /* Ensure the value wasn't truncated. */
709 if (sizeof(gid_t) < sizeof(long) &&
710 (unsigned long)gid != uresult)
711 goto overflow;
712 /* fallthrough */
713
714success:
715 Py_DECREF(index);
716 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200717 return 1;
718
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700719underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200720 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700721 "gid is less than minimum");
722 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200723
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700724overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200725 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700726 "gid is greater than maximum");
727 /* fallthrough */
728
729fail:
730 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200731 return 0;
732}
733#endif /* MS_WINDOWS */
734
735
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700736#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800737
738
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200739#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
740static int
741_Py_Dev_Converter(PyObject *obj, void *p)
742{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200743 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200744 if (PyErr_Occurred())
745 return 0;
746 return 1;
747}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800748#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200749
750
Larry Hastings9cf065c2012-06-22 16:30:09 -0700751#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400752/*
753 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
754 * without the int cast, the value gets interpreted as uint (4291925331),
755 * which doesn't play nicely with all the initializer lines in this file that
756 * look like this:
757 * int dir_fd = DEFAULT_DIR_FD;
758 */
759#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700760#else
761#define DEFAULT_DIR_FD (-100)
762#endif
763
764static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300765_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200766{
767 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700768 long long_value;
769
770 PyObject *index = PyNumber_Index(o);
771 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700772 return 0;
773 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700774
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300775 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700776 long_value = PyLong_AsLongAndOverflow(index, &overflow);
777 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300778 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200779 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700780 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700781 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700782 return 0;
783 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200784 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700785 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700786 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700787 return 0;
788 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700789
Larry Hastings9cf065c2012-06-22 16:30:09 -0700790 *p = (int)long_value;
791 return 1;
792}
793
794static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200795dir_fd_converter(PyObject *o, void *p)
796{
797 if (o == Py_None) {
798 *(int *)p = DEFAULT_DIR_FD;
799 return 1;
800 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300801 else if (PyIndex_Check(o)) {
802 return _fd_converter(o, (int *)p);
803 }
804 else {
805 PyErr_Format(PyExc_TypeError,
806 "argument should be integer or None, not %.200s",
807 Py_TYPE(o)->tp_name);
808 return 0;
809 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700810}
811
812
Larry Hastings9cf065c2012-06-22 16:30:09 -0700813/*
814 * A PyArg_ParseTuple "converter" function
815 * that handles filesystem paths in the manner
816 * preferred by the os module.
817 *
818 * path_converter accepts (Unicode) strings and their
819 * subclasses, and bytes and their subclasses. What
820 * it does with the argument depends on the platform:
821 *
822 * * On Windows, if we get a (Unicode) string we
823 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700824 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700825 *
826 * * On all other platforms, strings are encoded
827 * to bytes using PyUnicode_FSConverter, then we
828 * extract the char * from the bytes object and
829 * return that.
830 *
831 * path_converter also optionally accepts signed
832 * integers (representing open file descriptors) instead
833 * of path strings.
834 *
835 * Input fields:
836 * path.nullable
837 * If nonzero, the path is permitted to be None.
838 * path.allow_fd
839 * If nonzero, the path is permitted to be a file handle
840 * (a signed int) instead of a string.
841 * path.function_name
842 * If non-NULL, path_converter will use that as the name
843 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700844 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700845 * path.argument_name
846 * If non-NULL, path_converter will use that as the name
847 * of the parameter in error messages.
848 * (If path.argument_name is NULL it uses "path".)
849 *
850 * Output fields:
851 * path.wide
852 * Points to the path if it was expressed as Unicode
853 * and was not encoded. (Only used on Windows.)
854 * path.narrow
855 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700856 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000857 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700858 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700859 * path.fd
860 * Contains a file descriptor if path.accept_fd was true
861 * and the caller provided a signed integer instead of any
862 * sort of string.
863 *
864 * WARNING: if your "path" parameter is optional, and is
865 * unspecified, path_converter will never get called.
866 * So if you set allow_fd, you *MUST* initialize path.fd = -1
867 * yourself!
868 * path.length
869 * The length of the path in characters, if specified as
870 * a string.
871 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800872 * The original object passed in (if get a PathLike object,
873 * the result of PyOS_FSPath() is treated as the original object).
874 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700875 * path.cleanup
876 * For internal use only. May point to a temporary object.
877 * (Pay no attention to the man behind the curtain.)
878 *
879 * At most one of path.wide or path.narrow will be non-NULL.
880 * If path was None and path.nullable was set,
881 * or if path was an integer and path.allow_fd was set,
882 * both path.wide and path.narrow will be NULL
883 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200884 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700885 * path_converter takes care to not write to the path_t
886 * unless it's successful. However it must reset the
887 * "cleanup" field each time it's called.
888 *
889 * Use as follows:
890 * path_t path;
891 * memset(&path, 0, sizeof(path));
892 * PyArg_ParseTuple(args, "O&", path_converter, &path);
893 * // ... use values from path ...
894 * path_cleanup(&path);
895 *
896 * (Note that if PyArg_Parse fails you don't need to call
897 * path_cleanup(). However it is safe to do so.)
898 */
899typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100900 const char *function_name;
901 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700902 int nullable;
903 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300904 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700905#ifdef MS_WINDOWS
906 BOOL narrow;
907#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300908 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700909#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700910 int fd;
911 Py_ssize_t length;
912 PyObject *object;
913 PyObject *cleanup;
914} path_t;
915
Steve Dowercc16be82016-09-08 10:35:16 -0700916#ifdef MS_WINDOWS
917#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
918 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
919#else
Larry Hastings2f936352014-08-05 14:04:04 +1000920#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
921 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700922#endif
Larry Hastings31826802013-10-19 00:09:25 -0700923
Larry Hastings9cf065c2012-06-22 16:30:09 -0700924static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800925path_cleanup(path_t *path)
926{
927 Py_CLEAR(path->object);
928 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700929}
930
931static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300932path_converter(PyObject *o, void *p)
933{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700934 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800935 PyObject *bytes = NULL;
936 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700937 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300938 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700939#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800940 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700941 const wchar_t *wide;
942#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700943
944#define FORMAT_EXCEPTION(exc, fmt) \
945 PyErr_Format(exc, "%s%s" fmt, \
946 path->function_name ? path->function_name : "", \
947 path->function_name ? ": " : "", \
948 path->argument_name ? path->argument_name : "path")
949
950 /* Py_CLEANUP_SUPPORTED support */
951 if (o == NULL) {
952 path_cleanup(path);
953 return 1;
954 }
955
Brett Cannon3f9183b2016-08-26 14:44:48 -0700956 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800957 path->object = path->cleanup = NULL;
958 /* path->object owns a reference to the original object */
959 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700960
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300961 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700962 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700963#ifdef MS_WINDOWS
964 path->narrow = FALSE;
965#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700967#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700968 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800969 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700970 }
971
Brett Cannon3f9183b2016-08-26 14:44:48 -0700972 /* Only call this here so that we don't treat the return value of
973 os.fspath() as an fd or buffer. */
974 is_index = path->allow_fd && PyIndex_Check(o);
975 is_buffer = PyObject_CheckBuffer(o);
976 is_bytes = PyBytes_Check(o);
977 is_unicode = PyUnicode_Check(o);
978
979 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
980 /* Inline PyOS_FSPath() for better error messages. */
981 _Py_IDENTIFIER(__fspath__);
982 PyObject *func = NULL;
983
984 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
985 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800986 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700987 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800988 /* still owns a reference to the original object */
989 Py_DECREF(o);
990 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700991 Py_DECREF(func);
992 if (NULL == o) {
993 goto error_exit;
994 }
995 else if (PyUnicode_Check(o)) {
996 is_unicode = 1;
997 }
998 else if (PyBytes_Check(o)) {
999 is_bytes = 1;
1000 }
1001 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001002 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001003 }
1004 }
1005
1006 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001007#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001008 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001009 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001010 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001011 }
Victor Stinner59799a82013-11-13 14:17:30 +01001012 if (length > 32767) {
1013 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001014 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001015 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001016 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001017 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001018 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001019 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001020
1021 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001022 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001023 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001024 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001025#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001026 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001027 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001028 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001029#endif
1030 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001031 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001032 bytes = o;
1033 Py_INCREF(bytes);
1034 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001035 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001036 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001037 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001038 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1039 "%s%s%s should be %s, not %.200s",
1040 path->function_name ? path->function_name : "",
1041 path->function_name ? ": " : "",
1042 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001043 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1044 "integer or None" :
1045 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1046 path->nullable ? "string, bytes, os.PathLike or None" :
1047 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001048 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001049 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001050 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001051 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001053 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001054 }
1055 }
Steve Dowercc16be82016-09-08 10:35:16 -07001056 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001057 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001058 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001059 }
1060 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001061#ifdef MS_WINDOWS
1062 path->narrow = FALSE;
1063#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001064 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001065#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001066 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001067 }
1068 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001069 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001070 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1071 path->function_name ? path->function_name : "",
1072 path->function_name ? ": " : "",
1073 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001074 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1075 "integer or None" :
1076 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1077 path->nullable ? "string, bytes, os.PathLike or None" :
1078 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001079 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001080 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001081 }
1082
Larry Hastings9cf065c2012-06-22 16:30:09 -07001083 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001085 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001086 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001087 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001088 }
1089
Steve Dowercc16be82016-09-08 10:35:16 -07001090#ifdef MS_WINDOWS
1091 wo = PyUnicode_DecodeFSDefaultAndSize(
1092 narrow,
1093 length
1094 );
1095 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001096 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001097 }
1098
Xiang Zhang04316c42017-01-08 23:26:57 +08001099 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001100 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001101 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001102 }
1103 if (length > 32767) {
1104 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001105 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001106 }
1107 if (wcslen(wide) != length) {
1108 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001109 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001110 }
1111 path->wide = wide;
1112 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001113 path->cleanup = wo;
1114 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001115#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001116 path->wide = NULL;
1117 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001118 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001119 /* Still a reference owned by path->object, don't have to
1120 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001121 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001122 }
1123 else {
1124 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001125 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001126#endif
1127 path->fd = -1;
1128
1129 success_exit:
1130 path->length = length;
1131 path->object = o;
1132 return Py_CLEANUP_SUPPORTED;
1133
1134 error_exit:
1135 Py_XDECREF(o);
1136 Py_XDECREF(bytes);
1137#ifdef MS_WINDOWS
1138 Py_XDECREF(wo);
1139#endif
1140 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001141}
1142
1143static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001144argument_unavailable_error(const char *function_name, const char *argument_name)
1145{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001146 PyErr_Format(PyExc_NotImplementedError,
1147 "%s%s%s unavailable on this platform",
1148 (function_name != NULL) ? function_name : "",
1149 (function_name != NULL) ? ": ": "",
1150 argument_name);
1151}
1152
1153static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001154dir_fd_unavailable(PyObject *o, void *p)
1155{
1156 int dir_fd;
1157 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001158 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001159 if (dir_fd != DEFAULT_DIR_FD) {
1160 argument_unavailable_error(NULL, "dir_fd");
1161 return 0;
1162 }
1163 *(int *)p = dir_fd;
1164 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001165}
1166
1167static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001168fd_specified(const char *function_name, int fd)
1169{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001170 if (fd == -1)
1171 return 0;
1172
1173 argument_unavailable_error(function_name, "fd");
1174 return 1;
1175}
1176
1177static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001178follow_symlinks_specified(const char *function_name, int follow_symlinks)
1179{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001180 if (follow_symlinks)
1181 return 0;
1182
1183 argument_unavailable_error(function_name, "follow_symlinks");
1184 return 1;
1185}
1186
1187static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001188path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1189{
Steve Dowercc16be82016-09-08 10:35:16 -07001190 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1191#ifndef MS_WINDOWS
1192 && !path->narrow
1193#endif
1194 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001195 PyErr_Format(PyExc_ValueError,
1196 "%s: can't specify dir_fd without matching path",
1197 function_name);
1198 return 1;
1199 }
1200 return 0;
1201}
1202
1203static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001204dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1205{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001206 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1207 PyErr_Format(PyExc_ValueError,
1208 "%s: can't specify both dir_fd and fd",
1209 function_name);
1210 return 1;
1211 }
1212 return 0;
1213}
1214
1215static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001216fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1217 int follow_symlinks)
1218{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001219 if ((fd > 0) && (!follow_symlinks)) {
1220 PyErr_Format(PyExc_ValueError,
1221 "%s: cannot use fd and follow_symlinks together",
1222 function_name);
1223 return 1;
1224 }
1225 return 0;
1226}
1227
1228static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001229dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1230 int follow_symlinks)
1231{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001232 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1233 PyErr_Format(PyExc_ValueError,
1234 "%s: cannot use dir_fd and follow_symlinks together",
1235 function_name);
1236 return 1;
1237 }
1238 return 0;
1239}
1240
Larry Hastings2f936352014-08-05 14:04:04 +10001241#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001242 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001243#else
Larry Hastings2f936352014-08-05 14:04:04 +10001244 typedef off_t Py_off_t;
1245#endif
1246
1247static int
1248Py_off_t_converter(PyObject *arg, void *addr)
1249{
1250#ifdef HAVE_LARGEFILE_SUPPORT
1251 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1252#else
1253 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001254#endif
1255 if (PyErr_Occurred())
1256 return 0;
1257 return 1;
1258}
Larry Hastings2f936352014-08-05 14:04:04 +10001259
1260static PyObject *
1261PyLong_FromPy_off_t(Py_off_t offset)
1262{
1263#ifdef HAVE_LARGEFILE_SUPPORT
1264 return PyLong_FromLongLong(offset);
1265#else
1266 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001267#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001268}
1269
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001270#ifdef HAVE_SIGSET_T
1271/* Convert an iterable of integers to a sigset.
1272 Return 1 on success, return 0 and raise an exception on error. */
1273int
1274_Py_Sigset_Converter(PyObject *obj, void *addr)
1275{
1276 sigset_t *mask = (sigset_t *)addr;
1277 PyObject *iterator, *item;
1278 long signum;
1279 int overflow;
1280
1281 if (sigemptyset(mask)) {
1282 /* Probably only if mask == NULL. */
1283 PyErr_SetFromErrno(PyExc_OSError);
1284 return 0;
1285 }
1286
1287 iterator = PyObject_GetIter(obj);
1288 if (iterator == NULL) {
1289 return 0;
1290 }
1291
1292 while ((item = PyIter_Next(iterator)) != NULL) {
1293 signum = PyLong_AsLongAndOverflow(item, &overflow);
1294 Py_DECREF(item);
1295 if (signum <= 0 || signum >= NSIG) {
1296 if (overflow || signum != -1 || !PyErr_Occurred()) {
1297 PyErr_Format(PyExc_ValueError,
1298 "signal number %ld out of range", signum);
1299 }
1300 goto error;
1301 }
1302 if (sigaddset(mask, (int)signum)) {
1303 if (errno != EINVAL) {
1304 /* Probably impossible */
1305 PyErr_SetFromErrno(PyExc_OSError);
1306 goto error;
1307 }
1308 /* For backwards compatibility, allow idioms such as
1309 * `range(1, NSIG)` but warn about invalid signal numbers
1310 */
1311 const char msg[] =
1312 "invalid signal number %ld, please use valid_signals()";
1313 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1314 goto error;
1315 }
1316 }
1317 }
1318 if (!PyErr_Occurred()) {
1319 Py_DECREF(iterator);
1320 return 1;
1321 }
1322
1323error:
1324 Py_DECREF(iterator);
1325 return 0;
1326}
1327#endif /* HAVE_SIGSET_T */
1328
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001329#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001330
1331static int
Brian Curtind25aef52011-06-13 15:16:04 -05001332win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001333{
Martin Panter70214ad2016-08-04 02:38:59 +00001334 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1335 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001336 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001337
1338 if (0 == DeviceIoControl(
1339 reparse_point_handle,
1340 FSCTL_GET_REPARSE_POINT,
1341 NULL, 0, /* in buffer */
1342 target_buffer, sizeof(target_buffer),
1343 &n_bytes_returned,
1344 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001345 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001346
1347 if (reparse_tag)
1348 *reparse_tag = rdb->ReparseTag;
1349
Brian Curtind25aef52011-06-13 15:16:04 -05001350 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001351}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001352
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001353#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001354
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001355/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001356#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001357/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001358** environ directly, we must obtain it with _NSGetEnviron(). See also
1359** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001360*/
1361#include <crt_externs.h>
1362static char **environ;
1363#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001364extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001365#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001366
Barry Warsaw53699e91996-12-10 23:23:01 +00001367static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001368convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001369{
Victor Stinner8c62be82010-05-06 00:08:46 +00001370 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001371#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001372 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001373#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001374 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001375#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001376
Victor Stinner8c62be82010-05-06 00:08:46 +00001377 d = PyDict_New();
1378 if (d == NULL)
1379 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001380#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001381 if (environ == NULL)
1382 environ = *_NSGetEnviron();
1383#endif
1384#ifdef MS_WINDOWS
1385 /* _wenviron must be initialized in this way if the program is started
1386 through main() instead of wmain(). */
1387 _wgetenv(L"");
1388 if (_wenviron == NULL)
1389 return d;
1390 /* This part ignores errors */
1391 for (e = _wenviron; *e != NULL; e++) {
1392 PyObject *k;
1393 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001394 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001395 if (p == NULL)
1396 continue;
1397 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1398 if (k == NULL) {
1399 PyErr_Clear();
1400 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001401 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001402 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1403 if (v == NULL) {
1404 PyErr_Clear();
1405 Py_DECREF(k);
1406 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001407 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001408 if (PyDict_GetItem(d, k) == NULL) {
1409 if (PyDict_SetItem(d, k, v) != 0)
1410 PyErr_Clear();
1411 }
1412 Py_DECREF(k);
1413 Py_DECREF(v);
1414 }
1415#else
1416 if (environ == NULL)
1417 return d;
1418 /* This part ignores errors */
1419 for (e = environ; *e != NULL; e++) {
1420 PyObject *k;
1421 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001422 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001423 if (p == NULL)
1424 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001425 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001426 if (k == NULL) {
1427 PyErr_Clear();
1428 continue;
1429 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001430 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001431 if (v == NULL) {
1432 PyErr_Clear();
1433 Py_DECREF(k);
1434 continue;
1435 }
1436 if (PyDict_GetItem(d, k) == NULL) {
1437 if (PyDict_SetItem(d, k, v) != 0)
1438 PyErr_Clear();
1439 }
1440 Py_DECREF(k);
1441 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001442 }
1443#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001444 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001445}
1446
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001447/* Set a POSIX-specific error from errno, and return NULL */
1448
Barry Warsawd58d7641998-07-23 16:14:40 +00001449static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001450posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001451{
Victor Stinner8c62be82010-05-06 00:08:46 +00001452 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001453}
Mark Hammondef8b6542001-05-13 08:04:26 +00001454
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001455#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001456static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001457win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001458{
Victor Stinner8c62be82010-05-06 00:08:46 +00001459 /* XXX We should pass the function name along in the future.
1460 (winreg.c also wants to pass the function name.)
1461 This would however require an additional param to the
1462 Windows error object, which is non-trivial.
1463 */
1464 errno = GetLastError();
1465 if (filename)
1466 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1467 else
1468 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001469}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001470
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001471static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001472win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001473{
1474 /* XXX - see win32_error for comments on 'function' */
1475 errno = GetLastError();
1476 if (filename)
1477 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001478 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001479 errno,
1480 filename);
1481 else
1482 return PyErr_SetFromWindowsErr(errno);
1483}
1484
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001485#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001486
Larry Hastings9cf065c2012-06-22 16:30:09 -07001487static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001488path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001489{
1490#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001491 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1492 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001493#else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001494 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001495#endif
1496}
1497
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001498static PyObject *
1499path_object_error2(PyObject *path, PyObject *path2)
1500{
1501#ifdef MS_WINDOWS
1502 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1503 PyExc_OSError, 0, path, path2);
1504#else
1505 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1506#endif
1507}
1508
1509static PyObject *
1510path_error(path_t *path)
1511{
1512 return path_object_error(path->object);
1513}
Larry Hastings31826802013-10-19 00:09:25 -07001514
Larry Hastingsb0827312014-02-09 22:05:19 -08001515static PyObject *
1516path_error2(path_t *path, path_t *path2)
1517{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001518 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001519}
1520
1521
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001522/* POSIX generic methods */
1523
Larry Hastings2f936352014-08-05 14:04:04 +10001524static int
1525fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001526{
Victor Stinner8c62be82010-05-06 00:08:46 +00001527 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001528 int *pointer = (int *)p;
1529 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001530 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001531 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001532 *pointer = fd;
1533 return 1;
1534}
1535
1536static PyObject *
1537posix_fildes_fd(int fd, int (*func)(int))
1538{
1539 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001540 int async_err = 0;
1541
1542 do {
1543 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001544 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001545 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001546 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001547 Py_END_ALLOW_THREADS
1548 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1549 if (res != 0)
1550 return (!async_err) ? posix_error() : NULL;
1551 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001552}
Guido van Rossum21142a01999-01-08 21:05:37 +00001553
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001554
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001555#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001556/* This is a reimplementation of the C library's chdir function,
1557 but one that produces Win32 errors instead of DOS error codes.
1558 chdir is essentially a wrapper around SetCurrentDirectory; however,
1559 it also needs to set "magic" environment variables indicating
1560 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001561static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001562win32_wchdir(LPCWSTR path)
1563{
Victor Stinnered537822015-12-13 21:40:26 +01001564 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001565 int result;
1566 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001567
Victor Stinner8c62be82010-05-06 00:08:46 +00001568 if(!SetCurrentDirectoryW(path))
1569 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001570 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001571 if (!result)
1572 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001573 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001574 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001575 if (!new_path) {
1576 SetLastError(ERROR_OUTOFMEMORY);
1577 return FALSE;
1578 }
1579 result = GetCurrentDirectoryW(result, new_path);
1580 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001581 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001582 return FALSE;
1583 }
1584 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001585 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1586 wcsncmp(new_path, L"//", 2) == 0);
1587 if (!is_unc_like_path) {
1588 env[1] = new_path[0];
1589 result = SetEnvironmentVariableW(env, new_path);
1590 }
Victor Stinnered537822015-12-13 21:40:26 +01001591 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001592 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001593 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001594}
1595#endif
1596
Martin v. Löwis14694662006-02-03 12:54:16 +00001597#ifdef MS_WINDOWS
1598/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1599 - time stamps are restricted to second resolution
1600 - file modification times suffer from forth-and-back conversions between
1601 UTC and local time
1602 Therefore, we implement our own stat, based on the Win32 API directly.
1603*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001604#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001605#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001606
Victor Stinner6036e442015-03-08 01:58:04 +01001607static void
Steve Dowercc16be82016-09-08 10:35:16 -07001608find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1609 BY_HANDLE_FILE_INFORMATION *info,
1610 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001611{
1612 memset(info, 0, sizeof(*info));
1613 info->dwFileAttributes = pFileData->dwFileAttributes;
1614 info->ftCreationTime = pFileData->ftCreationTime;
1615 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1616 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1617 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1618 info->nFileSizeLow = pFileData->nFileSizeLow;
1619/* info->nNumberOfLinks = 1; */
1620 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1621 *reparse_tag = pFileData->dwReserved0;
1622 else
1623 *reparse_tag = 0;
1624}
1625
Guido van Rossumd8faa362007-04-27 19:54:29 +00001626static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001627attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001628{
Victor Stinner8c62be82010-05-06 00:08:46 +00001629 HANDLE hFindFile;
1630 WIN32_FIND_DATAW FileData;
1631 hFindFile = FindFirstFileW(pszFile, &FileData);
1632 if (hFindFile == INVALID_HANDLE_VALUE)
1633 return FALSE;
1634 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001635 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001636 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001637}
1638
Brian Curtind25aef52011-06-13 15:16:04 -05001639static BOOL
1640get_target_path(HANDLE hdl, wchar_t **target_path)
1641{
1642 int buf_size, result_length;
1643 wchar_t *buf;
1644
1645 /* We have a good handle to the target, use it to determine
1646 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001647 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1648 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001649 if(!buf_size)
1650 return FALSE;
1651
Victor Stinnerc36674a2016-03-16 14:30:16 +01001652 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001653 if (!buf) {
1654 SetLastError(ERROR_OUTOFMEMORY);
1655 return FALSE;
1656 }
1657
Steve Dower2ea51c92015-03-20 21:49:12 -07001658 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001659 buf, buf_size, VOLUME_NAME_DOS);
1660
1661 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001662 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001663 return FALSE;
1664 }
1665
1666 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001667 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001668 return FALSE;
1669 }
1670
1671 buf[result_length] = 0;
1672
1673 *target_path = buf;
1674 return TRUE;
1675}
1676
1677static int
Steve Dowercc16be82016-09-08 10:35:16 -07001678win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001679 BOOL traverse)
1680{
Victor Stinner26de69d2011-06-17 15:15:38 +02001681 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001682 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001683 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001684 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001685 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001686 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001687
Steve Dowercc16be82016-09-08 10:35:16 -07001688 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001689 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001690 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001691 0, /* share mode */
1692 NULL, /* security attributes */
1693 OPEN_EXISTING,
1694 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001695 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1696 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001697 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001698 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1699 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001700 NULL);
1701
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001702 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001703 /* Either the target doesn't exist, or we don't have access to
1704 get a handle to it. If the former, we need to return an error.
1705 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001706 DWORD lastError = GetLastError();
1707 if (lastError != ERROR_ACCESS_DENIED &&
1708 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 return -1;
1710 /* Could not get attributes on open file. Fall back to
1711 reading the directory. */
1712 if (!attributes_from_dir(path, &info, &reparse_tag))
1713 /* Very strange. This should not fail now */
1714 return -1;
1715 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1716 if (traverse) {
1717 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001718 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001719 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001720 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001721 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001722 } else {
1723 if (!GetFileInformationByHandle(hFile, &info)) {
1724 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001725 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001726 }
1727 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001728 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1729 return -1;
1730
1731 /* Close the outer open file handle now that we're about to
1732 reopen it with different flags. */
1733 if (!CloseHandle(hFile))
1734 return -1;
1735
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001736 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001737 /* In order to call GetFinalPathNameByHandle we need to open
1738 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001739 hFile2 = CreateFileW(
1740 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1741 NULL, OPEN_EXISTING,
1742 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1743 NULL);
1744 if (hFile2 == INVALID_HANDLE_VALUE)
1745 return -1;
1746
1747 if (!get_target_path(hFile2, &target_path))
1748 return -1;
1749
Steve Dowercc16be82016-09-08 10:35:16 -07001750 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001751 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001752 return code;
1753 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001754 } else
1755 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001756 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001757 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001758
1759 /* Set S_IEXEC if it is an .exe, .bat, ... */
1760 dot = wcsrchr(path, '.');
1761 if (dot) {
1762 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1763 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1764 result->st_mode |= 0111;
1765 }
1766 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001767}
1768
1769static int
Steve Dowercc16be82016-09-08 10:35:16 -07001770win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001771{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001772 /* Protocol violation: we explicitly clear errno, instead of
1773 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001774 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001775 errno = 0;
1776 return code;
1777}
Brian Curtind25aef52011-06-13 15:16:04 -05001778/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001779
1780 In Posix, stat automatically traverses symlinks and returns the stat
1781 structure for the target. In Windows, the equivalent GetFileAttributes by
1782 default does not traverse symlinks and instead returns attributes for
1783 the symlink.
1784
1785 Therefore, win32_lstat will get the attributes traditionally, and
1786 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001787 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001788
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001789static int
Steve Dowercc16be82016-09-08 10:35:16 -07001790win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001791{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001792 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001793}
1794
Victor Stinner8c62be82010-05-06 00:08:46 +00001795static int
Steve Dowercc16be82016-09-08 10:35:16 -07001796win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001797{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001798 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001799}
1800
Martin v. Löwis14694662006-02-03 12:54:16 +00001801#endif /* MS_WINDOWS */
1802
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001803PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001804"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001805This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001806 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001807or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1808\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001809Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1810or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001811\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001812See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001813
1814static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001815 {"st_mode", "protection bits"},
1816 {"st_ino", "inode"},
1817 {"st_dev", "device"},
1818 {"st_nlink", "number of hard links"},
1819 {"st_uid", "user ID of owner"},
1820 {"st_gid", "group ID of owner"},
1821 {"st_size", "total size, in bytes"},
1822 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1823 {NULL, "integer time of last access"},
1824 {NULL, "integer time of last modification"},
1825 {NULL, "integer time of last change"},
1826 {"st_atime", "time of last access"},
1827 {"st_mtime", "time of last modification"},
1828 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001829 {"st_atime_ns", "time of last access in nanoseconds"},
1830 {"st_mtime_ns", "time of last modification in nanoseconds"},
1831 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001832#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001833 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001834#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001835#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001836 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001837#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001838#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001839 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001840#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001841#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001842 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001843#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001844#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001845 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001846#endif
1847#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001848 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001849#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001850#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1851 {"st_file_attributes", "Windows file attribute bits"},
1852#endif
jcea6c51d512018-01-28 14:00:08 +01001853#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1854 {"st_fstype", "Type of filesystem"},
1855#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001856 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001857};
1858
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001859#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001860#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001861#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001862#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001863#endif
1864
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001865#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001866#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1867#else
1868#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1869#endif
1870
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001871#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001872#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1873#else
1874#define ST_RDEV_IDX ST_BLOCKS_IDX
1875#endif
1876
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001877#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1878#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1879#else
1880#define ST_FLAGS_IDX ST_RDEV_IDX
1881#endif
1882
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001883#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001884#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001885#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001886#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001887#endif
1888
1889#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1890#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1891#else
1892#define ST_BIRTHTIME_IDX ST_GEN_IDX
1893#endif
1894
Zachary Ware63f277b2014-06-19 09:46:37 -05001895#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1896#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1897#else
1898#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1899#endif
1900
jcea6c51d512018-01-28 14:00:08 +01001901#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1902#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1903#else
1904#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1905#endif
1906
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001907static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001908 "stat_result", /* name */
1909 stat_result__doc__, /* doc */
1910 stat_result_fields,
1911 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001912};
1913
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001914PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001915"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1916This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001917 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001918or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001919\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001920See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001921
1922static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001923 {"f_bsize", },
1924 {"f_frsize", },
1925 {"f_blocks", },
1926 {"f_bfree", },
1927 {"f_bavail", },
1928 {"f_files", },
1929 {"f_ffree", },
1930 {"f_favail", },
1931 {"f_flag", },
1932 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001933 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001935};
1936
1937static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 "statvfs_result", /* name */
1939 statvfs_result__doc__, /* doc */
1940 statvfs_result_fields,
1941 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001942};
1943
Ross Lagerwall7807c352011-03-17 20:20:30 +02001944#if defined(HAVE_WAITID) && !defined(__APPLE__)
1945PyDoc_STRVAR(waitid_result__doc__,
1946"waitid_result: Result from waitid.\n\n\
1947This object may be accessed either as a tuple of\n\
1948 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1949or via the attributes si_pid, si_uid, and so on.\n\
1950\n\
1951See os.waitid for more information.");
1952
1953static PyStructSequence_Field waitid_result_fields[] = {
1954 {"si_pid", },
1955 {"si_uid", },
1956 {"si_signo", },
1957 {"si_status", },
1958 {"si_code", },
1959 {0}
1960};
1961
1962static PyStructSequence_Desc waitid_result_desc = {
1963 "waitid_result", /* name */
1964 waitid_result__doc__, /* doc */
1965 waitid_result_fields,
1966 5
1967};
1968static PyTypeObject WaitidResultType;
1969#endif
1970
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001971static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001972static PyTypeObject StatResultType;
1973static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001974#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001975static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001976#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001977static newfunc structseq_new;
1978
1979static PyObject *
1980statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1981{
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 PyStructSequence *result;
1983 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001984
Victor Stinner8c62be82010-05-06 00:08:46 +00001985 result = (PyStructSequence*)structseq_new(type, args, kwds);
1986 if (!result)
1987 return NULL;
1988 /* If we have been initialized from a tuple,
1989 st_?time might be set to None. Initialize it
1990 from the int slots. */
1991 for (i = 7; i <= 9; i++) {
1992 if (result->ob_item[i+3] == Py_None) {
1993 Py_DECREF(Py_None);
1994 Py_INCREF(result->ob_item[i]);
1995 result->ob_item[i+3] = result->ob_item[i];
1996 }
1997 }
1998 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001999}
2000
2001
Larry Hastings6fe20b32012-04-19 15:07:49 -07002002static PyObject *billion = NULL;
2003
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002004static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002005fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002006{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002007 PyObject *s = _PyLong_FromTime_t(sec);
2008 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2009 PyObject *s_in_ns = NULL;
2010 PyObject *ns_total = NULL;
2011 PyObject *float_s = NULL;
2012
2013 if (!(s && ns_fractional))
2014 goto exit;
2015
2016 s_in_ns = PyNumber_Multiply(s, billion);
2017 if (!s_in_ns)
2018 goto exit;
2019
2020 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2021 if (!ns_total)
2022 goto exit;
2023
Victor Stinner01b5aab2017-10-24 02:02:00 -07002024 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2025 if (!float_s) {
2026 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002027 }
2028
2029 PyStructSequence_SET_ITEM(v, index, s);
2030 PyStructSequence_SET_ITEM(v, index+3, float_s);
2031 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2032 s = NULL;
2033 float_s = NULL;
2034 ns_total = NULL;
2035exit:
2036 Py_XDECREF(s);
2037 Py_XDECREF(ns_fractional);
2038 Py_XDECREF(s_in_ns);
2039 Py_XDECREF(ns_total);
2040 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002041}
2042
Tim Peters5aa91602002-01-30 05:46:57 +00002043/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002044 (used by posix_stat() and posix_fstat()) */
2045static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002046_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002047{
Victor Stinner8c62be82010-05-06 00:08:46 +00002048 unsigned long ansec, mnsec, cnsec;
2049 PyObject *v = PyStructSequence_New(&StatResultType);
2050 if (v == NULL)
2051 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002052
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002054 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002055 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002056#ifdef MS_WINDOWS
2057 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002058#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002059 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002060#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002061 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002062#if defined(MS_WINDOWS)
2063 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2064 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2065#else
2066 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2067 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2068#endif
xdegaye50e86032017-05-22 11:15:08 +02002069 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2070 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002071
Martin v. Löwis14694662006-02-03 12:54:16 +00002072#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002073 ansec = st->st_atim.tv_nsec;
2074 mnsec = st->st_mtim.tv_nsec;
2075 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002076#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 ansec = st->st_atimespec.tv_nsec;
2078 mnsec = st->st_mtimespec.tv_nsec;
2079 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002080#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002081 ansec = st->st_atime_nsec;
2082 mnsec = st->st_mtime_nsec;
2083 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002084#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002085 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002086#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002087 fill_time(v, 7, st->st_atime, ansec);
2088 fill_time(v, 8, st->st_mtime, mnsec);
2089 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002090
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002091#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002092 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2093 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002094#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002095#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002096 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2097 PyLong_FromLong((long)st->st_blocks));
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_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2101 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002102#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002103#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002104 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2105 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002106#endif
2107#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002108 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002109 PyObject *val;
2110 unsigned long bsec,bnsec;
2111 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002112#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002113 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002114#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002115 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002116#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002117 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002118 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2119 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002120 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002121#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002122#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002123 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2124 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002125#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002126#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2127 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2128 PyLong_FromUnsignedLong(st->st_file_attributes));
2129#endif
jcea6c51d512018-01-28 14:00:08 +01002130#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2131 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2132 PyUnicode_FromString(st->st_fstype));
2133#endif
Fred Drake699f3522000-06-29 21:12:41 +00002134
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 if (PyErr_Occurred()) {
2136 Py_DECREF(v);
2137 return NULL;
2138 }
Fred Drake699f3522000-06-29 21:12:41 +00002139
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002141}
2142
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002143/* POSIX methods */
2144
Guido van Rossum94f6f721999-01-06 18:42:14 +00002145
2146static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002147posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002148 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002149{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002150 STRUCT_STAT st;
2151 int result;
2152
2153#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2154 if (follow_symlinks_specified(function_name, follow_symlinks))
2155 return NULL;
2156#endif
2157
2158 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2159 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2160 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2161 return NULL;
2162
2163 Py_BEGIN_ALLOW_THREADS
2164 if (path->fd != -1)
2165 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002166#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002167 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002168 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002169 else
Steve Dowercc16be82016-09-08 10:35:16 -07002170 result = win32_lstat(path->wide, &st);
2171#else
2172 else
2173#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002174 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2175 result = LSTAT(path->narrow, &st);
2176 else
Steve Dowercc16be82016-09-08 10:35:16 -07002177#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002178#ifdef HAVE_FSTATAT
2179 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2180 result = fstatat(dir_fd, path->narrow, &st,
2181 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2182 else
Steve Dowercc16be82016-09-08 10:35:16 -07002183#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002184 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002185#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002186 Py_END_ALLOW_THREADS
2187
Victor Stinner292c8352012-10-30 02:17:38 +01002188 if (result != 0) {
2189 return path_error(path);
2190 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002191
2192 return _pystat_fromstructstat(&st);
2193}
2194
Larry Hastings2f936352014-08-05 14:04:04 +10002195/*[python input]
2196
2197for s in """
2198
2199FACCESSAT
2200FCHMODAT
2201FCHOWNAT
2202FSTATAT
2203LINKAT
2204MKDIRAT
2205MKFIFOAT
2206MKNODAT
2207OPENAT
2208READLINKAT
2209SYMLINKAT
2210UNLINKAT
2211
2212""".strip().split():
2213 s = s.strip()
2214 print("""
2215#ifdef HAVE_{s}
2216 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002217#else
Larry Hastings2f936352014-08-05 14:04:04 +10002218 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002219#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002220""".rstrip().format(s=s))
2221
2222for s in """
2223
2224FCHDIR
2225FCHMOD
2226FCHOWN
2227FDOPENDIR
2228FEXECVE
2229FPATHCONF
2230FSTATVFS
2231FTRUNCATE
2232
2233""".strip().split():
2234 s = s.strip()
2235 print("""
2236#ifdef HAVE_{s}
2237 #define PATH_HAVE_{s} 1
2238#else
2239 #define PATH_HAVE_{s} 0
2240#endif
2241
2242""".rstrip().format(s=s))
2243[python start generated code]*/
2244
2245#ifdef HAVE_FACCESSAT
2246 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2247#else
2248 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2249#endif
2250
2251#ifdef HAVE_FCHMODAT
2252 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2253#else
2254 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2255#endif
2256
2257#ifdef HAVE_FCHOWNAT
2258 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2259#else
2260 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2261#endif
2262
2263#ifdef HAVE_FSTATAT
2264 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2265#else
2266 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2267#endif
2268
2269#ifdef HAVE_LINKAT
2270 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2271#else
2272 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2273#endif
2274
2275#ifdef HAVE_MKDIRAT
2276 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2277#else
2278 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2279#endif
2280
2281#ifdef HAVE_MKFIFOAT
2282 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2283#else
2284 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2285#endif
2286
2287#ifdef HAVE_MKNODAT
2288 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2289#else
2290 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2291#endif
2292
2293#ifdef HAVE_OPENAT
2294 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2295#else
2296 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2297#endif
2298
2299#ifdef HAVE_READLINKAT
2300 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2301#else
2302 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2303#endif
2304
2305#ifdef HAVE_SYMLINKAT
2306 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2307#else
2308 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2309#endif
2310
2311#ifdef HAVE_UNLINKAT
2312 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2313#else
2314 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2315#endif
2316
2317#ifdef HAVE_FCHDIR
2318 #define PATH_HAVE_FCHDIR 1
2319#else
2320 #define PATH_HAVE_FCHDIR 0
2321#endif
2322
2323#ifdef HAVE_FCHMOD
2324 #define PATH_HAVE_FCHMOD 1
2325#else
2326 #define PATH_HAVE_FCHMOD 0
2327#endif
2328
2329#ifdef HAVE_FCHOWN
2330 #define PATH_HAVE_FCHOWN 1
2331#else
2332 #define PATH_HAVE_FCHOWN 0
2333#endif
2334
2335#ifdef HAVE_FDOPENDIR
2336 #define PATH_HAVE_FDOPENDIR 1
2337#else
2338 #define PATH_HAVE_FDOPENDIR 0
2339#endif
2340
2341#ifdef HAVE_FEXECVE
2342 #define PATH_HAVE_FEXECVE 1
2343#else
2344 #define PATH_HAVE_FEXECVE 0
2345#endif
2346
2347#ifdef HAVE_FPATHCONF
2348 #define PATH_HAVE_FPATHCONF 1
2349#else
2350 #define PATH_HAVE_FPATHCONF 0
2351#endif
2352
2353#ifdef HAVE_FSTATVFS
2354 #define PATH_HAVE_FSTATVFS 1
2355#else
2356 #define PATH_HAVE_FSTATVFS 0
2357#endif
2358
2359#ifdef HAVE_FTRUNCATE
2360 #define PATH_HAVE_FTRUNCATE 1
2361#else
2362 #define PATH_HAVE_FTRUNCATE 0
2363#endif
2364/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002365
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002366#ifdef MS_WINDOWS
2367 #undef PATH_HAVE_FTRUNCATE
2368 #define PATH_HAVE_FTRUNCATE 1
2369#endif
Larry Hastings31826802013-10-19 00:09:25 -07002370
Larry Hastings61272b72014-01-07 12:41:53 -08002371/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002372
2373class path_t_converter(CConverter):
2374
2375 type = "path_t"
2376 impl_by_reference = True
2377 parse_by_reference = True
2378
2379 converter = 'path_converter'
2380
2381 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002382 # right now path_t doesn't support default values.
2383 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002384 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002385 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002386
Larry Hastings2f936352014-08-05 14:04:04 +10002387 if self.c_default not in (None, 'Py_None'):
2388 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002389
2390 self.nullable = nullable
2391 self.allow_fd = allow_fd
2392
Larry Hastings7726ac92014-01-31 22:03:12 -08002393 def pre_render(self):
2394 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002395 if isinstance(value, str):
2396 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002397 return str(int(bool(value)))
2398
2399 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002400 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002401 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002402 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002403 strify(self.nullable),
2404 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002405 )
2406
2407 def cleanup(self):
2408 return "path_cleanup(&" + self.name + ");\n"
2409
2410
2411class dir_fd_converter(CConverter):
2412 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002413
Larry Hastings2f936352014-08-05 14:04:04 +10002414 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002415 if self.default in (unspecified, None):
2416 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002417 if isinstance(requires, str):
2418 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2419 else:
2420 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002421
Larry Hastings2f936352014-08-05 14:04:04 +10002422class fildes_converter(CConverter):
2423 type = 'int'
2424 converter = 'fildes_converter'
2425
2426class uid_t_converter(CConverter):
2427 type = "uid_t"
2428 converter = '_Py_Uid_Converter'
2429
2430class gid_t_converter(CConverter):
2431 type = "gid_t"
2432 converter = '_Py_Gid_Converter'
2433
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002434class dev_t_converter(CConverter):
2435 type = 'dev_t'
2436 converter = '_Py_Dev_Converter'
2437
2438class dev_t_return_converter(unsigned_long_return_converter):
2439 type = 'dev_t'
2440 conversion_fn = '_PyLong_FromDev'
2441 unsigned_cast = '(dev_t)'
2442
Larry Hastings2f936352014-08-05 14:04:04 +10002443class FSConverter_converter(CConverter):
2444 type = 'PyObject *'
2445 converter = 'PyUnicode_FSConverter'
2446 def converter_init(self):
2447 if self.default is not unspecified:
2448 fail("FSConverter_converter does not support default values")
2449 self.c_default = 'NULL'
2450
2451 def cleanup(self):
2452 return "Py_XDECREF(" + self.name + ");\n"
2453
2454class pid_t_converter(CConverter):
2455 type = 'pid_t'
2456 format_unit = '" _Py_PARSE_PID "'
2457
2458class idtype_t_converter(int_converter):
2459 type = 'idtype_t'
2460
2461class id_t_converter(CConverter):
2462 type = 'id_t'
2463 format_unit = '" _Py_PARSE_PID "'
2464
Benjamin Petersonca470632016-09-06 13:47:26 -07002465class intptr_t_converter(CConverter):
2466 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002467 format_unit = '" _Py_PARSE_INTPTR "'
2468
2469class Py_off_t_converter(CConverter):
2470 type = 'Py_off_t'
2471 converter = 'Py_off_t_converter'
2472
2473class Py_off_t_return_converter(long_return_converter):
2474 type = 'Py_off_t'
2475 conversion_fn = 'PyLong_FromPy_off_t'
2476
2477class path_confname_converter(CConverter):
2478 type="int"
2479 converter="conv_path_confname"
2480
2481class confstr_confname_converter(path_confname_converter):
2482 converter='conv_confstr_confname'
2483
2484class sysconf_confname_converter(path_confname_converter):
2485 converter="conv_sysconf_confname"
2486
2487class sched_param_converter(CConverter):
2488 type = 'struct sched_param'
2489 converter = 'convert_sched_param'
2490 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002491
Larry Hastings61272b72014-01-07 12:41:53 -08002492[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002493/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002494
Larry Hastings61272b72014-01-07 12:41:53 -08002495/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002496
Larry Hastings2a727912014-01-16 11:32:01 -08002497os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002498
2499 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002500 Path to be examined; can be string, bytes, path-like object or
2501 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002502
2503 *
2504
Larry Hastings2f936352014-08-05 14:04:04 +10002505 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002506 If not None, it should be a file descriptor open to a directory,
2507 and path should be a relative string; path will then be relative to
2508 that directory.
2509
2510 follow_symlinks: bool = True
2511 If False, and the last element of the path is a symbolic link,
2512 stat will examine the symbolic link itself instead of the file
2513 the link points to.
2514
2515Perform a stat system call on the given path.
2516
2517dir_fd and follow_symlinks may not be implemented
2518 on your platform. If they are unavailable, using them will raise a
2519 NotImplementedError.
2520
2521It's an error to use dir_fd or follow_symlinks when specifying path as
2522 an open file descriptor.
2523
Larry Hastings61272b72014-01-07 12:41:53 -08002524[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002525
Larry Hastings31826802013-10-19 00:09:25 -07002526static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002527os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002528/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002529{
2530 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2531}
2532
Larry Hastings2f936352014-08-05 14:04:04 +10002533
2534/*[clinic input]
2535os.lstat
2536
2537 path : path_t
2538
2539 *
2540
2541 dir_fd : dir_fd(requires='fstatat') = None
2542
2543Perform a stat system call on the given path, without following symbolic links.
2544
2545Like stat(), but do not follow symbolic links.
2546Equivalent to stat(path, follow_symlinks=False).
2547[clinic start generated code]*/
2548
Larry Hastings2f936352014-08-05 14:04:04 +10002549static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002550os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2551/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002552{
2553 int follow_symlinks = 0;
2554 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2555}
Larry Hastings31826802013-10-19 00:09:25 -07002556
Larry Hastings2f936352014-08-05 14:04:04 +10002557
Larry Hastings61272b72014-01-07 12:41:53 -08002558/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002559os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002560
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002561 path: path_t
2562 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002563
2564 mode: int
2565 Operating-system mode bitfield. Can be F_OK to test existence,
2566 or the inclusive-OR of R_OK, W_OK, and X_OK.
2567
2568 *
2569
Larry Hastings2f936352014-08-05 14:04:04 +10002570 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002571 If not None, it should be a file descriptor open to a directory,
2572 and path should be relative; path will then be relative to that
2573 directory.
2574
2575 effective_ids: bool = False
2576 If True, access will use the effective uid/gid instead of
2577 the real uid/gid.
2578
2579 follow_symlinks: bool = True
2580 If False, and the last element of the path is a symbolic link,
2581 access will examine the symbolic link itself instead of the file
2582 the link points to.
2583
2584Use the real uid/gid to test for access to a path.
2585
2586{parameters}
2587dir_fd, effective_ids, and follow_symlinks may not be implemented
2588 on your platform. If they are unavailable, using them will raise a
2589 NotImplementedError.
2590
2591Note that most operations will use the effective uid/gid, therefore this
2592 routine can be used in a suid/sgid environment to test if the invoking user
2593 has the specified access to the path.
2594
Larry Hastings61272b72014-01-07 12:41:53 -08002595[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002596
Larry Hastings2f936352014-08-05 14:04:04 +10002597static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002598os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002599 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002600/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002601{
Larry Hastings2f936352014-08-05 14:04:04 +10002602 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002603
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002604#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002605 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002606#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002607 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002608#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002609
Larry Hastings9cf065c2012-06-22 16:30:09 -07002610#ifndef HAVE_FACCESSAT
2611 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002612 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002613
2614 if (effective_ids) {
2615 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002616 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002617 }
2618#endif
2619
2620#ifdef MS_WINDOWS
2621 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002622 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002623 Py_END_ALLOW_THREADS
2624
2625 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002626 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002627 * * we didn't get a -1, and
2628 * * write access wasn't requested,
2629 * * or the file isn't read-only,
2630 * * or it's a directory.
2631 * (Directories cannot be read-only on Windows.)
2632 */
Larry Hastings2f936352014-08-05 14:04:04 +10002633 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002634 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002635 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002636 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002637#else
2638
2639 Py_BEGIN_ALLOW_THREADS
2640#ifdef HAVE_FACCESSAT
2641 if ((dir_fd != DEFAULT_DIR_FD) ||
2642 effective_ids ||
2643 !follow_symlinks) {
2644 int flags = 0;
2645 if (!follow_symlinks)
2646 flags |= AT_SYMLINK_NOFOLLOW;
2647 if (effective_ids)
2648 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002649 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002650 }
2651 else
2652#endif
Larry Hastings31826802013-10-19 00:09:25 -07002653 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002654 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002655 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002656#endif
2657
Larry Hastings9cf065c2012-06-22 16:30:09 -07002658 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002659}
2660
Guido van Rossumd371ff11999-01-25 16:12:23 +00002661#ifndef F_OK
2662#define F_OK 0
2663#endif
2664#ifndef R_OK
2665#define R_OK 4
2666#endif
2667#ifndef W_OK
2668#define W_OK 2
2669#endif
2670#ifndef X_OK
2671#define X_OK 1
2672#endif
2673
Larry Hastings31826802013-10-19 00:09:25 -07002674
Guido van Rossumd371ff11999-01-25 16:12:23 +00002675#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002676/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002677os.ttyname -> DecodeFSDefault
2678
2679 fd: int
2680 Integer file descriptor handle.
2681
2682 /
2683
2684Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002685[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002686
Larry Hastings31826802013-10-19 00:09:25 -07002687static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002688os_ttyname_impl(PyObject *module, int fd)
2689/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002690{
2691 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002692
Larry Hastings31826802013-10-19 00:09:25 -07002693 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002694 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002695 posix_error();
2696 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002697}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002698#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002699
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002700#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002701/*[clinic input]
2702os.ctermid
2703
2704Return the name of the controlling terminal for this process.
2705[clinic start generated code]*/
2706
Larry Hastings2f936352014-08-05 14:04:04 +10002707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002708os_ctermid_impl(PyObject *module)
2709/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002710{
Victor Stinner8c62be82010-05-06 00:08:46 +00002711 char *ret;
2712 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002713
Greg Wardb48bc172000-03-01 21:51:56 +00002714#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002715 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002716#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002717 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002718#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002719 if (ret == NULL)
2720 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002721 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002722}
Larry Hastings2f936352014-08-05 14:04:04 +10002723#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002724
Larry Hastings2f936352014-08-05 14:04:04 +10002725
2726/*[clinic input]
2727os.chdir
2728
2729 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2730
2731Change the current working directory to the specified path.
2732
2733path may always be specified as a string.
2734On some platforms, path may also be specified as an open file descriptor.
2735 If this functionality is unavailable, using it raises an exception.
2736[clinic start generated code]*/
2737
Larry Hastings2f936352014-08-05 14:04:04 +10002738static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002739os_chdir_impl(PyObject *module, path_t *path)
2740/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002741{
2742 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002743
2744 Py_BEGIN_ALLOW_THREADS
2745#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002746 /* on unix, success = 0, on windows, success = !0 */
2747 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002748#else
2749#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002750 if (path->fd != -1)
2751 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002752 else
2753#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002754 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002755#endif
2756 Py_END_ALLOW_THREADS
2757
2758 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002759 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002760 }
2761
Larry Hastings2f936352014-08-05 14:04:04 +10002762 Py_RETURN_NONE;
2763}
2764
2765
2766#ifdef HAVE_FCHDIR
2767/*[clinic input]
2768os.fchdir
2769
2770 fd: fildes
2771
2772Change to the directory of the given file descriptor.
2773
2774fd must be opened on a directory, not a file.
2775Equivalent to os.chdir(fd).
2776
2777[clinic start generated code]*/
2778
Fred Drake4d1e64b2002-04-15 19:40:07 +00002779static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002780os_fchdir_impl(PyObject *module, int fd)
2781/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002782{
Larry Hastings2f936352014-08-05 14:04:04 +10002783 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002784}
2785#endif /* HAVE_FCHDIR */
2786
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002787
Larry Hastings2f936352014-08-05 14:04:04 +10002788/*[clinic input]
2789os.chmod
2790
2791 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2792 Path to be modified. May always be specified as a str or bytes.
2793 On some platforms, path may also be specified as an open file descriptor.
2794 If this functionality is unavailable, using it raises an exception.
2795
2796 mode: int
2797 Operating-system mode bitfield.
2798
2799 *
2800
2801 dir_fd : dir_fd(requires='fchmodat') = None
2802 If not None, it should be a file descriptor open to a directory,
2803 and path should be relative; path will then be relative to that
2804 directory.
2805
2806 follow_symlinks: bool = True
2807 If False, and the last element of the path is a symbolic link,
2808 chmod will modify the symbolic link itself instead of the file
2809 the link points to.
2810
2811Change the access permissions of a file.
2812
2813It is an error to use dir_fd or follow_symlinks when specifying path as
2814 an open file descriptor.
2815dir_fd and follow_symlinks may not be implemented on your platform.
2816 If they are unavailable, using them will raise a NotImplementedError.
2817
2818[clinic start generated code]*/
2819
Larry Hastings2f936352014-08-05 14:04:04 +10002820static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002821os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002822 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002823/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002824{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002825 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002826
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002827#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002828 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002830
Larry Hastings9cf065c2012-06-22 16:30:09 -07002831#ifdef HAVE_FCHMODAT
2832 int fchmodat_nofollow_unsupported = 0;
2833#endif
2834
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2836 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002837 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002838#endif
2839
2840#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002841 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002842 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002843 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844 result = 0;
2845 else {
2846 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002847 attr &= ~FILE_ATTRIBUTE_READONLY;
2848 else
2849 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002850 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002851 }
2852 Py_END_ALLOW_THREADS
2853
2854 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002855 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002856 }
2857#else /* MS_WINDOWS */
2858 Py_BEGIN_ALLOW_THREADS
2859#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002860 if (path->fd != -1)
2861 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002862 else
2863#endif
2864#ifdef HAVE_LCHMOD
2865 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002866 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002867 else
2868#endif
2869#ifdef HAVE_FCHMODAT
2870 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2871 /*
2872 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2873 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002874 * and then says it isn't implemented yet.
2875 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002876 *
2877 * Once it is supported, os.chmod will automatically
2878 * support dir_fd and follow_symlinks=False. (Hopefully.)
2879 * Until then, we need to be careful what exception we raise.
2880 */
Larry Hastings2f936352014-08-05 14:04:04 +10002881 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002882 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2883 /*
2884 * But wait! We can't throw the exception without allowing threads,
2885 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2886 */
2887 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002888 result &&
2889 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2890 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002891 }
2892 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002893#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002894 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002895 Py_END_ALLOW_THREADS
2896
2897 if (result) {
2898#ifdef HAVE_FCHMODAT
2899 if (fchmodat_nofollow_unsupported) {
2900 if (dir_fd != DEFAULT_DIR_FD)
2901 dir_fd_and_follow_symlinks_invalid("chmod",
2902 dir_fd, follow_symlinks);
2903 else
2904 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002905 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002906 }
2907 else
2908#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002909 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002910 }
2911#endif
2912
Larry Hastings2f936352014-08-05 14:04:04 +10002913 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002914}
2915
Larry Hastings9cf065c2012-06-22 16:30:09 -07002916
Christian Heimes4e30a842007-11-30 22:12:06 +00002917#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002918/*[clinic input]
2919os.fchmod
2920
2921 fd: int
2922 mode: int
2923
2924Change the access permissions of the file given by file descriptor fd.
2925
2926Equivalent to os.chmod(fd, mode).
2927[clinic start generated code]*/
2928
Larry Hastings2f936352014-08-05 14:04:04 +10002929static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002930os_fchmod_impl(PyObject *module, int fd, int mode)
2931/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002932{
2933 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002934 int async_err = 0;
2935
2936 do {
2937 Py_BEGIN_ALLOW_THREADS
2938 res = fchmod(fd, mode);
2939 Py_END_ALLOW_THREADS
2940 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2941 if (res != 0)
2942 return (!async_err) ? posix_error() : NULL;
2943
Victor Stinner8c62be82010-05-06 00:08:46 +00002944 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002945}
2946#endif /* HAVE_FCHMOD */
2947
Larry Hastings2f936352014-08-05 14:04:04 +10002948
Christian Heimes4e30a842007-11-30 22:12:06 +00002949#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002950/*[clinic input]
2951os.lchmod
2952
2953 path: path_t
2954 mode: int
2955
2956Change the access permissions of a file, without following symbolic links.
2957
2958If path is a symlink, this affects the link itself rather than the target.
2959Equivalent to chmod(path, mode, follow_symlinks=False)."
2960[clinic start generated code]*/
2961
Larry Hastings2f936352014-08-05 14:04:04 +10002962static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002963os_lchmod_impl(PyObject *module, path_t *path, int mode)
2964/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002965{
Victor Stinner8c62be82010-05-06 00:08:46 +00002966 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002967 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002968 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002969 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002970 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002971 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002972 return NULL;
2973 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002974 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002975}
2976#endif /* HAVE_LCHMOD */
2977
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002978
Thomas Wouterscf297e42007-02-23 15:07:44 +00002979#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002980/*[clinic input]
2981os.chflags
2982
2983 path: path_t
2984 flags: unsigned_long(bitwise=True)
2985 follow_symlinks: bool=True
2986
2987Set file flags.
2988
2989If follow_symlinks is False, and the last element of the path is a symbolic
2990 link, chflags will change flags on the symbolic link itself instead of the
2991 file the link points to.
2992follow_symlinks may not be implemented on your platform. If it is
2993unavailable, using it will raise a NotImplementedError.
2994
2995[clinic start generated code]*/
2996
Larry Hastings2f936352014-08-05 14:04:04 +10002997static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002998os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002999 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003000/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003001{
3002 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003003
3004#ifndef HAVE_LCHFLAGS
3005 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003006 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003007#endif
3008
Victor Stinner8c62be82010-05-06 00:08:46 +00003009 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003010#ifdef HAVE_LCHFLAGS
3011 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003012 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003013 else
3014#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003015 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003016 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003017
Larry Hastings2f936352014-08-05 14:04:04 +10003018 if (result)
3019 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003020
Larry Hastings2f936352014-08-05 14:04:04 +10003021 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003022}
3023#endif /* HAVE_CHFLAGS */
3024
Larry Hastings2f936352014-08-05 14:04:04 +10003025
Thomas Wouterscf297e42007-02-23 15:07:44 +00003026#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003027/*[clinic input]
3028os.lchflags
3029
3030 path: path_t
3031 flags: unsigned_long(bitwise=True)
3032
3033Set file flags.
3034
3035This function will not follow symbolic links.
3036Equivalent to chflags(path, flags, follow_symlinks=False).
3037[clinic start generated code]*/
3038
Larry Hastings2f936352014-08-05 14:04:04 +10003039static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003040os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3041/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003042{
Victor Stinner8c62be82010-05-06 00:08:46 +00003043 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003044 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003045 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003046 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003047 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003048 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003049 }
Victor Stinner292c8352012-10-30 02:17:38 +01003050 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003051}
3052#endif /* HAVE_LCHFLAGS */
3053
Larry Hastings2f936352014-08-05 14:04:04 +10003054
Martin v. Löwis244edc82001-10-04 22:44:26 +00003055#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003056/*[clinic input]
3057os.chroot
3058 path: path_t
3059
3060Change root directory to path.
3061
3062[clinic start generated code]*/
3063
Larry Hastings2f936352014-08-05 14:04:04 +10003064static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003065os_chroot_impl(PyObject *module, path_t *path)
3066/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003067{
3068 int res;
3069 Py_BEGIN_ALLOW_THREADS
3070 res = chroot(path->narrow);
3071 Py_END_ALLOW_THREADS
3072 if (res < 0)
3073 return path_error(path);
3074 Py_RETURN_NONE;
3075}
3076#endif /* HAVE_CHROOT */
3077
Martin v. Löwis244edc82001-10-04 22:44:26 +00003078
Guido van Rossum21142a01999-01-08 21:05:37 +00003079#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003080/*[clinic input]
3081os.fsync
3082
3083 fd: fildes
3084
3085Force write of fd to disk.
3086[clinic start generated code]*/
3087
Larry Hastings2f936352014-08-05 14:04:04 +10003088static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003089os_fsync_impl(PyObject *module, int fd)
3090/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003091{
3092 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003093}
3094#endif /* HAVE_FSYNC */
3095
Larry Hastings2f936352014-08-05 14:04:04 +10003096
Ross Lagerwall7807c352011-03-17 20:20:30 +02003097#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003098/*[clinic input]
3099os.sync
3100
3101Force write of everything to disk.
3102[clinic start generated code]*/
3103
Larry Hastings2f936352014-08-05 14:04:04 +10003104static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003105os_sync_impl(PyObject *module)
3106/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003107{
3108 Py_BEGIN_ALLOW_THREADS
3109 sync();
3110 Py_END_ALLOW_THREADS
3111 Py_RETURN_NONE;
3112}
Larry Hastings2f936352014-08-05 14:04:04 +10003113#endif /* HAVE_SYNC */
3114
Ross Lagerwall7807c352011-03-17 20:20:30 +02003115
Guido van Rossum21142a01999-01-08 21:05:37 +00003116#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003117#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003118extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3119#endif
3120
Larry Hastings2f936352014-08-05 14:04:04 +10003121/*[clinic input]
3122os.fdatasync
3123
3124 fd: fildes
3125
3126Force write of fd to disk without forcing update of metadata.
3127[clinic start generated code]*/
3128
Larry Hastings2f936352014-08-05 14:04:04 +10003129static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003130os_fdatasync_impl(PyObject *module, int fd)
3131/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003132{
3133 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003134}
3135#endif /* HAVE_FDATASYNC */
3136
3137
Fredrik Lundh10723342000-07-10 16:38:09 +00003138#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003139/*[clinic input]
3140os.chown
3141
3142 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3143 Path to be examined; can be string, bytes, or open-file-descriptor int.
3144
3145 uid: uid_t
3146
3147 gid: gid_t
3148
3149 *
3150
3151 dir_fd : dir_fd(requires='fchownat') = None
3152 If not None, it should be a file descriptor open to a directory,
3153 and path should be relative; path will then be relative to that
3154 directory.
3155
3156 follow_symlinks: bool = True
3157 If False, and the last element of the path is a symbolic link,
3158 stat will examine the symbolic link itself instead of the file
3159 the link points to.
3160
3161Change the owner and group id of path to the numeric uid and gid.\
3162
3163path may always be specified as a string.
3164On some platforms, path may also be specified as an open file descriptor.
3165 If this functionality is unavailable, using it raises an exception.
3166If dir_fd is not None, it should be a file descriptor open to a directory,
3167 and path should be relative; path will then be relative to that directory.
3168If follow_symlinks is False, and the last element of the path is a symbolic
3169 link, chown will modify the symbolic link itself instead of the file the
3170 link points to.
3171It is an error to use dir_fd or follow_symlinks when specifying path as
3172 an open file descriptor.
3173dir_fd and follow_symlinks may not be implemented on your platform.
3174 If they are unavailable, using them will raise a NotImplementedError.
3175
3176[clinic start generated code]*/
3177
Larry Hastings2f936352014-08-05 14:04:04 +10003178static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003179os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003180 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003181/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003182{
3183 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003184
3185#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3186 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003187 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003188#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003189 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3190 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3191 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192
3193#ifdef __APPLE__
3194 /*
3195 * This is for Mac OS X 10.3, which doesn't have lchown.
3196 * (But we still have an lchown symbol because of weak-linking.)
3197 * It doesn't have fchownat either. So there's no possibility
3198 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003199 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003200 if ((!follow_symlinks) && (lchown == NULL)) {
3201 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003202 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003203 }
3204#endif
3205
Victor Stinner8c62be82010-05-06 00:08:46 +00003206 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003207#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003208 if (path->fd != -1)
3209 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003210 else
3211#endif
3212#ifdef HAVE_LCHOWN
3213 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003214 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003215 else
3216#endif
3217#ifdef HAVE_FCHOWNAT
3218 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003219 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003220 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3221 else
3222#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003223 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003224 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003225
Larry Hastings2f936352014-08-05 14:04:04 +10003226 if (result)
3227 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003228
Larry Hastings2f936352014-08-05 14:04:04 +10003229 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003230}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003231#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003232
Larry Hastings2f936352014-08-05 14:04:04 +10003233
Christian Heimes4e30a842007-11-30 22:12:06 +00003234#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003235/*[clinic input]
3236os.fchown
3237
3238 fd: int
3239 uid: uid_t
3240 gid: gid_t
3241
3242Change the owner and group id of the file specified by file descriptor.
3243
3244Equivalent to os.chown(fd, uid, gid).
3245
3246[clinic start generated code]*/
3247
Larry Hastings2f936352014-08-05 14:04:04 +10003248static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003249os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3250/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003251{
Victor Stinner8c62be82010-05-06 00:08:46 +00003252 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003253 int async_err = 0;
3254
3255 do {
3256 Py_BEGIN_ALLOW_THREADS
3257 res = fchown(fd, uid, gid);
3258 Py_END_ALLOW_THREADS
3259 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3260 if (res != 0)
3261 return (!async_err) ? posix_error() : NULL;
3262
Victor Stinner8c62be82010-05-06 00:08:46 +00003263 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003264}
3265#endif /* HAVE_FCHOWN */
3266
Larry Hastings2f936352014-08-05 14:04:04 +10003267
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003268#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003269/*[clinic input]
3270os.lchown
3271
3272 path : path_t
3273 uid: uid_t
3274 gid: gid_t
3275
3276Change the owner and group id of path to the numeric uid and gid.
3277
3278This function will not follow symbolic links.
3279Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3280[clinic start generated code]*/
3281
Larry Hastings2f936352014-08-05 14:04:04 +10003282static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003283os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3284/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003285{
Victor Stinner8c62be82010-05-06 00:08:46 +00003286 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003288 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003289 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003290 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003291 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003292 }
Larry Hastings2f936352014-08-05 14:04:04 +10003293 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003294}
3295#endif /* HAVE_LCHOWN */
3296
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003297
Barry Warsaw53699e91996-12-10 23:23:01 +00003298static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003299posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003300{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003301 char *buf, *tmpbuf;
3302 char *cwd;
3303 const size_t chunk = 1024;
3304 size_t buflen = 0;
3305 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003306
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003307#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003308 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003309 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003310 wchar_t *wbuf2 = wbuf;
3311 PyObject *resobj;
3312 DWORD len;
3313 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003314 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003315 /* If the buffer is large enough, len does not include the
3316 terminating \0. If the buffer is too small, len includes
3317 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003318 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003319 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003320 if (wbuf2)
3321 len = GetCurrentDirectoryW(len, wbuf2);
3322 }
3323 Py_END_ALLOW_THREADS
3324 if (!wbuf2) {
3325 PyErr_NoMemory();
3326 return NULL;
3327 }
3328 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003329 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003330 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003331 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003332 }
3333 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003334 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003335 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003336 return resobj;
3337 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003338
3339 if (win32_warn_bytes_api())
3340 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003341#endif
3342
Victor Stinner4403d7d2015-04-25 00:16:10 +02003343 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003344 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003345 do {
3346 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003347#ifdef MS_WINDOWS
3348 if (buflen > INT_MAX) {
3349 PyErr_NoMemory();
3350 break;
3351 }
3352#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003353 tmpbuf = PyMem_RawRealloc(buf, buflen);
3354 if (tmpbuf == NULL)
3355 break;
3356
3357 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003358#ifdef MS_WINDOWS
3359 cwd = getcwd(buf, (int)buflen);
3360#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003361 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003362#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003363 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003364 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003365
3366 if (cwd == NULL) {
3367 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003369 }
3370
Victor Stinner8c62be82010-05-06 00:08:46 +00003371 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003372 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3373 else
3374 obj = PyUnicode_DecodeFSDefault(buf);
3375 PyMem_RawFree(buf);
3376
3377 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003378}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003379
Larry Hastings2f936352014-08-05 14:04:04 +10003380
3381/*[clinic input]
3382os.getcwd
3383
3384Return a unicode string representing the current working directory.
3385[clinic start generated code]*/
3386
Larry Hastings2f936352014-08-05 14:04:04 +10003387static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003388os_getcwd_impl(PyObject *module)
3389/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003390{
3391 return posix_getcwd(0);
3392}
3393
Larry Hastings2f936352014-08-05 14:04:04 +10003394
3395/*[clinic input]
3396os.getcwdb
3397
3398Return a bytes string representing the current working directory.
3399[clinic start generated code]*/
3400
Larry Hastings2f936352014-08-05 14:04:04 +10003401static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003402os_getcwdb_impl(PyObject *module)
3403/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003404{
3405 return posix_getcwd(1);
3406}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003407
Larry Hastings2f936352014-08-05 14:04:04 +10003408
Larry Hastings9cf065c2012-06-22 16:30:09 -07003409#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3410#define HAVE_LINK 1
3411#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003412
Guido van Rossumb6775db1994-08-01 11:34:53 +00003413#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003414/*[clinic input]
3415
3416os.link
3417
3418 src : path_t
3419 dst : path_t
3420 *
3421 src_dir_fd : dir_fd = None
3422 dst_dir_fd : dir_fd = None
3423 follow_symlinks: bool = True
3424
3425Create a hard link to a file.
3426
3427If either src_dir_fd or dst_dir_fd is not None, it should be a file
3428 descriptor open to a directory, and the respective path string (src or dst)
3429 should be relative; the path will then be relative to that directory.
3430If follow_symlinks is False, and the last element of src is a symbolic
3431 link, link will create a link to the symbolic link itself instead of the
3432 file the link points to.
3433src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3434 platform. If they are unavailable, using them will raise a
3435 NotImplementedError.
3436[clinic start generated code]*/
3437
Larry Hastings2f936352014-08-05 14:04:04 +10003438static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003439os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003440 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003441/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003442{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003444 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003445#else
3446 int result;
3447#endif
3448
Larry Hastings9cf065c2012-06-22 16:30:09 -07003449#ifndef HAVE_LINKAT
3450 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3451 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003452 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453 }
3454#endif
3455
Steve Dowercc16be82016-09-08 10:35:16 -07003456#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003457 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458 PyErr_SetString(PyExc_NotImplementedError,
3459 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003460 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461 }
Steve Dowercc16be82016-09-08 10:35:16 -07003462#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003463
Brian Curtin1b9df392010-11-24 20:24:31 +00003464#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003466 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003467 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003468
Larry Hastings2f936352014-08-05 14:04:04 +10003469 if (!result)
3470 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471#else
3472 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003473#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003474 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3475 (dst_dir_fd != DEFAULT_DIR_FD) ||
3476 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003477 result = linkat(src_dir_fd, src->narrow,
3478 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3480 else
Steve Dowercc16be82016-09-08 10:35:16 -07003481#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003482 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003483 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003484
Larry Hastings2f936352014-08-05 14:04:04 +10003485 if (result)
3486 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003487#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003488
Larry Hastings2f936352014-08-05 14:04:04 +10003489 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003490}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003491#endif
3492
Brian Curtin1b9df392010-11-24 20:24:31 +00003493
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003494#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003495static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003496_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003497{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003498 PyObject *v;
3499 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3500 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003501 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003503 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003504 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003505
Steve Dowercc16be82016-09-08 10:35:16 -07003506 WIN32_FIND_DATAW wFileData;
3507 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003508
Steve Dowercc16be82016-09-08 10:35:16 -07003509 if (!path->wide) { /* Default arg: "." */
3510 po_wchars = L".";
3511 len = 1;
3512 } else {
3513 po_wchars = path->wide;
3514 len = wcslen(path->wide);
3515 }
3516 /* The +5 is so we can append "\\*.*\0" */
3517 wnamebuf = PyMem_New(wchar_t, len + 5);
3518 if (!wnamebuf) {
3519 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 }
Steve Dowercc16be82016-09-08 10:35:16 -07003522 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003523 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003524 wchar_t wch = wnamebuf[len-1];
3525 if (wch != SEP && wch != ALTSEP && wch != L':')
3526 wnamebuf[len++] = SEP;
3527 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003528 }
Steve Dowercc16be82016-09-08 10:35:16 -07003529 if ((list = PyList_New(0)) == NULL) {
3530 goto exit;
3531 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003532 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003533 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003534 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 if (hFindFile == INVALID_HANDLE_VALUE) {
3536 int error = GetLastError();
3537 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003538 goto exit;
3539 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003540 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003541 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003542 }
3543 do {
3544 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003545 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3546 wcscmp(wFileData.cFileName, L"..") != 0) {
3547 v = PyUnicode_FromWideChar(wFileData.cFileName,
3548 wcslen(wFileData.cFileName));
3549 if (path->narrow && v) {
3550 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3551 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003552 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003553 Py_DECREF(list);
3554 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 break;
3556 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003559 Py_DECREF(list);
3560 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003561 break;
3562 }
3563 Py_DECREF(v);
3564 }
3565 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003566 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003567 Py_END_ALLOW_THREADS
3568 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3569 it got to the end of the directory. */
3570 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003571 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003572 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 }
3575 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003576
Larry Hastings9cf065c2012-06-22 16:30:09 -07003577exit:
3578 if (hFindFile != INVALID_HANDLE_VALUE) {
3579 if (FindClose(hFindFile) == FALSE) {
3580 if (list != NULL) {
3581 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003582 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003583 }
3584 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003586 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003587
Larry Hastings9cf065c2012-06-22 16:30:09 -07003588 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003589} /* end of _listdir_windows_no_opendir */
3590
3591#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3592
3593static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003594_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003595{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003596 PyObject *v;
3597 DIR *dirp = NULL;
3598 struct dirent *ep;
3599 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003600#ifdef HAVE_FDOPENDIR
3601 int fd = -1;
3602#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003603
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003605#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003606 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003607 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003608 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003609 if (fd == -1)
3610 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003611
Larry Hastingsfdaea062012-06-25 04:42:23 -07003612 return_str = 1;
3613
Larry Hastings9cf065c2012-06-22 16:30:09 -07003614 Py_BEGIN_ALLOW_THREADS
3615 dirp = fdopendir(fd);
3616 Py_END_ALLOW_THREADS
3617 }
3618 else
3619#endif
3620 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003621 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003622 if (path->narrow) {
3623 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003624 /* only return bytes if they specified a bytes-like object */
3625 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003626 }
3627 else {
3628 name = ".";
3629 return_str = 1;
3630 }
3631
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632 Py_BEGIN_ALLOW_THREADS
3633 dirp = opendir(name);
3634 Py_END_ALLOW_THREADS
3635 }
3636
3637 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003638 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003639#ifdef HAVE_FDOPENDIR
3640 if (fd != -1) {
3641 Py_BEGIN_ALLOW_THREADS
3642 close(fd);
3643 Py_END_ALLOW_THREADS
3644 }
3645#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003646 goto exit;
3647 }
3648 if ((list = PyList_New(0)) == NULL) {
3649 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003650 }
3651 for (;;) {
3652 errno = 0;
3653 Py_BEGIN_ALLOW_THREADS
3654 ep = readdir(dirp);
3655 Py_END_ALLOW_THREADS
3656 if (ep == NULL) {
3657 if (errno == 0) {
3658 break;
3659 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003660 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003661 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003662 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003663 }
3664 }
3665 if (ep->d_name[0] == '.' &&
3666 (NAMLEN(ep) == 1 ||
3667 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3668 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003669 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003670 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3671 else
3672 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003673 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003674 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003675 break;
3676 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003677 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003678 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003679 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003680 break;
3681 }
3682 Py_DECREF(v);
3683 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003684
Larry Hastings9cf065c2012-06-22 16:30:09 -07003685exit:
3686 if (dirp != NULL) {
3687 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003688#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003689 if (fd > -1)
3690 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003691#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003692 closedir(dirp);
3693 Py_END_ALLOW_THREADS
3694 }
3695
Larry Hastings9cf065c2012-06-22 16:30:09 -07003696 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003697} /* end of _posix_listdir */
3698#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003699
Larry Hastings2f936352014-08-05 14:04:04 +10003700
3701/*[clinic input]
3702os.listdir
3703
3704 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3705
3706Return a list containing the names of the files in the directory.
3707
3708path can be specified as either str or bytes. If path is bytes,
3709 the filenames returned will also be bytes; in all other circumstances
3710 the filenames returned will be str.
3711If path is None, uses the path='.'.
3712On some platforms, path may also be specified as an open file descriptor;\
3713 the file descriptor must refer to a directory.
3714 If this functionality is unavailable, using it raises NotImplementedError.
3715
3716The list is in arbitrary order. It does not include the special
3717entries '.' and '..' even if they are present in the directory.
3718
3719
3720[clinic start generated code]*/
3721
Larry Hastings2f936352014-08-05 14:04:04 +10003722static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003723os_listdir_impl(PyObject *module, path_t *path)
3724/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003725{
3726#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3727 return _listdir_windows_no_opendir(path, NULL);
3728#else
3729 return _posix_listdir(path, NULL);
3730#endif
3731}
3732
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003733#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003734/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003735/*[clinic input]
3736os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003737
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003738 path: path_t
3739 /
3740
3741[clinic start generated code]*/
3742
3743static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003744os__getfullpathname_impl(PyObject *module, path_t *path)
3745/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003746{
Steve Dowercc16be82016-09-08 10:35:16 -07003747 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3748 wchar_t *wtemp;
3749 DWORD result;
3750 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003751
Steve Dowercc16be82016-09-08 10:35:16 -07003752 result = GetFullPathNameW(path->wide,
3753 Py_ARRAY_LENGTH(woutbuf),
3754 woutbuf, &wtemp);
3755 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3756 woutbufp = PyMem_New(wchar_t, result);
3757 if (!woutbufp)
3758 return PyErr_NoMemory();
3759 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003760 }
Steve Dowercc16be82016-09-08 10:35:16 -07003761 if (result) {
3762 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3763 if (path->narrow)
3764 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3765 } else
3766 v = win32_error_object("GetFullPathNameW", path->object);
3767 if (woutbufp != woutbuf)
3768 PyMem_Free(woutbufp);
3769 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003770}
Brian Curtind40e6f72010-07-08 21:39:08 +00003771
Brian Curtind25aef52011-06-13 15:16:04 -05003772
Larry Hastings2f936352014-08-05 14:04:04 +10003773/*[clinic input]
3774os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003775
Steve Dower23ad6d02018-02-22 10:39:10 -08003776 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003777 /
3778
3779A helper function for samepath on windows.
3780[clinic start generated code]*/
3781
Larry Hastings2f936352014-08-05 14:04:04 +10003782static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003783os__getfinalpathname_impl(PyObject *module, path_t *path)
3784/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003785{
3786 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003787 wchar_t buf[MAXPATHLEN], *target_path = buf;
3788 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003789 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003790 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003791
Steve Dower23ad6d02018-02-22 10:39:10 -08003792 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003793 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003794 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003795 0, /* desired access */
3796 0, /* share mode */
3797 NULL, /* security attributes */
3798 OPEN_EXISTING,
3799 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3800 FILE_FLAG_BACKUP_SEMANTICS,
3801 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003802 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003803
Steve Dower23ad6d02018-02-22 10:39:10 -08003804 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003805 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003806 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003807
3808 /* We have a good handle to the target, use it to determine the
3809 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003810 while (1) {
3811 Py_BEGIN_ALLOW_THREADS
3812 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3813 buf_size, VOLUME_NAME_DOS);
3814 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003815
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003816 if (!result_length) {
3817 result = win32_error_object("GetFinalPathNameByHandleW",
3818 path->object);
3819 goto cleanup;
3820 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003821
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003822 if (result_length < buf_size) {
3823 break;
3824 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003825
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003826 wchar_t *tmp;
3827 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3828 result_length * sizeof(*tmp));
3829 if (!tmp) {
3830 result = PyErr_NoMemory();
3831 goto cleanup;
3832 }
3833
3834 buf_size = result_length;
3835 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003836 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003837
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003838 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dower23ad6d02018-02-22 10:39:10 -08003839 if (path->narrow)
3840 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dower23ad6d02018-02-22 10:39:10 -08003841
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003842cleanup:
3843 if (target_path != buf) {
3844 PyMem_Free(target_path);
3845 }
3846 CloseHandle(hFile);
3847 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003848}
Brian Curtin62857742010-09-06 17:07:27 +00003849
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003850/*[clinic input]
3851os._isdir
3852
3853 path: path_t
3854 /
3855
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003856Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003857[clinic start generated code]*/
3858
Brian Curtin9c669cc2011-06-08 18:17:18 -05003859static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003860os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003861/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003862{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003863 DWORD attributes;
3864
Steve Dowerb22a6772016-07-17 20:49:38 -07003865 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003866 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003867 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003868
Brian Curtin9c669cc2011-06-08 18:17:18 -05003869 if (attributes == INVALID_FILE_ATTRIBUTES)
3870 Py_RETURN_FALSE;
3871
Brian Curtin9c669cc2011-06-08 18:17:18 -05003872 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3873 Py_RETURN_TRUE;
3874 else
3875 Py_RETURN_FALSE;
3876}
Tim Golden6b528062013-08-01 12:44:00 +01003877
Tim Golden6b528062013-08-01 12:44:00 +01003878
Larry Hastings2f936352014-08-05 14:04:04 +10003879/*[clinic input]
3880os._getvolumepathname
3881
Steve Dower23ad6d02018-02-22 10:39:10 -08003882 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003883
3884A helper function for ismount on Win32.
3885[clinic start generated code]*/
3886
Larry Hastings2f936352014-08-05 14:04:04 +10003887static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003888os__getvolumepathname_impl(PyObject *module, path_t *path)
3889/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003890{
3891 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003892 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003893 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003894 BOOL ret;
3895
Tim Golden6b528062013-08-01 12:44:00 +01003896 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003897 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003898
Victor Stinner850a18e2017-10-24 16:53:32 -07003899 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003900 PyErr_SetString(PyExc_OverflowError, "path too long");
3901 return NULL;
3902 }
3903
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003904 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003905 if (mountpath == NULL)
3906 return PyErr_NoMemory();
3907
3908 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003909 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003910 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003911 Py_END_ALLOW_THREADS
3912
3913 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003914 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003915 goto exit;
3916 }
3917 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003918 if (path->narrow)
3919 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003920
3921exit:
3922 PyMem_Free(mountpath);
3923 return result;
3924}
Tim Golden6b528062013-08-01 12:44:00 +01003925
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003926#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003927
Larry Hastings2f936352014-08-05 14:04:04 +10003928
3929/*[clinic input]
3930os.mkdir
3931
3932 path : path_t
3933
3934 mode: int = 0o777
3935
3936 *
3937
3938 dir_fd : dir_fd(requires='mkdirat') = None
3939
3940# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3941
3942Create a directory.
3943
3944If dir_fd is not None, it should be a file descriptor open to a directory,
3945 and path should be relative; path will then be relative to that directory.
3946dir_fd may not be implemented on your platform.
3947 If it is unavailable, using it will raise a NotImplementedError.
3948
3949The mode argument is ignored on Windows.
3950[clinic start generated code]*/
3951
Larry Hastings2f936352014-08-05 14:04:04 +10003952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003953os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3954/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003955{
3956 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003957
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003958#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003959 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003960 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003961 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003962
Larry Hastings2f936352014-08-05 14:04:04 +10003963 if (!result)
3964 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003965#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003966 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003967#if HAVE_MKDIRAT
3968 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003969 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003970 else
3971#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003972#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003973 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003974#else
Larry Hastings2f936352014-08-05 14:04:04 +10003975 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003976#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003977 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003978 if (result < 0)
3979 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003980#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003981 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003982}
3983
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003984
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003985/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3986#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003987#include <sys/resource.h>
3988#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003989
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003990
3991#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003992/*[clinic input]
3993os.nice
3994
3995 increment: int
3996 /
3997
3998Add increment to the priority of process and return the new priority.
3999[clinic start generated code]*/
4000
Larry Hastings2f936352014-08-05 14:04:04 +10004001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004002os_nice_impl(PyObject *module, int increment)
4003/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004004{
4005 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004006
Victor Stinner8c62be82010-05-06 00:08:46 +00004007 /* There are two flavours of 'nice': one that returns the new
4008 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004009 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004010 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004011
Victor Stinner8c62be82010-05-06 00:08:46 +00004012 If we are of the nice family that returns the new priority, we
4013 need to clear errno before the call, and check if errno is filled
4014 before calling posix_error() on a returnvalue of -1, because the
4015 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004016
Victor Stinner8c62be82010-05-06 00:08:46 +00004017 errno = 0;
4018 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004019#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004020 if (value == 0)
4021 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004022#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004023 if (value == -1 && errno != 0)
4024 /* either nice() or getpriority() returned an error */
4025 return posix_error();
4026 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004027}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004028#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004029
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004030
4031#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004032/*[clinic input]
4033os.getpriority
4034
4035 which: int
4036 who: int
4037
4038Return program scheduling priority.
4039[clinic start generated code]*/
4040
Larry Hastings2f936352014-08-05 14:04:04 +10004041static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004042os_getpriority_impl(PyObject *module, int which, int who)
4043/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004044{
4045 int retval;
4046
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004047 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004048 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004049 if (errno != 0)
4050 return posix_error();
4051 return PyLong_FromLong((long)retval);
4052}
4053#endif /* HAVE_GETPRIORITY */
4054
4055
4056#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004057/*[clinic input]
4058os.setpriority
4059
4060 which: int
4061 who: int
4062 priority: int
4063
4064Set program scheduling priority.
4065[clinic start generated code]*/
4066
Larry Hastings2f936352014-08-05 14:04:04 +10004067static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004068os_setpriority_impl(PyObject *module, int which, int who, int priority)
4069/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004070{
4071 int retval;
4072
4073 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004074 if (retval == -1)
4075 return posix_error();
4076 Py_RETURN_NONE;
4077}
4078#endif /* HAVE_SETPRIORITY */
4079
4080
Barry Warsaw53699e91996-12-10 23:23:01 +00004081static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004082internal_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 +00004083{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004084 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004085 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004086
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004087#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004088 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004089 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004090#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004091 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004092#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004093
Larry Hastings9cf065c2012-06-22 16:30:09 -07004094 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4095 (dst_dir_fd != DEFAULT_DIR_FD);
4096#ifndef HAVE_RENAMEAT
4097 if (dir_fd_specified) {
4098 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004099 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004100 }
4101#endif
4102
Larry Hastings9cf065c2012-06-22 16:30:09 -07004103#ifdef MS_WINDOWS
4104 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004105 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004106 Py_END_ALLOW_THREADS
4107
Larry Hastings2f936352014-08-05 14:04:04 +10004108 if (!result)
4109 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004110
4111#else
Steve Dowercc16be82016-09-08 10:35:16 -07004112 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4113 PyErr_Format(PyExc_ValueError,
4114 "%s: src and dst must be the same type", function_name);
4115 return NULL;
4116 }
4117
Larry Hastings9cf065c2012-06-22 16:30:09 -07004118 Py_BEGIN_ALLOW_THREADS
4119#ifdef HAVE_RENAMEAT
4120 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004121 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122 else
4123#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004124 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004125 Py_END_ALLOW_THREADS
4126
Larry Hastings2f936352014-08-05 14:04:04 +10004127 if (result)
4128 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004129#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004130 Py_RETURN_NONE;
4131}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004132
Larry Hastings2f936352014-08-05 14:04:04 +10004133
4134/*[clinic input]
4135os.rename
4136
4137 src : path_t
4138 dst : path_t
4139 *
4140 src_dir_fd : dir_fd = None
4141 dst_dir_fd : dir_fd = None
4142
4143Rename a file or directory.
4144
4145If either src_dir_fd or dst_dir_fd is not None, it should be a file
4146 descriptor open to a directory, and the respective path string (src or dst)
4147 should be relative; the path will then be relative to that directory.
4148src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4149 If they are unavailable, using them will raise a NotImplementedError.
4150[clinic start generated code]*/
4151
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004152static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004153os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004154 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004155/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004156{
Larry Hastings2f936352014-08-05 14:04:04 +10004157 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004158}
4159
Larry Hastings2f936352014-08-05 14:04:04 +10004160
4161/*[clinic input]
4162os.replace = os.rename
4163
4164Rename a file or directory, overwriting the destination.
4165
4166If either src_dir_fd or dst_dir_fd is not None, it should be a file
4167 descriptor open to a directory, and the respective path string (src or dst)
4168 should be relative; the path will then be relative to that directory.
4169src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4170 If they are unavailable, using them will raise a NotImplementedError."
4171[clinic start generated code]*/
4172
Larry Hastings2f936352014-08-05 14:04:04 +10004173static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004174os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4175 int dst_dir_fd)
4176/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004177{
4178 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4179}
4180
4181
4182/*[clinic input]
4183os.rmdir
4184
4185 path: path_t
4186 *
4187 dir_fd: dir_fd(requires='unlinkat') = None
4188
4189Remove a directory.
4190
4191If dir_fd is not None, it should be a file descriptor open to a directory,
4192 and path should be relative; path will then be relative to that directory.
4193dir_fd may not be implemented on your platform.
4194 If it is unavailable, using it will raise a NotImplementedError.
4195[clinic start generated code]*/
4196
Larry Hastings2f936352014-08-05 14:04:04 +10004197static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004198os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4199/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004200{
4201 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004202
4203 Py_BEGIN_ALLOW_THREADS
4204#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004205 /* Windows, success=1, UNIX, success=0 */
4206 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004207#else
4208#ifdef HAVE_UNLINKAT
4209 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004210 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004211 else
4212#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004213 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004214#endif
4215 Py_END_ALLOW_THREADS
4216
Larry Hastings2f936352014-08-05 14:04:04 +10004217 if (result)
4218 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004219
Larry Hastings2f936352014-08-05 14:04:04 +10004220 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004221}
4222
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004223
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004224#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004225#ifdef MS_WINDOWS
4226/*[clinic input]
4227os.system -> long
4228
4229 command: Py_UNICODE
4230
4231Execute the command in a subshell.
4232[clinic start generated code]*/
4233
Larry Hastings2f936352014-08-05 14:04:04 +10004234static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004235os_system_impl(PyObject *module, Py_UNICODE *command)
4236/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004237{
4238 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004239 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004240 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004241 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004242 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004243 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004244 return result;
4245}
4246#else /* MS_WINDOWS */
4247/*[clinic input]
4248os.system -> long
4249
4250 command: FSConverter
4251
4252Execute the command in a subshell.
4253[clinic start generated code]*/
4254
Larry Hastings2f936352014-08-05 14:04:04 +10004255static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004256os_system_impl(PyObject *module, PyObject *command)
4257/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004258{
4259 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004260 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004261 Py_BEGIN_ALLOW_THREADS
4262 result = system(bytes);
4263 Py_END_ALLOW_THREADS
4264 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004265}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004266#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004267#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004268
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004269
Larry Hastings2f936352014-08-05 14:04:04 +10004270/*[clinic input]
4271os.umask
4272
4273 mask: int
4274 /
4275
4276Set the current numeric umask and return the previous umask.
4277[clinic start generated code]*/
4278
Larry Hastings2f936352014-08-05 14:04:04 +10004279static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004280os_umask_impl(PyObject *module, int mask)
4281/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004282{
4283 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004284 if (i < 0)
4285 return posix_error();
4286 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004287}
4288
Brian Curtind40e6f72010-07-08 21:39:08 +00004289#ifdef MS_WINDOWS
4290
4291/* override the default DeleteFileW behavior so that directory
4292symlinks can be removed with this function, the same as with
4293Unix symlinks */
4294BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4295{
4296 WIN32_FILE_ATTRIBUTE_DATA info;
4297 WIN32_FIND_DATAW find_data;
4298 HANDLE find_data_handle;
4299 int is_directory = 0;
4300 int is_link = 0;
4301
4302 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4303 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004304
Brian Curtind40e6f72010-07-08 21:39:08 +00004305 /* Get WIN32_FIND_DATA structure for the path to determine if
4306 it is a symlink */
4307 if(is_directory &&
4308 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4309 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4310
4311 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004312 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4313 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4314 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4315 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004316 FindClose(find_data_handle);
4317 }
4318 }
4319 }
4320
4321 if (is_directory && is_link)
4322 return RemoveDirectoryW(lpFileName);
4323
4324 return DeleteFileW(lpFileName);
4325}
4326#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004328
Larry Hastings2f936352014-08-05 14:04:04 +10004329/*[clinic input]
4330os.unlink
4331
4332 path: path_t
4333 *
4334 dir_fd: dir_fd(requires='unlinkat')=None
4335
4336Remove a file (same as remove()).
4337
4338If dir_fd is not None, it should be a file descriptor open to a directory,
4339 and path should be relative; path will then be relative to that directory.
4340dir_fd may not be implemented on your platform.
4341 If it is unavailable, using it will raise a NotImplementedError.
4342
4343[clinic start generated code]*/
4344
Larry Hastings2f936352014-08-05 14:04:04 +10004345static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004346os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4347/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004348{
4349 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004350
4351 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004352 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004353#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004354 /* Windows, success=1, UNIX, success=0 */
4355 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004356#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004357#ifdef HAVE_UNLINKAT
4358 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004359 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004360 else
4361#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004362 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004363#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004364 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004365 Py_END_ALLOW_THREADS
4366
Larry Hastings2f936352014-08-05 14:04:04 +10004367 if (result)
4368 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004369
Larry Hastings2f936352014-08-05 14:04:04 +10004370 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004371}
4372
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004373
Larry Hastings2f936352014-08-05 14:04:04 +10004374/*[clinic input]
4375os.remove = os.unlink
4376
4377Remove a file (same as unlink()).
4378
4379If dir_fd is not None, it should be a file descriptor open to a directory,
4380 and path should be relative; path will then be relative to that directory.
4381dir_fd may not be implemented on your platform.
4382 If it is unavailable, using it will raise a NotImplementedError.
4383[clinic start generated code]*/
4384
Larry Hastings2f936352014-08-05 14:04:04 +10004385static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004386os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4387/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004388{
4389 return os_unlink_impl(module, path, dir_fd);
4390}
4391
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004392
Larry Hastings605a62d2012-06-24 04:33:36 -07004393static PyStructSequence_Field uname_result_fields[] = {
4394 {"sysname", "operating system name"},
4395 {"nodename", "name of machine on network (implementation-defined)"},
4396 {"release", "operating system release"},
4397 {"version", "operating system version"},
4398 {"machine", "hardware identifier"},
4399 {NULL}
4400};
4401
4402PyDoc_STRVAR(uname_result__doc__,
4403"uname_result: Result from os.uname().\n\n\
4404This object may be accessed either as a tuple of\n\
4405 (sysname, nodename, release, version, machine),\n\
4406or via the attributes sysname, nodename, release, version, and machine.\n\
4407\n\
4408See os.uname for more information.");
4409
4410static PyStructSequence_Desc uname_result_desc = {
4411 "uname_result", /* name */
4412 uname_result__doc__, /* doc */
4413 uname_result_fields,
4414 5
4415};
4416
4417static PyTypeObject UnameResultType;
4418
4419
4420#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004421/*[clinic input]
4422os.uname
4423
4424Return an object identifying the current operating system.
4425
4426The object behaves like a named tuple with the following fields:
4427 (sysname, nodename, release, version, machine)
4428
4429[clinic start generated code]*/
4430
Larry Hastings2f936352014-08-05 14:04:04 +10004431static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004432os_uname_impl(PyObject *module)
4433/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004434{
Victor Stinner8c62be82010-05-06 00:08:46 +00004435 struct utsname u;
4436 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004437 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004438
Victor Stinner8c62be82010-05-06 00:08:46 +00004439 Py_BEGIN_ALLOW_THREADS
4440 res = uname(&u);
4441 Py_END_ALLOW_THREADS
4442 if (res < 0)
4443 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004444
4445 value = PyStructSequence_New(&UnameResultType);
4446 if (value == NULL)
4447 return NULL;
4448
4449#define SET(i, field) \
4450 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004451 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004452 if (!o) { \
4453 Py_DECREF(value); \
4454 return NULL; \
4455 } \
4456 PyStructSequence_SET_ITEM(value, i, o); \
4457 } \
4458
4459 SET(0, u.sysname);
4460 SET(1, u.nodename);
4461 SET(2, u.release);
4462 SET(3, u.version);
4463 SET(4, u.machine);
4464
4465#undef SET
4466
4467 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004468}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004469#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004470
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004471
Larry Hastings9cf065c2012-06-22 16:30:09 -07004472
4473typedef struct {
4474 int now;
4475 time_t atime_s;
4476 long atime_ns;
4477 time_t mtime_s;
4478 long mtime_ns;
4479} utime_t;
4480
4481/*
Victor Stinner484df002014-10-09 13:52:31 +02004482 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004483 * they also intentionally leak the declaration of a pointer named "time"
4484 */
4485#define UTIME_TO_TIMESPEC \
4486 struct timespec ts[2]; \
4487 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004488 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004489 time = NULL; \
4490 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004491 ts[0].tv_sec = ut->atime_s; \
4492 ts[0].tv_nsec = ut->atime_ns; \
4493 ts[1].tv_sec = ut->mtime_s; \
4494 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004495 time = ts; \
4496 } \
4497
4498#define UTIME_TO_TIMEVAL \
4499 struct timeval tv[2]; \
4500 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004501 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004502 time = NULL; \
4503 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004504 tv[0].tv_sec = ut->atime_s; \
4505 tv[0].tv_usec = ut->atime_ns / 1000; \
4506 tv[1].tv_sec = ut->mtime_s; \
4507 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004508 time = tv; \
4509 } \
4510
4511#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004512 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004513 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004514 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004515 time = NULL; \
4516 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004517 u.actime = ut->atime_s; \
4518 u.modtime = ut->mtime_s; \
4519 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004520 }
4521
4522#define UTIME_TO_TIME_T \
4523 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004524 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004525 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004526 time = NULL; \
4527 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004528 timet[0] = ut->atime_s; \
4529 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004530 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531 } \
4532
4533
Victor Stinner528a9ab2015-09-03 21:30:26 +02004534#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004535
4536static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004537utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538{
4539#ifdef HAVE_UTIMENSAT
4540 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4541 UTIME_TO_TIMESPEC;
4542 return utimensat(dir_fd, path, time, flags);
4543#elif defined(HAVE_FUTIMESAT)
4544 UTIME_TO_TIMEVAL;
4545 /*
4546 * follow_symlinks will never be false here;
4547 * we only allow !follow_symlinks and dir_fd together
4548 * if we have utimensat()
4549 */
4550 assert(follow_symlinks);
4551 return futimesat(dir_fd, path, time);
4552#endif
4553}
4554
Larry Hastings2f936352014-08-05 14:04:04 +10004555 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4556#else
4557 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004558#endif
4559
Victor Stinner528a9ab2015-09-03 21:30:26 +02004560#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004561
4562static int
Victor Stinner484df002014-10-09 13:52:31 +02004563utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004564{
4565#ifdef HAVE_FUTIMENS
4566 UTIME_TO_TIMESPEC;
4567 return futimens(fd, time);
4568#else
4569 UTIME_TO_TIMEVAL;
4570 return futimes(fd, time);
4571#endif
4572}
4573
Larry Hastings2f936352014-08-05 14:04:04 +10004574 #define PATH_UTIME_HAVE_FD 1
4575#else
4576 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004577#endif
4578
Victor Stinner5ebae872015-09-22 01:29:33 +02004579#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4580# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4581#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004582
Victor Stinner4552ced2015-09-21 22:37:15 +02004583#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004584
4585static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004586utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004587{
4588#ifdef HAVE_UTIMENSAT
4589 UTIME_TO_TIMESPEC;
4590 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4591#else
4592 UTIME_TO_TIMEVAL;
4593 return lutimes(path, time);
4594#endif
4595}
4596
4597#endif
4598
4599#ifndef MS_WINDOWS
4600
4601static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004602utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004603{
4604#ifdef HAVE_UTIMENSAT
4605 UTIME_TO_TIMESPEC;
4606 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4607#elif defined(HAVE_UTIMES)
4608 UTIME_TO_TIMEVAL;
4609 return utimes(path, time);
4610#elif defined(HAVE_UTIME_H)
4611 UTIME_TO_UTIMBUF;
4612 return utime(path, time);
4613#else
4614 UTIME_TO_TIME_T;
4615 return utime(path, time);
4616#endif
4617}
4618
4619#endif
4620
Larry Hastings76ad59b2012-05-03 00:30:07 -07004621static int
4622split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4623{
4624 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004625 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004626 divmod = PyNumber_Divmod(py_long, billion);
4627 if (!divmod)
4628 goto exit;
4629 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4630 if ((*s == -1) && PyErr_Occurred())
4631 goto exit;
4632 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004633 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004634 goto exit;
4635
4636 result = 1;
4637exit:
4638 Py_XDECREF(divmod);
4639 return result;
4640}
4641
Larry Hastings2f936352014-08-05 14:04:04 +10004642
4643/*[clinic input]
4644os.utime
4645
4646 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4647 times: object = NULL
4648 *
4649 ns: object = NULL
4650 dir_fd: dir_fd(requires='futimensat') = None
4651 follow_symlinks: bool=True
4652
Martin Panter0ff89092015-09-09 01:56:53 +00004653# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004654
4655Set the access and modified time of path.
4656
4657path may always be specified as a string.
4658On some platforms, path may also be specified as an open file descriptor.
4659 If this functionality is unavailable, using it raises an exception.
4660
4661If times is not None, it must be a tuple (atime, mtime);
4662 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004663If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004664 atime_ns and mtime_ns should be expressed as integer nanoseconds
4665 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004666If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004667Specifying tuples for both times and ns is an error.
4668
4669If dir_fd is not None, it should be a file descriptor open to a directory,
4670 and path should be relative; path will then be relative to that directory.
4671If follow_symlinks is False, and the last element of the path is a symbolic
4672 link, utime will modify the symbolic link itself instead of the file the
4673 link points to.
4674It is an error to use dir_fd or follow_symlinks when specifying path
4675 as an open file descriptor.
4676dir_fd and follow_symlinks may not be available on your platform.
4677 If they are unavailable, using them will raise a NotImplementedError.
4678
4679[clinic start generated code]*/
4680
Larry Hastings2f936352014-08-05 14:04:04 +10004681static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004682os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4683 int dir_fd, int follow_symlinks)
4684/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004685{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686#ifdef MS_WINDOWS
4687 HANDLE hFile;
4688 FILETIME atime, mtime;
4689#else
4690 int result;
4691#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004692
Larry Hastings9cf065c2012-06-22 16:30:09 -07004693 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004694 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004695
Christian Heimesb3c87242013-08-01 00:08:16 +02004696 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004697
Larry Hastings9cf065c2012-06-22 16:30:09 -07004698 if (times && (times != Py_None) && ns) {
4699 PyErr_SetString(PyExc_ValueError,
4700 "utime: you may specify either 'times'"
4701 " or 'ns' but not both");
4702 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004703 }
4704
4705 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004706 time_t a_sec, m_sec;
4707 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004708 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004709 PyErr_SetString(PyExc_TypeError,
4710 "utime: 'times' must be either"
4711 " a tuple of two ints or None");
4712 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004713 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004714 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004715 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004716 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004717 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004718 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004719 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004720 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004721 utime.atime_s = a_sec;
4722 utime.atime_ns = a_nsec;
4723 utime.mtime_s = m_sec;
4724 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004725 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004726 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004727 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004728 PyErr_SetString(PyExc_TypeError,
4729 "utime: 'ns' must be a tuple of two ints");
4730 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004731 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004733 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004734 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004735 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004736 &utime.mtime_s, &utime.mtime_ns)) {
4737 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004738 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004739 }
4740 else {
4741 /* times and ns are both None/unspecified. use "now". */
4742 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004743 }
4744
Victor Stinner4552ced2015-09-21 22:37:15 +02004745#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004746 if (follow_symlinks_specified("utime", follow_symlinks))
4747 goto exit;
4748#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004749
Larry Hastings2f936352014-08-05 14:04:04 +10004750 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4751 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4752 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004754
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755#if !defined(HAVE_UTIMENSAT)
4756 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004757 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 "utime: cannot use dir_fd and follow_symlinks "
4759 "together on this platform");
4760 goto exit;
4761 }
4762#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004763
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004764#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004766 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4767 NULL, OPEN_EXISTING,
4768 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004769 Py_END_ALLOW_THREADS
4770 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004771 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004772 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004773 }
4774
Larry Hastings9cf065c2012-06-22 16:30:09 -07004775 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004776 GetSystemTimeAsFileTime(&mtime);
4777 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004778 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004780 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4781 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004782 }
4783 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4784 /* Avoid putting the file name into the error here,
4785 as that may confuse the user into believing that
4786 something is wrong with the file, when it also
4787 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004788 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004789 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004790 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004791#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004792 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004793
Victor Stinner4552ced2015-09-21 22:37:15 +02004794#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004795 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004796 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004797 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004798#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004799
Victor Stinner528a9ab2015-09-03 21:30:26 +02004800#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004801 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004802 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004803 else
4804#endif
4805
Victor Stinner528a9ab2015-09-03 21:30:26 +02004806#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004807 if (path->fd != -1)
4808 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004809 else
4810#endif
4811
Larry Hastings2f936352014-08-05 14:04:04 +10004812 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004813
4814 Py_END_ALLOW_THREADS
4815
4816 if (result < 0) {
4817 /* see previous comment about not putting filename in error here */
4818 return_value = posix_error();
4819 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004820 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004821
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004822#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004823
4824 Py_INCREF(Py_None);
4825 return_value = Py_None;
4826
4827exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004828#ifdef MS_WINDOWS
4829 if (hFile != INVALID_HANDLE_VALUE)
4830 CloseHandle(hFile);
4831#endif
4832 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004833}
4834
Guido van Rossum3b066191991-06-04 19:40:25 +00004835/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004836
Larry Hastings2f936352014-08-05 14:04:04 +10004837
4838/*[clinic input]
4839os._exit
4840
4841 status: int
4842
4843Exit to the system with specified status, without normal exit processing.
4844[clinic start generated code]*/
4845
Larry Hastings2f936352014-08-05 14:04:04 +10004846static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004847os__exit_impl(PyObject *module, int status)
4848/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004849{
4850 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004851 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004852}
4853
Steve Dowercc16be82016-09-08 10:35:16 -07004854#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4855#define EXECV_CHAR wchar_t
4856#else
4857#define EXECV_CHAR char
4858#endif
4859
Martin v. Löwis114619e2002-10-07 06:44:21 +00004860#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4861static void
Steve Dowercc16be82016-09-08 10:35:16 -07004862free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004863{
Victor Stinner8c62be82010-05-06 00:08:46 +00004864 Py_ssize_t i;
4865 for (i = 0; i < count; i++)
4866 PyMem_Free(array[i]);
4867 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004868}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004869
Berker Peksag81816462016-09-15 20:19:47 +03004870static int
4871fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004872{
Victor Stinner8c62be82010-05-06 00:08:46 +00004873 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004874 PyObject *ub;
4875 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004876#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004877 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004878 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004879 *out = PyUnicode_AsWideCharString(ub, &size);
4880 if (*out)
4881 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004882#else
Berker Peksag81816462016-09-15 20:19:47 +03004883 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004884 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004885 size = PyBytes_GET_SIZE(ub);
4886 *out = PyMem_Malloc(size + 1);
4887 if (*out) {
4888 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4889 result = 1;
4890 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004891 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004892#endif
Berker Peksag81816462016-09-15 20:19:47 +03004893 Py_DECREF(ub);
4894 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004895}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004896#endif
4897
Ross Lagerwall7807c352011-03-17 20:20:30 +02004898#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004899static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004900parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4901{
Victor Stinner8c62be82010-05-06 00:08:46 +00004902 Py_ssize_t i, pos, envc;
4903 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004904 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004905 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004906
Victor Stinner8c62be82010-05-06 00:08:46 +00004907 i = PyMapping_Size(env);
4908 if (i < 0)
4909 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004910 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004911 if (envlist == NULL) {
4912 PyErr_NoMemory();
4913 return NULL;
4914 }
4915 envc = 0;
4916 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004917 if (!keys)
4918 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004919 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004920 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 goto error;
4922 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4923 PyErr_Format(PyExc_TypeError,
4924 "env.keys() or env.values() is not a list");
4925 goto error;
4926 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004927
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 for (pos = 0; pos < i; pos++) {
4929 key = PyList_GetItem(keys, pos);
4930 val = PyList_GetItem(vals, pos);
4931 if (!key || !val)
4932 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004933
Berker Peksag81816462016-09-15 20:19:47 +03004934#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4935 if (!PyUnicode_FSDecoder(key, &key2))
4936 goto error;
4937 if (!PyUnicode_FSDecoder(val, &val2)) {
4938 Py_DECREF(key2);
4939 goto error;
4940 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004941 /* Search from index 1 because on Windows starting '=' is allowed for
4942 defining hidden environment variables. */
4943 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4944 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4945 {
4946 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004947 Py_DECREF(key2);
4948 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004949 goto error;
4950 }
Berker Peksag81816462016-09-15 20:19:47 +03004951 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4952#else
4953 if (!PyUnicode_FSConverter(key, &key2))
4954 goto error;
4955 if (!PyUnicode_FSConverter(val, &val2)) {
4956 Py_DECREF(key2);
4957 goto error;
4958 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004959 if (PyBytes_GET_SIZE(key2) == 0 ||
4960 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4961 {
4962 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004963 Py_DECREF(key2);
4964 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004965 goto error;
4966 }
Berker Peksag81816462016-09-15 20:19:47 +03004967 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4968 PyBytes_AS_STRING(val2));
4969#endif
4970 Py_DECREF(key2);
4971 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004972 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004974
4975 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4976 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004977 goto error;
4978 }
Berker Peksag81816462016-09-15 20:19:47 +03004979
Steve Dowercc16be82016-09-08 10:35:16 -07004980 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 }
4982 Py_DECREF(vals);
4983 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004984
Victor Stinner8c62be82010-05-06 00:08:46 +00004985 envlist[envc] = 0;
4986 *envc_ptr = envc;
4987 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004988
4989error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004990 Py_XDECREF(keys);
4991 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004992 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004993 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004994}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004995
Steve Dowercc16be82016-09-08 10:35:16 -07004996static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004997parse_arglist(PyObject* argv, Py_ssize_t *argc)
4998{
4999 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005000 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005001 if (argvlist == NULL) {
5002 PyErr_NoMemory();
5003 return NULL;
5004 }
5005 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005006 PyObject* item = PySequence_ITEM(argv, i);
5007 if (item == NULL)
5008 goto fail;
5009 if (!fsconvert_strdup(item, &argvlist[i])) {
5010 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005011 goto fail;
5012 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005013 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005014 }
5015 argvlist[*argc] = NULL;
5016 return argvlist;
5017fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005018 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005019 free_string_array(argvlist, *argc);
5020 return NULL;
5021}
Steve Dowercc16be82016-09-08 10:35:16 -07005022
Ross Lagerwall7807c352011-03-17 20:20:30 +02005023#endif
5024
Larry Hastings2f936352014-08-05 14:04:04 +10005025
Ross Lagerwall7807c352011-03-17 20:20:30 +02005026#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005027/*[clinic input]
5028os.execv
5029
Steve Dowercc16be82016-09-08 10:35:16 -07005030 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005031 Path of executable file.
5032 argv: object
5033 Tuple or list of strings.
5034 /
5035
5036Execute an executable path with arguments, replacing current process.
5037[clinic start generated code]*/
5038
Larry Hastings2f936352014-08-05 14:04:04 +10005039static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005040os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5041/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005042{
Steve Dowercc16be82016-09-08 10:35:16 -07005043 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005044 Py_ssize_t argc;
5045
5046 /* execv has two arguments: (path, argv), where
5047 argv is a list or tuple of strings. */
5048
Ross Lagerwall7807c352011-03-17 20:20:30 +02005049 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5050 PyErr_SetString(PyExc_TypeError,
5051 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005052 return NULL;
5053 }
5054 argc = PySequence_Size(argv);
5055 if (argc < 1) {
5056 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005057 return NULL;
5058 }
5059
5060 argvlist = parse_arglist(argv, &argc);
5061 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005062 return NULL;
5063 }
Steve Dowerbce26262016-11-19 19:17:26 -08005064 if (!argvlist[0][0]) {
5065 PyErr_SetString(PyExc_ValueError,
5066 "execv() arg 2 first element cannot be empty");
5067 free_string_array(argvlist, argc);
5068 return NULL;
5069 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005070
Steve Dowerbce26262016-11-19 19:17:26 -08005071 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005072#ifdef HAVE_WEXECV
5073 _wexecv(path->wide, argvlist);
5074#else
5075 execv(path->narrow, argvlist);
5076#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005077 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005078
5079 /* If we get here it's definitely an error */
5080
5081 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005082 return posix_error();
5083}
5084
Larry Hastings2f936352014-08-05 14:04:04 +10005085
5086/*[clinic input]
5087os.execve
5088
5089 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5090 Path of executable file.
5091 argv: object
5092 Tuple or list of strings.
5093 env: object
5094 Dictionary of strings mapping to strings.
5095
5096Execute an executable path with arguments, replacing current process.
5097[clinic start generated code]*/
5098
Larry Hastings2f936352014-08-05 14:04:04 +10005099static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005100os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5101/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005102{
Steve Dowercc16be82016-09-08 10:35:16 -07005103 EXECV_CHAR **argvlist = NULL;
5104 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005105 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005106
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 /* execve has three arguments: (path, argv, env), where
5108 argv is a list or tuple of strings and env is a dictionary
5109 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005110
Ross Lagerwall7807c352011-03-17 20:20:30 +02005111 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005112 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005113 "execve: argv must be a tuple or list");
5114 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005115 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005116 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005117 if (argc < 1) {
5118 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5119 return NULL;
5120 }
5121
Victor Stinner8c62be82010-05-06 00:08:46 +00005122 if (!PyMapping_Check(env)) {
5123 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005124 "execve: environment must be a mapping object");
5125 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005127
Ross Lagerwall7807c352011-03-17 20:20:30 +02005128 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005129 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005130 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 }
Steve Dowerbce26262016-11-19 19:17:26 -08005132 if (!argvlist[0][0]) {
5133 PyErr_SetString(PyExc_ValueError,
5134 "execve: argv first element cannot be empty");
5135 goto fail;
5136 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005137
Victor Stinner8c62be82010-05-06 00:08:46 +00005138 envlist = parse_envlist(env, &envc);
5139 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005140 goto fail;
5141
Steve Dowerbce26262016-11-19 19:17:26 -08005142 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005143#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005144 if (path->fd > -1)
5145 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005146 else
5147#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005148#ifdef HAVE_WEXECV
5149 _wexecve(path->wide, argvlist, envlist);
5150#else
Larry Hastings2f936352014-08-05 14:04:04 +10005151 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005152#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005153 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005154
5155 /* If we get here it's definitely an error */
5156
Larry Hastings2f936352014-08-05 14:04:04 +10005157 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005158
Steve Dowercc16be82016-09-08 10:35:16 -07005159 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005160 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005161 if (argvlist)
5162 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005163 return NULL;
5164}
Steve Dowercc16be82016-09-08 10:35:16 -07005165
Larry Hastings9cf065c2012-06-22 16:30:09 -07005166#endif /* HAVE_EXECV */
5167
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005168#ifdef HAVE_POSIX_SPAWN
5169
5170enum posix_spawn_file_actions_identifier {
5171 POSIX_SPAWN_OPEN,
5172 POSIX_SPAWN_CLOSE,
5173 POSIX_SPAWN_DUP2
5174};
5175
Serhiy Storchakaef347532018-05-01 16:45:04 +03005176static int
5177parse_file_actions(PyObject *file_actions,
5178 posix_spawn_file_actions_t *file_actionsp)
5179{
5180 PyObject *seq;
5181 PyObject *file_action = NULL;
5182 PyObject *tag_obj;
5183
5184 seq = PySequence_Fast(file_actions,
5185 "file_actions must be a sequence or None");
5186 if (seq == NULL) {
5187 return -1;
5188 }
5189
5190 errno = posix_spawn_file_actions_init(file_actionsp);
5191 if (errno) {
5192 posix_error();
5193 Py_DECREF(seq);
5194 return -1;
5195 }
5196
5197 for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
5198 file_action = PySequence_Fast_GET_ITEM(seq, i);
5199 Py_INCREF(file_action);
5200 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5201 PyErr_SetString(PyExc_TypeError,
5202 "Each file_actions element must be a non-empty tuple");
5203 goto fail;
5204 }
5205 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5206 if (tag == -1 && PyErr_Occurred()) {
5207 goto fail;
5208 }
5209
5210 /* Populate the file_actions object */
5211 switch (tag) {
5212 case POSIX_SPAWN_OPEN: {
5213 int fd, oflag;
5214 PyObject *path;
5215 unsigned long mode;
5216 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5217 ";A open file_action tuple must have 5 elements",
5218 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5219 &oflag, &mode))
5220 {
5221 goto fail;
5222 }
5223 errno = posix_spawn_file_actions_addopen(file_actionsp,
5224 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
5225 Py_DECREF(path); /* addopen copied it. */
5226 if (errno) {
5227 posix_error();
5228 goto fail;
5229 }
5230 break;
5231 }
5232 case POSIX_SPAWN_CLOSE: {
5233 int fd;
5234 if (!PyArg_ParseTuple(file_action, "Oi"
5235 ";A close file_action tuple must have 2 elements",
5236 &tag_obj, &fd))
5237 {
5238 goto fail;
5239 }
5240 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5241 if (errno) {
5242 posix_error();
5243 goto fail;
5244 }
5245 break;
5246 }
5247 case POSIX_SPAWN_DUP2: {
5248 int fd1, fd2;
5249 if (!PyArg_ParseTuple(file_action, "Oii"
5250 ";A dup2 file_action tuple must have 3 elements",
5251 &tag_obj, &fd1, &fd2))
5252 {
5253 goto fail;
5254 }
5255 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5256 fd1, fd2);
5257 if (errno) {
5258 posix_error();
5259 goto fail;
5260 }
5261 break;
5262 }
5263 default: {
5264 PyErr_SetString(PyExc_TypeError,
5265 "Unknown file_actions identifier");
5266 goto fail;
5267 }
5268 }
5269 Py_DECREF(file_action);
5270 }
5271 Py_DECREF(seq);
5272 return 0;
5273
5274fail:
5275 Py_DECREF(seq);
5276 Py_DECREF(file_action);
5277 (void)posix_spawn_file_actions_destroy(file_actionsp);
5278 return -1;
5279}
5280
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005281/*[clinic input]
5282
5283os.posix_spawn
5284 path: path_t
5285 Path of executable file.
5286 argv: object
5287 Tuple or list of strings.
5288 env: object
5289 Dictionary of strings mapping to strings.
5290 file_actions: object = None
Serhiy Storchakaef347532018-05-01 16:45:04 +03005291 A sequence of file action tuples.
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005292 /
5293
5294Execute the program specified by path in a new process.
5295[clinic start generated code]*/
5296
5297static PyObject *
5298os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5299 PyObject *env, PyObject *file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005300/*[clinic end generated code: output=d023521f541c709c input=a3db1021d33230dc]*/
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005301{
5302 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005303 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005304 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005305 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005306 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005307 PyObject *result = NULL;
5308 pid_t pid;
5309 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005310
5311 /* posix_spawn has three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005312 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005313 like posix.environ. */
5314
Serhiy Storchakaef347532018-05-01 16:45:04 +03005315 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005316 PyErr_SetString(PyExc_TypeError,
5317 "posix_spawn: argv must be a tuple or list");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005318 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005319 }
5320 argc = PySequence_Size(argv);
5321 if (argc < 1) {
5322 PyErr_SetString(PyExc_ValueError, "posix_spawn: argv must not be empty");
5323 return NULL;
5324 }
5325
5326 if (!PyMapping_Check(env)) {
5327 PyErr_SetString(PyExc_TypeError,
5328 "posix_spawn: environment must be a mapping object");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005329 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005330 }
5331
5332 argvlist = parse_arglist(argv, &argc);
5333 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005334 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005335 }
5336 if (!argvlist[0][0]) {
5337 PyErr_SetString(PyExc_ValueError,
5338 "posix_spawn: argv first element cannot be empty");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005339 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005340 }
5341
5342 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005343 if (envlist == NULL) {
5344 goto exit;
5345 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005346
Serhiy Storchakaef347532018-05-01 16:45:04 +03005347 if (file_actions != Py_None) {
5348 if (parse_file_actions(file_actions, &file_actions_buf)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005349 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005350 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005351 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005352 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005353
5354 _Py_BEGIN_SUPPRESS_IPH
Serhiy Storchakaef347532018-05-01 16:45:04 +03005355 err_code = posix_spawn(&pid, path->narrow,
5356 file_actionsp, NULL, argvlist, envlist);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005357 _Py_END_SUPPRESS_IPH
Serhiy Storchakaef347532018-05-01 16:45:04 +03005358 if (err_code) {
5359 errno = err_code;
5360 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005361 goto exit;
5362 }
5363 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005364
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005365exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005366 if (file_actionsp) {
5367 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005368 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005369 if (envlist) {
5370 free_string_array(envlist, envc);
5371 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005372 if (argvlist) {
5373 free_string_array(argvlist, argc);
5374 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005375 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005376}
5377#endif /* HAVE_POSIX_SPAWN */
5378
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005379
Steve Dowercc16be82016-09-08 10:35:16 -07005380#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005381/*[clinic input]
5382os.spawnv
5383
5384 mode: int
5385 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005386 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005387 Path of executable file.
5388 argv: object
5389 Tuple or list of strings.
5390 /
5391
5392Execute the program specified by path in a new process.
5393[clinic start generated code]*/
5394
Larry Hastings2f936352014-08-05 14:04:04 +10005395static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005396os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5397/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005398{
Steve Dowercc16be82016-09-08 10:35:16 -07005399 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005400 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005401 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005402 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005403 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005404
Victor Stinner8c62be82010-05-06 00:08:46 +00005405 /* spawnv has three arguments: (mode, path, argv), where
5406 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005407
Victor Stinner8c62be82010-05-06 00:08:46 +00005408 if (PyList_Check(argv)) {
5409 argc = PyList_Size(argv);
5410 getitem = PyList_GetItem;
5411 }
5412 else if (PyTuple_Check(argv)) {
5413 argc = PyTuple_Size(argv);
5414 getitem = PyTuple_GetItem;
5415 }
5416 else {
5417 PyErr_SetString(PyExc_TypeError,
5418 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005419 return NULL;
5420 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005421 if (argc == 0) {
5422 PyErr_SetString(PyExc_ValueError,
5423 "spawnv() arg 2 cannot be empty");
5424 return NULL;
5425 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005426
Steve Dowercc16be82016-09-08 10:35:16 -07005427 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005428 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005429 return PyErr_NoMemory();
5430 }
5431 for (i = 0; i < argc; i++) {
5432 if (!fsconvert_strdup((*getitem)(argv, i),
5433 &argvlist[i])) {
5434 free_string_array(argvlist, i);
5435 PyErr_SetString(
5436 PyExc_TypeError,
5437 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005438 return NULL;
5439 }
Steve Dower93ff8722016-11-19 19:03:54 -08005440 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005441 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005442 PyErr_SetString(
5443 PyExc_ValueError,
5444 "spawnv() arg 2 first element cannot be empty");
5445 return NULL;
5446 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005447 }
5448 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005449
Victor Stinner8c62be82010-05-06 00:08:46 +00005450 if (mode == _OLD_P_OVERLAY)
5451 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005452
Victor Stinner8c62be82010-05-06 00:08:46 +00005453 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005454 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005455#ifdef HAVE_WSPAWNV
5456 spawnval = _wspawnv(mode, path->wide, argvlist);
5457#else
5458 spawnval = _spawnv(mode, path->narrow, argvlist);
5459#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005460 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005461 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005462
Victor Stinner8c62be82010-05-06 00:08:46 +00005463 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005464
Victor Stinner8c62be82010-05-06 00:08:46 +00005465 if (spawnval == -1)
5466 return posix_error();
5467 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005468 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005469}
5470
Larry Hastings2f936352014-08-05 14:04:04 +10005471/*[clinic input]
5472os.spawnve
5473
5474 mode: int
5475 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005476 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005477 Path of executable file.
5478 argv: object
5479 Tuple or list of strings.
5480 env: object
5481 Dictionary of strings mapping to strings.
5482 /
5483
5484Execute the program specified by path in a new process.
5485[clinic start generated code]*/
5486
Larry Hastings2f936352014-08-05 14:04:04 +10005487static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005488os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005489 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005490/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005491{
Steve Dowercc16be82016-09-08 10:35:16 -07005492 EXECV_CHAR **argvlist;
5493 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005494 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005495 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005496 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005497 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005498 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005499
Victor Stinner8c62be82010-05-06 00:08:46 +00005500 /* spawnve has four arguments: (mode, path, argv, env), where
5501 argv is a list or tuple of strings and env is a dictionary
5502 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005503
Victor Stinner8c62be82010-05-06 00:08:46 +00005504 if (PyList_Check(argv)) {
5505 argc = PyList_Size(argv);
5506 getitem = PyList_GetItem;
5507 }
5508 else if (PyTuple_Check(argv)) {
5509 argc = PyTuple_Size(argv);
5510 getitem = PyTuple_GetItem;
5511 }
5512 else {
5513 PyErr_SetString(PyExc_TypeError,
5514 "spawnve() arg 2 must be a tuple or list");
5515 goto fail_0;
5516 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005517 if (argc == 0) {
5518 PyErr_SetString(PyExc_ValueError,
5519 "spawnve() arg 2 cannot be empty");
5520 goto fail_0;
5521 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005522 if (!PyMapping_Check(env)) {
5523 PyErr_SetString(PyExc_TypeError,
5524 "spawnve() arg 3 must be a mapping object");
5525 goto fail_0;
5526 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005527
Steve Dowercc16be82016-09-08 10:35:16 -07005528 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005529 if (argvlist == NULL) {
5530 PyErr_NoMemory();
5531 goto fail_0;
5532 }
5533 for (i = 0; i < argc; i++) {
5534 if (!fsconvert_strdup((*getitem)(argv, i),
5535 &argvlist[i]))
5536 {
5537 lastarg = i;
5538 goto fail_1;
5539 }
Steve Dowerbce26262016-11-19 19:17:26 -08005540 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005541 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005542 PyErr_SetString(
5543 PyExc_ValueError,
5544 "spawnv() arg 2 first element cannot be empty");
5545 goto fail_1;
5546 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005547 }
5548 lastarg = argc;
5549 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005550
Victor Stinner8c62be82010-05-06 00:08:46 +00005551 envlist = parse_envlist(env, &envc);
5552 if (envlist == NULL)
5553 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005554
Victor Stinner8c62be82010-05-06 00:08:46 +00005555 if (mode == _OLD_P_OVERLAY)
5556 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005557
Victor Stinner8c62be82010-05-06 00:08:46 +00005558 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005559 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005560#ifdef HAVE_WSPAWNV
5561 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5562#else
5563 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5564#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005565 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005566 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005567
Victor Stinner8c62be82010-05-06 00:08:46 +00005568 if (spawnval == -1)
5569 (void) posix_error();
5570 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005571 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005572
Victor Stinner8c62be82010-05-06 00:08:46 +00005573 while (--envc >= 0)
5574 PyMem_DEL(envlist[envc]);
5575 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005576 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005577 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005578 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005579 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005580}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005581
Guido van Rossuma1065681999-01-25 23:20:23 +00005582#endif /* HAVE_SPAWNV */
5583
5584
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005585#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005586
5587/* Helper function to validate arguments.
5588 Returns 0 on success. non-zero on failure with a TypeError raised.
5589 If obj is non-NULL it must be callable. */
5590static int
5591check_null_or_callable(PyObject *obj, const char* obj_name)
5592{
5593 if (obj && !PyCallable_Check(obj)) {
5594 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5595 obj_name, Py_TYPE(obj)->tp_name);
5596 return -1;
5597 }
5598 return 0;
5599}
5600
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005601/*[clinic input]
5602os.register_at_fork
5603
Gregory P. Smith163468a2017-05-29 10:03:41 -07005604 *
5605 before: object=NULL
5606 A callable to be called in the parent before the fork() syscall.
5607 after_in_child: object=NULL
5608 A callable to be called in the child after fork().
5609 after_in_parent: object=NULL
5610 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005611
Gregory P. Smith163468a2017-05-29 10:03:41 -07005612Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005613
Gregory P. Smith163468a2017-05-29 10:03:41 -07005614'before' callbacks are called in reverse order.
5615'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005616
5617[clinic start generated code]*/
5618
5619static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005620os_register_at_fork_impl(PyObject *module, PyObject *before,
5621 PyObject *after_in_child, PyObject *after_in_parent)
5622/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005623{
5624 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005625
Gregory P. Smith163468a2017-05-29 10:03:41 -07005626 if (!before && !after_in_child && !after_in_parent) {
5627 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5628 return NULL;
5629 }
5630 if (check_null_or_callable(before, "before") ||
5631 check_null_or_callable(after_in_child, "after_in_child") ||
5632 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005633 return NULL;
5634 }
5635 interp = PyThreadState_Get()->interp;
5636
Gregory P. Smith163468a2017-05-29 10:03:41 -07005637 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005638 return NULL;
5639 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005640 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005641 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005642 }
5643 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5644 return NULL;
5645 }
5646 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005647}
5648#endif /* HAVE_FORK */
5649
5650
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005651#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005652/*[clinic input]
5653os.fork1
5654
5655Fork a child process with a single multiplexed (i.e., not bound) thread.
5656
5657Return 0 to child process and PID of child to parent process.
5658[clinic start generated code]*/
5659
Larry Hastings2f936352014-08-05 14:04:04 +10005660static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005661os_fork1_impl(PyObject *module)
5662/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005663{
Victor Stinner8c62be82010-05-06 00:08:46 +00005664 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005665
5666 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005667 pid = fork1();
5668 if (pid == 0) {
5669 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005670 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005671 } else {
5672 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005673 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005674 }
5675 if (pid == -1)
5676 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005677 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005678}
Larry Hastings2f936352014-08-05 14:04:04 +10005679#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005680
5681
Guido van Rossumad0ee831995-03-01 10:34:45 +00005682#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005683/*[clinic input]
5684os.fork
5685
5686Fork a child process.
5687
5688Return 0 to child process and PID of child to parent process.
5689[clinic start generated code]*/
5690
Larry Hastings2f936352014-08-05 14:04:04 +10005691static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005692os_fork_impl(PyObject *module)
5693/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005694{
Victor Stinner8c62be82010-05-06 00:08:46 +00005695 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005696
5697 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005698 pid = fork();
5699 if (pid == 0) {
5700 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005701 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005702 } else {
5703 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005704 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005705 }
5706 if (pid == -1)
5707 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005708 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005709}
Larry Hastings2f936352014-08-05 14:04:04 +10005710#endif /* HAVE_FORK */
5711
Guido van Rossum85e3b011991-06-03 12:42:10 +00005712
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005713#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005714#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005715/*[clinic input]
5716os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005717
Larry Hastings2f936352014-08-05 14:04:04 +10005718 policy: int
5719
5720Get the maximum scheduling priority for policy.
5721[clinic start generated code]*/
5722
Larry Hastings2f936352014-08-05 14:04:04 +10005723static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005724os_sched_get_priority_max_impl(PyObject *module, int policy)
5725/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005726{
5727 int max;
5728
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005729 max = sched_get_priority_max(policy);
5730 if (max < 0)
5731 return posix_error();
5732 return PyLong_FromLong(max);
5733}
5734
Larry Hastings2f936352014-08-05 14:04:04 +10005735
5736/*[clinic input]
5737os.sched_get_priority_min
5738
5739 policy: int
5740
5741Get the minimum scheduling priority for policy.
5742[clinic start generated code]*/
5743
Larry Hastings2f936352014-08-05 14:04:04 +10005744static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005745os_sched_get_priority_min_impl(PyObject *module, int policy)
5746/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005747{
5748 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005749 if (min < 0)
5750 return posix_error();
5751 return PyLong_FromLong(min);
5752}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005753#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5754
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005755
Larry Hastings2f936352014-08-05 14:04:04 +10005756#ifdef HAVE_SCHED_SETSCHEDULER
5757/*[clinic input]
5758os.sched_getscheduler
5759 pid: pid_t
5760 /
5761
5762Get the scheduling policy for the process identifiedy by pid.
5763
5764Passing 0 for pid returns the scheduling policy for the calling process.
5765[clinic start generated code]*/
5766
Larry Hastings2f936352014-08-05 14:04:04 +10005767static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005768os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5769/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005770{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005771 int policy;
5772
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005773 policy = sched_getscheduler(pid);
5774 if (policy < 0)
5775 return posix_error();
5776 return PyLong_FromLong(policy);
5777}
Larry Hastings2f936352014-08-05 14:04:04 +10005778#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005779
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005780
5781#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005782/*[clinic input]
5783class os.sched_param "PyObject *" "&SchedParamType"
5784
5785@classmethod
5786os.sched_param.__new__
5787
5788 sched_priority: object
5789 A scheduling parameter.
5790
5791Current has only one field: sched_priority");
5792[clinic start generated code]*/
5793
Larry Hastings2f936352014-08-05 14:04:04 +10005794static PyObject *
5795os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005796/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005797{
5798 PyObject *res;
5799
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005800 res = PyStructSequence_New(type);
5801 if (!res)
5802 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005803 Py_INCREF(sched_priority);
5804 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005805 return res;
5806}
5807
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005808
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005809PyDoc_VAR(os_sched_param__doc__);
5810
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005811static PyStructSequence_Field sched_param_fields[] = {
5812 {"sched_priority", "the scheduling priority"},
5813 {0}
5814};
5815
5816static PyStructSequence_Desc sched_param_desc = {
5817 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005818 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005819 sched_param_fields,
5820 1
5821};
5822
5823static int
5824convert_sched_param(PyObject *param, struct sched_param *res)
5825{
5826 long priority;
5827
5828 if (Py_TYPE(param) != &SchedParamType) {
5829 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5830 return 0;
5831 }
5832 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5833 if (priority == -1 && PyErr_Occurred())
5834 return 0;
5835 if (priority > INT_MAX || priority < INT_MIN) {
5836 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5837 return 0;
5838 }
5839 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5840 return 1;
5841}
Larry Hastings2f936352014-08-05 14:04:04 +10005842#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005843
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005844
5845#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005846/*[clinic input]
5847os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005848
Larry Hastings2f936352014-08-05 14:04:04 +10005849 pid: pid_t
5850 policy: int
5851 param: sched_param
5852 /
5853
5854Set the scheduling policy for the process identified by pid.
5855
5856If pid is 0, the calling process is changed.
5857param is an instance of sched_param.
5858[clinic start generated code]*/
5859
Larry Hastings2f936352014-08-05 14:04:04 +10005860static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005861os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005862 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005863/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005864{
Jesus Cea9c822272011-09-10 01:40:52 +02005865 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005866 ** sched_setscheduler() returns 0 in Linux, but the previous
5867 ** scheduling policy under Solaris/Illumos, and others.
5868 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005869 */
Larry Hastings2f936352014-08-05 14:04:04 +10005870 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005871 return posix_error();
5872 Py_RETURN_NONE;
5873}
Larry Hastings2f936352014-08-05 14:04:04 +10005874#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005875
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005876
5877#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005878/*[clinic input]
5879os.sched_getparam
5880 pid: pid_t
5881 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005882
Larry Hastings2f936352014-08-05 14:04:04 +10005883Returns scheduling parameters for the process identified by pid.
5884
5885If pid is 0, returns parameters for the calling process.
5886Return value is an instance of sched_param.
5887[clinic start generated code]*/
5888
Larry Hastings2f936352014-08-05 14:04:04 +10005889static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005890os_sched_getparam_impl(PyObject *module, pid_t pid)
5891/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005892{
5893 struct sched_param param;
5894 PyObject *result;
5895 PyObject *priority;
5896
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005897 if (sched_getparam(pid, &param))
5898 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005899 result = PyStructSequence_New(&SchedParamType);
5900 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005901 return NULL;
5902 priority = PyLong_FromLong(param.sched_priority);
5903 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005904 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005905 return NULL;
5906 }
Larry Hastings2f936352014-08-05 14:04:04 +10005907 PyStructSequence_SET_ITEM(result, 0, priority);
5908 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005909}
5910
Larry Hastings2f936352014-08-05 14:04:04 +10005911
5912/*[clinic input]
5913os.sched_setparam
5914 pid: pid_t
5915 param: sched_param
5916 /
5917
5918Set scheduling parameters for the process identified by pid.
5919
5920If pid is 0, sets parameters for the calling process.
5921param should be an instance of sched_param.
5922[clinic start generated code]*/
5923
Larry Hastings2f936352014-08-05 14:04:04 +10005924static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005925os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005926 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005927/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005928{
5929 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005930 return posix_error();
5931 Py_RETURN_NONE;
5932}
Larry Hastings2f936352014-08-05 14:04:04 +10005933#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005934
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005935
5936#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005937/*[clinic input]
5938os.sched_rr_get_interval -> double
5939 pid: pid_t
5940 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005941
Larry Hastings2f936352014-08-05 14:04:04 +10005942Return the round-robin quantum for the process identified by pid, in seconds.
5943
5944Value returned is a float.
5945[clinic start generated code]*/
5946
Larry Hastings2f936352014-08-05 14:04:04 +10005947static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005948os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5949/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005950{
5951 struct timespec interval;
5952 if (sched_rr_get_interval(pid, &interval)) {
5953 posix_error();
5954 return -1.0;
5955 }
5956 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5957}
5958#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005959
Larry Hastings2f936352014-08-05 14:04:04 +10005960
5961/*[clinic input]
5962os.sched_yield
5963
5964Voluntarily relinquish the CPU.
5965[clinic start generated code]*/
5966
Larry Hastings2f936352014-08-05 14:04:04 +10005967static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005968os_sched_yield_impl(PyObject *module)
5969/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005970{
5971 if (sched_yield())
5972 return posix_error();
5973 Py_RETURN_NONE;
5974}
5975
Benjamin Peterson2740af82011-08-02 17:41:34 -05005976#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005977/* The minimum number of CPUs allocated in a cpu_set_t */
5978static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005979
Larry Hastings2f936352014-08-05 14:04:04 +10005980/*[clinic input]
5981os.sched_setaffinity
5982 pid: pid_t
5983 mask : object
5984 /
5985
5986Set the CPU affinity of the process identified by pid to mask.
5987
5988mask should be an iterable of integers identifying CPUs.
5989[clinic start generated code]*/
5990
Larry Hastings2f936352014-08-05 14:04:04 +10005991static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005992os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5993/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005994{
Antoine Pitrou84869872012-08-04 16:16:35 +02005995 int ncpus;
5996 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005997 cpu_set_t *cpu_set = NULL;
5998 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005999
Larry Hastings2f936352014-08-05 14:04:04 +10006000 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006001 if (iterator == NULL)
6002 return NULL;
6003
6004 ncpus = NCPUS_START;
6005 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006006 cpu_set = CPU_ALLOC(ncpus);
6007 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006008 PyErr_NoMemory();
6009 goto error;
6010 }
Larry Hastings2f936352014-08-05 14:04:04 +10006011 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006012
6013 while ((item = PyIter_Next(iterator))) {
6014 long cpu;
6015 if (!PyLong_Check(item)) {
6016 PyErr_Format(PyExc_TypeError,
6017 "expected an iterator of ints, "
6018 "but iterator yielded %R",
6019 Py_TYPE(item));
6020 Py_DECREF(item);
6021 goto error;
6022 }
6023 cpu = PyLong_AsLong(item);
6024 Py_DECREF(item);
6025 if (cpu < 0) {
6026 if (!PyErr_Occurred())
6027 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6028 goto error;
6029 }
6030 if (cpu > INT_MAX - 1) {
6031 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6032 goto error;
6033 }
6034 if (cpu >= ncpus) {
6035 /* Grow CPU mask to fit the CPU number */
6036 int newncpus = ncpus;
6037 cpu_set_t *newmask;
6038 size_t newsetsize;
6039 while (newncpus <= cpu) {
6040 if (newncpus > INT_MAX / 2)
6041 newncpus = cpu + 1;
6042 else
6043 newncpus = newncpus * 2;
6044 }
6045 newmask = CPU_ALLOC(newncpus);
6046 if (newmask == NULL) {
6047 PyErr_NoMemory();
6048 goto error;
6049 }
6050 newsetsize = CPU_ALLOC_SIZE(newncpus);
6051 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006052 memcpy(newmask, cpu_set, setsize);
6053 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006054 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006055 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006056 ncpus = newncpus;
6057 }
Larry Hastings2f936352014-08-05 14:04:04 +10006058 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006059 }
6060 Py_CLEAR(iterator);
6061
Larry Hastings2f936352014-08-05 14:04:04 +10006062 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006063 posix_error();
6064 goto error;
6065 }
Larry Hastings2f936352014-08-05 14:04:04 +10006066 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006067 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006068
6069error:
Larry Hastings2f936352014-08-05 14:04:04 +10006070 if (cpu_set)
6071 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006072 Py_XDECREF(iterator);
6073 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006074}
6075
Larry Hastings2f936352014-08-05 14:04:04 +10006076
6077/*[clinic input]
6078os.sched_getaffinity
6079 pid: pid_t
6080 /
6081
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006082Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006083
6084The affinity is returned as a set of CPU identifiers.
6085[clinic start generated code]*/
6086
Larry Hastings2f936352014-08-05 14:04:04 +10006087static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006088os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006089/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006090{
Antoine Pitrou84869872012-08-04 16:16:35 +02006091 int cpu, ncpus, count;
6092 size_t setsize;
6093 cpu_set_t *mask = NULL;
6094 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006095
Antoine Pitrou84869872012-08-04 16:16:35 +02006096 ncpus = NCPUS_START;
6097 while (1) {
6098 setsize = CPU_ALLOC_SIZE(ncpus);
6099 mask = CPU_ALLOC(ncpus);
6100 if (mask == NULL)
6101 return PyErr_NoMemory();
6102 if (sched_getaffinity(pid, setsize, mask) == 0)
6103 break;
6104 CPU_FREE(mask);
6105 if (errno != EINVAL)
6106 return posix_error();
6107 if (ncpus > INT_MAX / 2) {
6108 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6109 "a large enough CPU set");
6110 return NULL;
6111 }
6112 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006113 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006114
6115 res = PySet_New(NULL);
6116 if (res == NULL)
6117 goto error;
6118 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6119 if (CPU_ISSET_S(cpu, setsize, mask)) {
6120 PyObject *cpu_num = PyLong_FromLong(cpu);
6121 --count;
6122 if (cpu_num == NULL)
6123 goto error;
6124 if (PySet_Add(res, cpu_num)) {
6125 Py_DECREF(cpu_num);
6126 goto error;
6127 }
6128 Py_DECREF(cpu_num);
6129 }
6130 }
6131 CPU_FREE(mask);
6132 return res;
6133
6134error:
6135 if (mask)
6136 CPU_FREE(mask);
6137 Py_XDECREF(res);
6138 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006139}
6140
Benjamin Peterson2740af82011-08-02 17:41:34 -05006141#endif /* HAVE_SCHED_SETAFFINITY */
6142
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006143#endif /* HAVE_SCHED_H */
6144
Larry Hastings2f936352014-08-05 14:04:04 +10006145
Neal Norwitzb59798b2003-03-21 01:43:31 +00006146/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006147/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6148#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006149#define DEV_PTY_FILE "/dev/ptc"
6150#define HAVE_DEV_PTMX
6151#else
6152#define DEV_PTY_FILE "/dev/ptmx"
6153#endif
6154
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006155#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006156#ifdef HAVE_PTY_H
6157#include <pty.h>
6158#else
6159#ifdef HAVE_LIBUTIL_H
6160#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006161#else
6162#ifdef HAVE_UTIL_H
6163#include <util.h>
6164#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006165#endif /* HAVE_LIBUTIL_H */
6166#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006167#ifdef HAVE_STROPTS_H
6168#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006169#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006170#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006171
Larry Hastings2f936352014-08-05 14:04:04 +10006172
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006173#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006174/*[clinic input]
6175os.openpty
6176
6177Open a pseudo-terminal.
6178
6179Return a tuple of (master_fd, slave_fd) containing open file descriptors
6180for both the master and slave ends.
6181[clinic start generated code]*/
6182
Larry Hastings2f936352014-08-05 14:04:04 +10006183static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006184os_openpty_impl(PyObject *module)
6185/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006186{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006187 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006188#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006189 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006190#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006191#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006192 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006193#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006194 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006195#endif
6196#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006197
Thomas Wouters70c21a12000-07-14 14:28:33 +00006198#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006199 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006200 goto posix_error;
6201
6202 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6203 goto error;
6204 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6205 goto error;
6206
Neal Norwitzb59798b2003-03-21 01:43:31 +00006207#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006208 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6209 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006210 goto posix_error;
6211 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6212 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006213
Victor Stinnerdaf45552013-08-28 00:53:59 +02006214 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006215 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006216 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006217
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006218#else
Victor Stinner000de532013-11-25 23:19:58 +01006219 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006220 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006221 goto posix_error;
6222
Victor Stinner8c62be82010-05-06 00:08:46 +00006223 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006224
Victor Stinner8c62be82010-05-06 00:08:46 +00006225 /* change permission of slave */
6226 if (grantpt(master_fd) < 0) {
6227 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006228 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006229 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006230
Victor Stinner8c62be82010-05-06 00:08:46 +00006231 /* unlock slave */
6232 if (unlockpt(master_fd) < 0) {
6233 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006234 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006235 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006236
Victor Stinner8c62be82010-05-06 00:08:46 +00006237 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006238
Victor Stinner8c62be82010-05-06 00:08:46 +00006239 slave_name = ptsname(master_fd); /* get name of slave */
6240 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006241 goto posix_error;
6242
6243 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006244 if (slave_fd == -1)
6245 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006246
6247 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6248 goto posix_error;
6249
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006250#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006251 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6252 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006253#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006255#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006256#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006257#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006258
Victor Stinner8c62be82010-05-06 00:08:46 +00006259 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006260
Victor Stinnerdaf45552013-08-28 00:53:59 +02006261posix_error:
6262 posix_error();
6263error:
6264 if (master_fd != -1)
6265 close(master_fd);
6266 if (slave_fd != -1)
6267 close(slave_fd);
6268 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006269}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006270#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006271
Larry Hastings2f936352014-08-05 14:04:04 +10006272
Fred Drake8cef4cf2000-06-28 16:40:38 +00006273#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006274/*[clinic input]
6275os.forkpty
6276
6277Fork a new process with a new pseudo-terminal as controlling tty.
6278
6279Returns a tuple of (pid, master_fd).
6280Like fork(), return pid of 0 to the child process,
6281and pid of child to the parent process.
6282To both, return fd of newly opened pseudo-terminal.
6283[clinic start generated code]*/
6284
Larry Hastings2f936352014-08-05 14:04:04 +10006285static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006286os_forkpty_impl(PyObject *module)
6287/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006288{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006289 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006290 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006291
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006292 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 pid = forkpty(&master_fd, NULL, NULL, NULL);
6294 if (pid == 0) {
6295 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006296 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006297 } else {
6298 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006299 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006300 }
6301 if (pid == -1)
6302 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006303 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006304}
Larry Hastings2f936352014-08-05 14:04:04 +10006305#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006306
Ross Lagerwall7807c352011-03-17 20:20:30 +02006307
Guido van Rossumad0ee831995-03-01 10:34:45 +00006308#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006309/*[clinic input]
6310os.getegid
6311
6312Return the current process's effective group id.
6313[clinic start generated code]*/
6314
Larry Hastings2f936352014-08-05 14:04:04 +10006315static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006316os_getegid_impl(PyObject *module)
6317/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006318{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006319 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006320}
Larry Hastings2f936352014-08-05 14:04:04 +10006321#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006322
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006323
Guido van Rossumad0ee831995-03-01 10:34:45 +00006324#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006325/*[clinic input]
6326os.geteuid
6327
6328Return the current process's effective user id.
6329[clinic start generated code]*/
6330
Larry Hastings2f936352014-08-05 14:04:04 +10006331static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006332os_geteuid_impl(PyObject *module)
6333/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006334{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006335 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006336}
Larry Hastings2f936352014-08-05 14:04:04 +10006337#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006338
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006339
Guido van Rossumad0ee831995-03-01 10:34:45 +00006340#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006341/*[clinic input]
6342os.getgid
6343
6344Return the current process's group id.
6345[clinic start generated code]*/
6346
Larry Hastings2f936352014-08-05 14:04:04 +10006347static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006348os_getgid_impl(PyObject *module)
6349/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006350{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006351 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006352}
Larry Hastings2f936352014-08-05 14:04:04 +10006353#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006354
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006355
Berker Peksag39404992016-09-15 20:45:16 +03006356#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006357/*[clinic input]
6358os.getpid
6359
6360Return the current process id.
6361[clinic start generated code]*/
6362
Larry Hastings2f936352014-08-05 14:04:04 +10006363static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006364os_getpid_impl(PyObject *module)
6365/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006366{
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006368}
Berker Peksag39404992016-09-15 20:45:16 +03006369#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006370
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006371#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006372
6373/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006374PyDoc_STRVAR(posix_getgrouplist__doc__,
6375"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6376Returns a list of groups to which a user belongs.\n\n\
6377 user: username to lookup\n\
6378 group: base group id of the user");
6379
6380static PyObject *
6381posix_getgrouplist(PyObject *self, PyObject *args)
6382{
6383#ifdef NGROUPS_MAX
6384#define MAX_GROUPS NGROUPS_MAX
6385#else
6386 /* defined to be 16 on Solaris7, so this should be a small number */
6387#define MAX_GROUPS 64
6388#endif
6389
6390 const char *user;
6391 int i, ngroups;
6392 PyObject *list;
6393#ifdef __APPLE__
6394 int *groups, basegid;
6395#else
6396 gid_t *groups, basegid;
6397#endif
6398 ngroups = MAX_GROUPS;
6399
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006400#ifdef __APPLE__
6401 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006402 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006403#else
6404 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6405 _Py_Gid_Converter, &basegid))
6406 return NULL;
6407#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006408
6409#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006410 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006411#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006412 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006413#endif
6414 if (groups == NULL)
6415 return PyErr_NoMemory();
6416
6417 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6418 PyMem_Del(groups);
6419 return posix_error();
6420 }
6421
6422 list = PyList_New(ngroups);
6423 if (list == NULL) {
6424 PyMem_Del(groups);
6425 return NULL;
6426 }
6427
6428 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006429#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006430 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006431#else
6432 PyObject *o = _PyLong_FromGid(groups[i]);
6433#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006434 if (o == NULL) {
6435 Py_DECREF(list);
6436 PyMem_Del(groups);
6437 return NULL;
6438 }
6439 PyList_SET_ITEM(list, i, o);
6440 }
6441
6442 PyMem_Del(groups);
6443
6444 return list;
6445}
Larry Hastings2f936352014-08-05 14:04:04 +10006446#endif /* HAVE_GETGROUPLIST */
6447
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006448
Fred Drakec9680921999-12-13 16:37:25 +00006449#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006450/*[clinic input]
6451os.getgroups
6452
6453Return list of supplemental group IDs for the process.
6454[clinic start generated code]*/
6455
Larry Hastings2f936352014-08-05 14:04:04 +10006456static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006457os_getgroups_impl(PyObject *module)
6458/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006459{
6460 PyObject *result = NULL;
6461
Fred Drakec9680921999-12-13 16:37:25 +00006462#ifdef NGROUPS_MAX
6463#define MAX_GROUPS NGROUPS_MAX
6464#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006465 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006466#define MAX_GROUPS 64
6467#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006468 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006469
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006470 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006471 * This is a helper variable to store the intermediate result when
6472 * that happens.
6473 *
6474 * To keep the code readable the OSX behaviour is unconditional,
6475 * according to the POSIX spec this should be safe on all unix-y
6476 * systems.
6477 */
6478 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006479 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006480
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006481#ifdef __APPLE__
6482 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6483 * there are more groups than can fit in grouplist. Therefore, on OS X
6484 * always first call getgroups with length 0 to get the actual number
6485 * of groups.
6486 */
6487 n = getgroups(0, NULL);
6488 if (n < 0) {
6489 return posix_error();
6490 } else if (n <= MAX_GROUPS) {
6491 /* groups will fit in existing array */
6492 alt_grouplist = grouplist;
6493 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006494 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006495 if (alt_grouplist == NULL) {
6496 errno = EINVAL;
6497 return posix_error();
6498 }
6499 }
6500
6501 n = getgroups(n, alt_grouplist);
6502 if (n == -1) {
6503 if (alt_grouplist != grouplist) {
6504 PyMem_Free(alt_grouplist);
6505 }
6506 return posix_error();
6507 }
6508#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006509 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006510 if (n < 0) {
6511 if (errno == EINVAL) {
6512 n = getgroups(0, NULL);
6513 if (n == -1) {
6514 return posix_error();
6515 }
6516 if (n == 0) {
6517 /* Avoid malloc(0) */
6518 alt_grouplist = grouplist;
6519 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006520 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006521 if (alt_grouplist == NULL) {
6522 errno = EINVAL;
6523 return posix_error();
6524 }
6525 n = getgroups(n, alt_grouplist);
6526 if (n == -1) {
6527 PyMem_Free(alt_grouplist);
6528 return posix_error();
6529 }
6530 }
6531 } else {
6532 return posix_error();
6533 }
6534 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006535#endif
6536
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006537 result = PyList_New(n);
6538 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 int i;
6540 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006541 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006543 Py_DECREF(result);
6544 result = NULL;
6545 break;
Fred Drakec9680921999-12-13 16:37:25 +00006546 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006547 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006548 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006549 }
6550
6551 if (alt_grouplist != grouplist) {
6552 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006553 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006554
Fred Drakec9680921999-12-13 16:37:25 +00006555 return result;
6556}
Larry Hastings2f936352014-08-05 14:04:04 +10006557#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006558
Antoine Pitroub7572f02009-12-02 20:46:48 +00006559#ifdef HAVE_INITGROUPS
6560PyDoc_STRVAR(posix_initgroups__doc__,
6561"initgroups(username, gid) -> None\n\n\
6562Call the system initgroups() to initialize the group access list with all of\n\
6563the groups of which the specified username is a member, plus the specified\n\
6564group id.");
6565
Larry Hastings2f936352014-08-05 14:04:04 +10006566/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006567static PyObject *
6568posix_initgroups(PyObject *self, PyObject *args)
6569{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006570 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006571 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006572 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006573#ifdef __APPLE__
6574 int gid;
6575#else
6576 gid_t gid;
6577#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006578
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006579#ifdef __APPLE__
6580 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6581 PyUnicode_FSConverter, &oname,
6582 &gid))
6583#else
6584 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6585 PyUnicode_FSConverter, &oname,
6586 _Py_Gid_Converter, &gid))
6587#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006588 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006589 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006590
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006591 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006592 Py_DECREF(oname);
6593 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006594 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006595
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006596 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006597}
Larry Hastings2f936352014-08-05 14:04:04 +10006598#endif /* HAVE_INITGROUPS */
6599
Antoine Pitroub7572f02009-12-02 20:46:48 +00006600
Martin v. Löwis606edc12002-06-13 21:09:11 +00006601#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006602/*[clinic input]
6603os.getpgid
6604
6605 pid: pid_t
6606
6607Call the system call getpgid(), and return the result.
6608[clinic start generated code]*/
6609
Larry Hastings2f936352014-08-05 14:04:04 +10006610static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006611os_getpgid_impl(PyObject *module, pid_t pid)
6612/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006613{
6614 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006615 if (pgid < 0)
6616 return posix_error();
6617 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006618}
6619#endif /* HAVE_GETPGID */
6620
6621
Guido van Rossumb6775db1994-08-01 11:34:53 +00006622#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006623/*[clinic input]
6624os.getpgrp
6625
6626Return the current process group id.
6627[clinic start generated code]*/
6628
Larry Hastings2f936352014-08-05 14:04:04 +10006629static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006630os_getpgrp_impl(PyObject *module)
6631/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006632{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006633#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006634 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006635#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006636 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006637#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006638}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006639#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006640
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006641
Guido van Rossumb6775db1994-08-01 11:34:53 +00006642#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006643/*[clinic input]
6644os.setpgrp
6645
6646Make the current process the leader of its process group.
6647[clinic start generated code]*/
6648
Larry Hastings2f936352014-08-05 14:04:04 +10006649static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006650os_setpgrp_impl(PyObject *module)
6651/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006652{
Guido van Rossum64933891994-10-20 21:56:42 +00006653#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006654 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006655#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006656 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006657#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006658 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006659 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006660}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006661#endif /* HAVE_SETPGRP */
6662
Guido van Rossumad0ee831995-03-01 10:34:45 +00006663#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006664
6665#ifdef MS_WINDOWS
6666#include <tlhelp32.h>
6667
6668static PyObject*
6669win32_getppid()
6670{
6671 HANDLE snapshot;
6672 pid_t mypid;
6673 PyObject* result = NULL;
6674 BOOL have_record;
6675 PROCESSENTRY32 pe;
6676
6677 mypid = getpid(); /* This function never fails */
6678
6679 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6680 if (snapshot == INVALID_HANDLE_VALUE)
6681 return PyErr_SetFromWindowsErr(GetLastError());
6682
6683 pe.dwSize = sizeof(pe);
6684 have_record = Process32First(snapshot, &pe);
6685 while (have_record) {
6686 if (mypid == (pid_t)pe.th32ProcessID) {
6687 /* We could cache the ulong value in a static variable. */
6688 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6689 break;
6690 }
6691
6692 have_record = Process32Next(snapshot, &pe);
6693 }
6694
6695 /* If our loop exits and our pid was not found (result will be NULL)
6696 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6697 * error anyway, so let's raise it. */
6698 if (!result)
6699 result = PyErr_SetFromWindowsErr(GetLastError());
6700
6701 CloseHandle(snapshot);
6702
6703 return result;
6704}
6705#endif /*MS_WINDOWS*/
6706
Larry Hastings2f936352014-08-05 14:04:04 +10006707
6708/*[clinic input]
6709os.getppid
6710
6711Return the parent's process id.
6712
6713If the parent process has already exited, Windows machines will still
6714return its id; others systems will return the id of the 'init' process (1).
6715[clinic start generated code]*/
6716
Larry Hastings2f936352014-08-05 14:04:04 +10006717static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006718os_getppid_impl(PyObject *module)
6719/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006720{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006721#ifdef MS_WINDOWS
6722 return win32_getppid();
6723#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006724 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006725#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006726}
6727#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006728
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006729
Fred Drake12c6e2d1999-12-14 21:25:03 +00006730#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006731/*[clinic input]
6732os.getlogin
6733
6734Return the actual login name.
6735[clinic start generated code]*/
6736
Larry Hastings2f936352014-08-05 14:04:04 +10006737static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006738os_getlogin_impl(PyObject *module)
6739/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006740{
Victor Stinner8c62be82010-05-06 00:08:46 +00006741 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006742#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006743 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006744 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006745
6746 if (GetUserNameW(user_name, &num_chars)) {
6747 /* num_chars is the number of unicode chars plus null terminator */
6748 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006749 }
6750 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006751 result = PyErr_SetFromWindowsErr(GetLastError());
6752#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006753 char *name;
6754 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006755
Victor Stinner8c62be82010-05-06 00:08:46 +00006756 errno = 0;
6757 name = getlogin();
6758 if (name == NULL) {
6759 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006760 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006761 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006762 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006763 }
6764 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006765 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006766 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006767#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006768 return result;
6769}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006770#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006771
Larry Hastings2f936352014-08-05 14:04:04 +10006772
Guido van Rossumad0ee831995-03-01 10:34:45 +00006773#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006774/*[clinic input]
6775os.getuid
6776
6777Return the current process's user id.
6778[clinic start generated code]*/
6779
Larry Hastings2f936352014-08-05 14:04:04 +10006780static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006781os_getuid_impl(PyObject *module)
6782/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006783{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006784 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006785}
Larry Hastings2f936352014-08-05 14:04:04 +10006786#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006788
Brian Curtineb24d742010-04-12 17:16:38 +00006789#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006790#define HAVE_KILL
6791#endif /* MS_WINDOWS */
6792
6793#ifdef HAVE_KILL
6794/*[clinic input]
6795os.kill
6796
6797 pid: pid_t
6798 signal: Py_ssize_t
6799 /
6800
6801Kill a process with a signal.
6802[clinic start generated code]*/
6803
Larry Hastings2f936352014-08-05 14:04:04 +10006804static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006805os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6806/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006807#ifndef MS_WINDOWS
6808{
6809 if (kill(pid, (int)signal) == -1)
6810 return posix_error();
6811 Py_RETURN_NONE;
6812}
6813#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006814{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006815 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006816 DWORD sig = (DWORD)signal;
6817 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006818 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006819
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 /* Console processes which share a common console can be sent CTRL+C or
6821 CTRL+BREAK events, provided they handle said events. */
6822 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006823 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 err = GetLastError();
6825 PyErr_SetFromWindowsErr(err);
6826 }
6827 else
6828 Py_RETURN_NONE;
6829 }
Brian Curtineb24d742010-04-12 17:16:38 +00006830
Victor Stinner8c62be82010-05-06 00:08:46 +00006831 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6832 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006833 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006834 if (handle == NULL) {
6835 err = GetLastError();
6836 return PyErr_SetFromWindowsErr(err);
6837 }
Brian Curtineb24d742010-04-12 17:16:38 +00006838
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 if (TerminateProcess(handle, sig) == 0) {
6840 err = GetLastError();
6841 result = PyErr_SetFromWindowsErr(err);
6842 } else {
6843 Py_INCREF(Py_None);
6844 result = Py_None;
6845 }
Brian Curtineb24d742010-04-12 17:16:38 +00006846
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 CloseHandle(handle);
6848 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006849}
Larry Hastings2f936352014-08-05 14:04:04 +10006850#endif /* !MS_WINDOWS */
6851#endif /* HAVE_KILL */
6852
6853
6854#ifdef HAVE_KILLPG
6855/*[clinic input]
6856os.killpg
6857
6858 pgid: pid_t
6859 signal: int
6860 /
6861
6862Kill a process group with a signal.
6863[clinic start generated code]*/
6864
Larry Hastings2f936352014-08-05 14:04:04 +10006865static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006866os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6867/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006868{
6869 /* XXX some man pages make the `pgid` parameter an int, others
6870 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6871 take the same type. Moreover, pid_t is always at least as wide as
6872 int (else compilation of this module fails), which is safe. */
6873 if (killpg(pgid, signal) == -1)
6874 return posix_error();
6875 Py_RETURN_NONE;
6876}
6877#endif /* HAVE_KILLPG */
6878
Brian Curtineb24d742010-04-12 17:16:38 +00006879
Guido van Rossumc0125471996-06-28 18:55:32 +00006880#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006881#ifdef HAVE_SYS_LOCK_H
6882#include <sys/lock.h>
6883#endif
6884
Larry Hastings2f936352014-08-05 14:04:04 +10006885/*[clinic input]
6886os.plock
6887 op: int
6888 /
6889
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006890Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006891[clinic start generated code]*/
6892
Larry Hastings2f936352014-08-05 14:04:04 +10006893static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006894os_plock_impl(PyObject *module, int op)
6895/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006896{
Victor Stinner8c62be82010-05-06 00:08:46 +00006897 if (plock(op) == -1)
6898 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006899 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006900}
Larry Hastings2f936352014-08-05 14:04:04 +10006901#endif /* HAVE_PLOCK */
6902
Guido van Rossumc0125471996-06-28 18:55:32 +00006903
Guido van Rossumb6775db1994-08-01 11:34:53 +00006904#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006905/*[clinic input]
6906os.setuid
6907
6908 uid: uid_t
6909 /
6910
6911Set the current process's user id.
6912[clinic start generated code]*/
6913
Larry Hastings2f936352014-08-05 14:04:04 +10006914static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006915os_setuid_impl(PyObject *module, uid_t uid)
6916/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006917{
Victor Stinner8c62be82010-05-06 00:08:46 +00006918 if (setuid(uid) < 0)
6919 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006920 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006921}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006922#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006923
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006924
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006925#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006926/*[clinic input]
6927os.seteuid
6928
6929 euid: uid_t
6930 /
6931
6932Set the current process's effective user id.
6933[clinic start generated code]*/
6934
Larry Hastings2f936352014-08-05 14:04:04 +10006935static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006936os_seteuid_impl(PyObject *module, uid_t euid)
6937/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006938{
6939 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006940 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006941 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006942}
6943#endif /* HAVE_SETEUID */
6944
Larry Hastings2f936352014-08-05 14:04:04 +10006945
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006946#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006947/*[clinic input]
6948os.setegid
6949
6950 egid: gid_t
6951 /
6952
6953Set the current process's effective group id.
6954[clinic start generated code]*/
6955
Larry Hastings2f936352014-08-05 14:04:04 +10006956static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006957os_setegid_impl(PyObject *module, gid_t egid)
6958/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006959{
6960 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006962 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006963}
6964#endif /* HAVE_SETEGID */
6965
Larry Hastings2f936352014-08-05 14:04:04 +10006966
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006967#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006968/*[clinic input]
6969os.setreuid
6970
6971 ruid: uid_t
6972 euid: uid_t
6973 /
6974
6975Set the current process's real and effective user ids.
6976[clinic start generated code]*/
6977
Larry Hastings2f936352014-08-05 14:04:04 +10006978static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006979os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6980/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006981{
Victor Stinner8c62be82010-05-06 00:08:46 +00006982 if (setreuid(ruid, euid) < 0) {
6983 return posix_error();
6984 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006985 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006987}
6988#endif /* HAVE_SETREUID */
6989
Larry Hastings2f936352014-08-05 14:04:04 +10006990
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006991#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006992/*[clinic input]
6993os.setregid
6994
6995 rgid: gid_t
6996 egid: gid_t
6997 /
6998
6999Set the current process's real and effective group ids.
7000[clinic start generated code]*/
7001
Larry Hastings2f936352014-08-05 14:04:04 +10007002static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007003os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7004/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007005{
7006 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007007 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007008 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007009}
7010#endif /* HAVE_SETREGID */
7011
Larry Hastings2f936352014-08-05 14:04:04 +10007012
Guido van Rossumb6775db1994-08-01 11:34:53 +00007013#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007014/*[clinic input]
7015os.setgid
7016 gid: gid_t
7017 /
7018
7019Set the current process's group id.
7020[clinic start generated code]*/
7021
Larry Hastings2f936352014-08-05 14:04:04 +10007022static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007023os_setgid_impl(PyObject *module, gid_t gid)
7024/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007025{
Victor Stinner8c62be82010-05-06 00:08:46 +00007026 if (setgid(gid) < 0)
7027 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007028 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007029}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007030#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007031
Larry Hastings2f936352014-08-05 14:04:04 +10007032
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007033#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007034/*[clinic input]
7035os.setgroups
7036
7037 groups: object
7038 /
7039
7040Set the groups of the current process to list.
7041[clinic start generated code]*/
7042
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007044os_setgroups(PyObject *module, PyObject *groups)
7045/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007046{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007047 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007048 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007049
Victor Stinner8c62be82010-05-06 00:08:46 +00007050 if (!PySequence_Check(groups)) {
7051 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7052 return NULL;
7053 }
7054 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007055 if (len < 0) {
7056 return NULL;
7057 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007058 if (len > MAX_GROUPS) {
7059 PyErr_SetString(PyExc_ValueError, "too many groups");
7060 return NULL;
7061 }
7062 for(i = 0; i < len; i++) {
7063 PyObject *elem;
7064 elem = PySequence_GetItem(groups, i);
7065 if (!elem)
7066 return NULL;
7067 if (!PyLong_Check(elem)) {
7068 PyErr_SetString(PyExc_TypeError,
7069 "groups must be integers");
7070 Py_DECREF(elem);
7071 return NULL;
7072 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007073 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007074 Py_DECREF(elem);
7075 return NULL;
7076 }
7077 }
7078 Py_DECREF(elem);
7079 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007080
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 if (setgroups(len, grouplist) < 0)
7082 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007083 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007084}
7085#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007086
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007087#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7088static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007089wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007090{
Victor Stinner8c62be82010-05-06 00:08:46 +00007091 PyObject *result;
7092 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007093 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007094
Victor Stinner8c62be82010-05-06 00:08:46 +00007095 if (pid == -1)
7096 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007097
Victor Stinner8c62be82010-05-06 00:08:46 +00007098 if (struct_rusage == NULL) {
7099 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7100 if (m == NULL)
7101 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007102 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007103 Py_DECREF(m);
7104 if (struct_rusage == NULL)
7105 return NULL;
7106 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007107
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7109 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7110 if (!result)
7111 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007112
7113#ifndef doubletime
7114#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7115#endif
7116
Victor Stinner8c62be82010-05-06 00:08:46 +00007117 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007118 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007119 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007120 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007121#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007122 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7123 SET_INT(result, 2, ru->ru_maxrss);
7124 SET_INT(result, 3, ru->ru_ixrss);
7125 SET_INT(result, 4, ru->ru_idrss);
7126 SET_INT(result, 5, ru->ru_isrss);
7127 SET_INT(result, 6, ru->ru_minflt);
7128 SET_INT(result, 7, ru->ru_majflt);
7129 SET_INT(result, 8, ru->ru_nswap);
7130 SET_INT(result, 9, ru->ru_inblock);
7131 SET_INT(result, 10, ru->ru_oublock);
7132 SET_INT(result, 11, ru->ru_msgsnd);
7133 SET_INT(result, 12, ru->ru_msgrcv);
7134 SET_INT(result, 13, ru->ru_nsignals);
7135 SET_INT(result, 14, ru->ru_nvcsw);
7136 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007137#undef SET_INT
7138
Victor Stinner8c62be82010-05-06 00:08:46 +00007139 if (PyErr_Occurred()) {
7140 Py_DECREF(result);
7141 return NULL;
7142 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007143
Victor Stinner8c62be82010-05-06 00:08:46 +00007144 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007145}
7146#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7147
Larry Hastings2f936352014-08-05 14:04:04 +10007148
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007149#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007150/*[clinic input]
7151os.wait3
7152
7153 options: int
7154Wait for completion of a child process.
7155
7156Returns a tuple of information about the child process:
7157 (pid, status, rusage)
7158[clinic start generated code]*/
7159
Larry Hastings2f936352014-08-05 14:04:04 +10007160static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007161os_wait3_impl(PyObject *module, int options)
7162/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007163{
Victor Stinner8c62be82010-05-06 00:08:46 +00007164 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007166 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007167 WAIT_TYPE status;
7168 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007169
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007170 do {
7171 Py_BEGIN_ALLOW_THREADS
7172 pid = wait3(&status, options, &ru);
7173 Py_END_ALLOW_THREADS
7174 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7175 if (pid < 0)
7176 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007177
Victor Stinner4195b5c2012-02-08 23:03:19 +01007178 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007179}
7180#endif /* HAVE_WAIT3 */
7181
Larry Hastings2f936352014-08-05 14:04:04 +10007182
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007183#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007184/*[clinic input]
7185
7186os.wait4
7187
7188 pid: pid_t
7189 options: int
7190
7191Wait for completion of a specific child process.
7192
7193Returns a tuple of information about the child process:
7194 (pid, status, rusage)
7195[clinic start generated code]*/
7196
Larry Hastings2f936352014-08-05 14:04:04 +10007197static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007198os_wait4_impl(PyObject *module, pid_t pid, int options)
7199/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007200{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007201 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007202 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007203 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 WAIT_TYPE status;
7205 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007206
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007207 do {
7208 Py_BEGIN_ALLOW_THREADS
7209 res = wait4(pid, &status, options, &ru);
7210 Py_END_ALLOW_THREADS
7211 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7212 if (res < 0)
7213 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007214
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007215 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007216}
7217#endif /* HAVE_WAIT4 */
7218
Larry Hastings2f936352014-08-05 14:04:04 +10007219
Ross Lagerwall7807c352011-03-17 20:20:30 +02007220#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007221/*[clinic input]
7222os.waitid
7223
7224 idtype: idtype_t
7225 Must be one of be P_PID, P_PGID or P_ALL.
7226 id: id_t
7227 The id to wait on.
7228 options: int
7229 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7230 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7231 /
7232
7233Returns the result of waiting for a process or processes.
7234
7235Returns either waitid_result or None if WNOHANG is specified and there are
7236no children in a waitable state.
7237[clinic start generated code]*/
7238
Larry Hastings2f936352014-08-05 14:04:04 +10007239static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007240os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7241/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007242{
7243 PyObject *result;
7244 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007245 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007246 siginfo_t si;
7247 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007248
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007249 do {
7250 Py_BEGIN_ALLOW_THREADS
7251 res = waitid(idtype, id, &si, options);
7252 Py_END_ALLOW_THREADS
7253 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7254 if (res < 0)
7255 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007256
7257 if (si.si_pid == 0)
7258 Py_RETURN_NONE;
7259
7260 result = PyStructSequence_New(&WaitidResultType);
7261 if (!result)
7262 return NULL;
7263
7264 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007265 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007266 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7267 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7268 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7269 if (PyErr_Occurred()) {
7270 Py_DECREF(result);
7271 return NULL;
7272 }
7273
7274 return result;
7275}
Larry Hastings2f936352014-08-05 14:04:04 +10007276#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007277
Larry Hastings2f936352014-08-05 14:04:04 +10007278
7279#if defined(HAVE_WAITPID)
7280/*[clinic input]
7281os.waitpid
7282 pid: pid_t
7283 options: int
7284 /
7285
7286Wait for completion of a given child process.
7287
7288Returns a tuple of information regarding the child process:
7289 (pid, status)
7290
7291The options argument is ignored on Windows.
7292[clinic start generated code]*/
7293
Larry Hastings2f936352014-08-05 14:04:04 +10007294static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007295os_waitpid_impl(PyObject *module, pid_t pid, int options)
7296/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007297{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007298 pid_t res;
7299 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007300 WAIT_TYPE status;
7301 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007302
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007303 do {
7304 Py_BEGIN_ALLOW_THREADS
7305 res = waitpid(pid, &status, options);
7306 Py_END_ALLOW_THREADS
7307 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7308 if (res < 0)
7309 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007310
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007311 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007312}
Tim Petersab034fa2002-02-01 11:27:43 +00007313#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007314/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007315/*[clinic input]
7316os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007317 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007318 options: int
7319 /
7320
7321Wait for completion of a given process.
7322
7323Returns a tuple of information regarding the process:
7324 (pid, status << 8)
7325
7326The options argument is ignored on Windows.
7327[clinic start generated code]*/
7328
Larry Hastings2f936352014-08-05 14:04:04 +10007329static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007330os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007331/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007332{
7333 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007334 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007335 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007336
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007337 do {
7338 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007339 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007340 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007341 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007342 Py_END_ALLOW_THREADS
7343 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007344 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007345 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007346
Victor Stinner8c62be82010-05-06 00:08:46 +00007347 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007348 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007349}
Larry Hastings2f936352014-08-05 14:04:04 +10007350#endif
7351
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007352
Guido van Rossumad0ee831995-03-01 10:34:45 +00007353#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007354/*[clinic input]
7355os.wait
7356
7357Wait for completion of a child process.
7358
7359Returns a tuple of information about the child process:
7360 (pid, status)
7361[clinic start generated code]*/
7362
Larry Hastings2f936352014-08-05 14:04:04 +10007363static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007364os_wait_impl(PyObject *module)
7365/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007366{
Victor Stinner8c62be82010-05-06 00:08:46 +00007367 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007368 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007369 WAIT_TYPE status;
7370 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007371
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007372 do {
7373 Py_BEGIN_ALLOW_THREADS
7374 pid = wait(&status);
7375 Py_END_ALLOW_THREADS
7376 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7377 if (pid < 0)
7378 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007379
Victor Stinner8c62be82010-05-06 00:08:46 +00007380 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007381}
Larry Hastings2f936352014-08-05 14:04:04 +10007382#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007383
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007384
Larry Hastings9cf065c2012-06-22 16:30:09 -07007385#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7386PyDoc_STRVAR(readlink__doc__,
7387"readlink(path, *, dir_fd=None) -> path\n\n\
7388Return a string representing the path to which the symbolic link points.\n\
7389\n\
7390If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7391 and path should be relative; path will then be relative to that directory.\n\
7392dir_fd may not be implemented on your platform.\n\
7393 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007394#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007395
Guido van Rossumb6775db1994-08-01 11:34:53 +00007396#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007397
Larry Hastings2f936352014-08-05 14:04:04 +10007398/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007399static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007400posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007401{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007402 path_t path;
7403 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007404 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007405 ssize_t length;
7406 PyObject *return_value = NULL;
7407 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007408
Larry Hastings9cf065c2012-06-22 16:30:09 -07007409 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007410 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007411 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7412 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007413 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007414 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007415
Victor Stinner8c62be82010-05-06 00:08:46 +00007416 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007417#ifdef HAVE_READLINKAT
7418 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007419 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007420 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007421#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007422 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007423 Py_END_ALLOW_THREADS
7424
7425 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007426 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007427 goto exit;
7428 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007429 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007430
7431 if (PyUnicode_Check(path.object))
7432 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7433 else
7434 return_value = PyBytes_FromStringAndSize(buffer, length);
7435exit:
7436 path_cleanup(&path);
7437 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007438}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007439
Guido van Rossumb6775db1994-08-01 11:34:53 +00007440#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007441
Larry Hastings2f936352014-08-05 14:04:04 +10007442#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7443
7444static PyObject *
7445win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7446{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007447 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007448 DWORD n_bytes_returned;
7449 DWORD io_result;
7450 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007451 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007452 HANDLE reparse_point_handle;
7453
Martin Panter70214ad2016-08-04 02:38:59 +00007454 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7455 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007456 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007457
7458 static char *keywords[] = {"path", "dir_fd", NULL};
7459
7460 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7461 &po,
7462 dir_fd_unavailable, &dir_fd
7463 ))
7464 return NULL;
7465
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007466 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007467 if (path == NULL)
7468 return NULL;
7469
7470 /* First get a handle to the reparse point */
7471 Py_BEGIN_ALLOW_THREADS
7472 reparse_point_handle = CreateFileW(
7473 path,
7474 0,
7475 0,
7476 0,
7477 OPEN_EXISTING,
7478 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7479 0);
7480 Py_END_ALLOW_THREADS
7481
7482 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7483 return win32_error_object("readlink", po);
7484
7485 Py_BEGIN_ALLOW_THREADS
7486 /* New call DeviceIoControl to read the reparse point */
7487 io_result = DeviceIoControl(
7488 reparse_point_handle,
7489 FSCTL_GET_REPARSE_POINT,
7490 0, 0, /* in buffer */
7491 target_buffer, sizeof(target_buffer),
7492 &n_bytes_returned,
7493 0 /* we're not using OVERLAPPED_IO */
7494 );
7495 CloseHandle(reparse_point_handle);
7496 Py_END_ALLOW_THREADS
7497
7498 if (io_result==0)
7499 return win32_error_object("readlink", po);
7500
7501 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7502 {
7503 PyErr_SetString(PyExc_ValueError,
7504 "not a symbolic link");
7505 return NULL;
7506 }
SSE43c34aad2018-02-13 00:10:35 +07007507 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7508 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007509
7510 result = PyUnicode_FromWideChar(print_name,
SSE43c34aad2018-02-13 00:10:35 +07007511 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
Larry Hastings2f936352014-08-05 14:04:04 +10007512 return result;
7513}
7514
7515#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7516
7517
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007518
Larry Hastings9cf065c2012-06-22 16:30:09 -07007519#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007520
7521#if defined(MS_WINDOWS)
7522
7523/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Steve Dower6921e732018-03-05 14:26:08 -08007524static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007525
Larry Hastings9cf065c2012-06-22 16:30:09 -07007526static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007527check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007528{
7529 HINSTANCE hKernel32;
7530 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007531 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007532 return 1;
7533 hKernel32 = GetModuleHandleW(L"KERNEL32");
7534 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7535 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007536 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007537}
7538
Steve Dower6921e732018-03-05 14:26:08 -08007539/* Remove the last portion of the path - return 0 on success */
7540static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007541_dirnameW(WCHAR *path)
7542{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007543 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007544 size_t length = wcsnlen_s(path, MAX_PATH);
7545 if (length == MAX_PATH) {
7546 return -1;
7547 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007548
7549 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007550 for(ptr = path + length; ptr != path; ptr--) {
7551 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007552 break;
Steve Dower6921e732018-03-05 14:26:08 -08007553 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007554 }
7555 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007556 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007557}
7558
Victor Stinner31b3b922013-06-05 01:49:17 +02007559/* Is this path absolute? */
7560static int
7561_is_absW(const WCHAR *path)
7562{
Steve Dower6921e732018-03-05 14:26:08 -08007563 return path[0] == L'\\' || path[0] == L'/' ||
7564 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007565}
7566
Steve Dower6921e732018-03-05 14:26:08 -08007567/* join root and rest with a backslash - return 0 on success */
7568static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007569_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7570{
Victor Stinner31b3b922013-06-05 01:49:17 +02007571 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007572 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007573 }
7574
Steve Dower6921e732018-03-05 14:26:08 -08007575 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7576 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007577 }
Steve Dower6921e732018-03-05 14:26:08 -08007578
7579 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7580 return -1;
7581 }
7582
7583 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007584}
7585
Victor Stinner31b3b922013-06-05 01:49:17 +02007586/* Return True if the path at src relative to dest is a directory */
7587static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007588_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007589{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007590 WIN32_FILE_ATTRIBUTE_DATA src_info;
7591 WCHAR dest_parent[MAX_PATH];
7592 WCHAR src_resolved[MAX_PATH] = L"";
7593
7594 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007595 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7596 _dirnameW(dest_parent)) {
7597 return 0;
7598 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007599 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007600 if (_joinW(src_resolved, dest_parent, src)) {
7601 return 0;
7602 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007603 return (
7604 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7605 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7606 );
7607}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007608#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007609
Larry Hastings2f936352014-08-05 14:04:04 +10007610
7611/*[clinic input]
7612os.symlink
7613 src: path_t
7614 dst: path_t
7615 target_is_directory: bool = False
7616 *
7617 dir_fd: dir_fd(requires='symlinkat')=None
7618
7619# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7620
7621Create a symbolic link pointing to src named dst.
7622
7623target_is_directory is required on Windows if the target is to be
7624 interpreted as a directory. (On Windows, symlink requires
7625 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7626 target_is_directory is ignored on non-Windows platforms.
7627
7628If dir_fd is not None, it should be a file descriptor open to a directory,
7629 and path should be relative; path will then be relative to that directory.
7630dir_fd may not be implemented on your platform.
7631 If it is unavailable, using it will raise a NotImplementedError.
7632
7633[clinic start generated code]*/
7634
Larry Hastings2f936352014-08-05 14:04:04 +10007635static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007636os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007637 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007638/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007639{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007640#ifdef MS_WINDOWS
7641 DWORD result;
7642#else
7643 int result;
7644#endif
7645
Larry Hastings9cf065c2012-06-22 16:30:09 -07007646#ifdef MS_WINDOWS
7647 if (!check_CreateSymbolicLink()) {
7648 PyErr_SetString(PyExc_NotImplementedError,
7649 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007650 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007651 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007652 if (!win32_can_symlink) {
7653 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007654 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007655 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007656#endif
7657
Larry Hastings9cf065c2012-06-22 16:30:09 -07007658#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007659
Larry Hastings9cf065c2012-06-22 16:30:09 -07007660 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007661 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007662 /* if src is a directory, ensure target_is_directory==1 */
7663 target_is_directory |= _check_dirW(src->wide, dst->wide);
7664 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7665 target_is_directory);
Steve Dower6921e732018-03-05 14:26:08 -08007666 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007667 Py_END_ALLOW_THREADS
7668
Larry Hastings2f936352014-08-05 14:04:04 +10007669 if (!result)
7670 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007671
7672#else
7673
Steve Dower6921e732018-03-05 14:26:08 -08007674 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7675 PyErr_SetString(PyExc_ValueError,
7676 "symlink: src and dst must be the same type");
7677 return NULL;
7678 }
7679
Larry Hastings9cf065c2012-06-22 16:30:09 -07007680 Py_BEGIN_ALLOW_THREADS
7681#if HAVE_SYMLINKAT
7682 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007683 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007684 else
7685#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007686 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007687 Py_END_ALLOW_THREADS
7688
Larry Hastings2f936352014-08-05 14:04:04 +10007689 if (result)
7690 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007691#endif
7692
Larry Hastings2f936352014-08-05 14:04:04 +10007693 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007694}
7695#endif /* HAVE_SYMLINK */
7696
Larry Hastings9cf065c2012-06-22 16:30:09 -07007697
Brian Curtind40e6f72010-07-08 21:39:08 +00007698
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007699
Larry Hastings605a62d2012-06-24 04:33:36 -07007700static PyStructSequence_Field times_result_fields[] = {
7701 {"user", "user time"},
7702 {"system", "system time"},
7703 {"children_user", "user time of children"},
7704 {"children_system", "system time of children"},
7705 {"elapsed", "elapsed time since an arbitrary point in the past"},
7706 {NULL}
7707};
7708
7709PyDoc_STRVAR(times_result__doc__,
7710"times_result: Result from os.times().\n\n\
7711This object may be accessed either as a tuple of\n\
7712 (user, system, children_user, children_system, elapsed),\n\
7713or via the attributes user, system, children_user, children_system,\n\
7714and elapsed.\n\
7715\n\
7716See os.times for more information.");
7717
7718static PyStructSequence_Desc times_result_desc = {
7719 "times_result", /* name */
7720 times_result__doc__, /* doc */
7721 times_result_fields,
7722 5
7723};
7724
7725static PyTypeObject TimesResultType;
7726
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007727#ifdef MS_WINDOWS
7728#define HAVE_TIMES /* mandatory, for the method table */
7729#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007730
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007731#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007732
7733static PyObject *
7734build_times_result(double user, double system,
7735 double children_user, double children_system,
7736 double elapsed)
7737{
7738 PyObject *value = PyStructSequence_New(&TimesResultType);
7739 if (value == NULL)
7740 return NULL;
7741
7742#define SET(i, field) \
7743 { \
7744 PyObject *o = PyFloat_FromDouble(field); \
7745 if (!o) { \
7746 Py_DECREF(value); \
7747 return NULL; \
7748 } \
7749 PyStructSequence_SET_ITEM(value, i, o); \
7750 } \
7751
7752 SET(0, user);
7753 SET(1, system);
7754 SET(2, children_user);
7755 SET(3, children_system);
7756 SET(4, elapsed);
7757
7758#undef SET
7759
7760 return value;
7761}
7762
Larry Hastings605a62d2012-06-24 04:33:36 -07007763
Larry Hastings2f936352014-08-05 14:04:04 +10007764#ifndef MS_WINDOWS
7765#define NEED_TICKS_PER_SECOND
7766static long ticks_per_second = -1;
7767#endif /* MS_WINDOWS */
7768
7769/*[clinic input]
7770os.times
7771
7772Return a collection containing process timing information.
7773
7774The object returned behaves like a named tuple with these fields:
7775 (utime, stime, cutime, cstime, elapsed_time)
7776All fields are floating point numbers.
7777[clinic start generated code]*/
7778
Larry Hastings2f936352014-08-05 14:04:04 +10007779static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007780os_times_impl(PyObject *module)
7781/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007782#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007783{
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 FILETIME create, exit, kernel, user;
7785 HANDLE hProc;
7786 hProc = GetCurrentProcess();
7787 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7788 /* The fields of a FILETIME structure are the hi and lo part
7789 of a 64-bit value expressed in 100 nanosecond units.
7790 1e7 is one second in such units; 1e-7 the inverse.
7791 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7792 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007793 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 (double)(user.dwHighDateTime*429.4967296 +
7795 user.dwLowDateTime*1e-7),
7796 (double)(kernel.dwHighDateTime*429.4967296 +
7797 kernel.dwLowDateTime*1e-7),
7798 (double)0,
7799 (double)0,
7800 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007801}
Larry Hastings2f936352014-08-05 14:04:04 +10007802#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007803{
Larry Hastings2f936352014-08-05 14:04:04 +10007804
7805
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007806 struct tms t;
7807 clock_t c;
7808 errno = 0;
7809 c = times(&t);
7810 if (c == (clock_t) -1)
7811 return posix_error();
7812 return build_times_result(
7813 (double)t.tms_utime / ticks_per_second,
7814 (double)t.tms_stime / ticks_per_second,
7815 (double)t.tms_cutime / ticks_per_second,
7816 (double)t.tms_cstime / ticks_per_second,
7817 (double)c / ticks_per_second);
7818}
Larry Hastings2f936352014-08-05 14:04:04 +10007819#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007820#endif /* HAVE_TIMES */
7821
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007822
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007823#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007824/*[clinic input]
7825os.getsid
7826
7827 pid: pid_t
7828 /
7829
7830Call the system call getsid(pid) and return the result.
7831[clinic start generated code]*/
7832
Larry Hastings2f936352014-08-05 14:04:04 +10007833static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007834os_getsid_impl(PyObject *module, pid_t pid)
7835/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007836{
Victor Stinner8c62be82010-05-06 00:08:46 +00007837 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007838 sid = getsid(pid);
7839 if (sid < 0)
7840 return posix_error();
7841 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007842}
7843#endif /* HAVE_GETSID */
7844
7845
Guido van Rossumb6775db1994-08-01 11:34:53 +00007846#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007847/*[clinic input]
7848os.setsid
7849
7850Call the system call setsid().
7851[clinic start generated code]*/
7852
Larry Hastings2f936352014-08-05 14:04:04 +10007853static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007854os_setsid_impl(PyObject *module)
7855/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007856{
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 if (setsid() < 0)
7858 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007859 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007860}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007861#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007862
Larry Hastings2f936352014-08-05 14:04:04 +10007863
Guido van Rossumb6775db1994-08-01 11:34:53 +00007864#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007865/*[clinic input]
7866os.setpgid
7867
7868 pid: pid_t
7869 pgrp: pid_t
7870 /
7871
7872Call the system call setpgid(pid, pgrp).
7873[clinic start generated code]*/
7874
Larry Hastings2f936352014-08-05 14:04:04 +10007875static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007876os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7877/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007878{
Victor Stinner8c62be82010-05-06 00:08:46 +00007879 if (setpgid(pid, pgrp) < 0)
7880 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007881 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007882}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007883#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007884
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007885
Guido van Rossumb6775db1994-08-01 11:34:53 +00007886#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007887/*[clinic input]
7888os.tcgetpgrp
7889
7890 fd: int
7891 /
7892
7893Return the process group associated with the terminal specified by fd.
7894[clinic start generated code]*/
7895
Larry Hastings2f936352014-08-05 14:04:04 +10007896static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007897os_tcgetpgrp_impl(PyObject *module, int fd)
7898/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007899{
7900 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007901 if (pgid < 0)
7902 return posix_error();
7903 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007904}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007905#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007906
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007907
Guido van Rossumb6775db1994-08-01 11:34:53 +00007908#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007909/*[clinic input]
7910os.tcsetpgrp
7911
7912 fd: int
7913 pgid: pid_t
7914 /
7915
7916Set 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_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7921/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007922{
Victor Stinner8c62be82010-05-06 00:08:46 +00007923 if (tcsetpgrp(fd, pgid) < 0)
7924 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007925 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007926}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007927#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007928
Guido van Rossum687dd131993-05-17 08:34:16 +00007929/* Functions acting on file descriptors */
7930
Victor Stinnerdaf45552013-08-28 00:53:59 +02007931#ifdef O_CLOEXEC
7932extern int _Py_open_cloexec_works;
7933#endif
7934
Larry Hastings2f936352014-08-05 14:04:04 +10007935
7936/*[clinic input]
7937os.open -> int
7938 path: path_t
7939 flags: int
7940 mode: int = 0o777
7941 *
7942 dir_fd: dir_fd(requires='openat') = None
7943
7944# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7945
7946Open a file for low level IO. Returns a file descriptor (integer).
7947
7948If dir_fd is not None, it should be a file descriptor open to a directory,
7949 and path should be relative; path will then be relative to that directory.
7950dir_fd may not be implemented on your platform.
7951 If it is unavailable, using it will raise a NotImplementedError.
7952[clinic start generated code]*/
7953
Larry Hastings2f936352014-08-05 14:04:04 +10007954static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007955os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7956/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007957{
7958 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007959 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007960
Victor Stinnerdaf45552013-08-28 00:53:59 +02007961#ifdef O_CLOEXEC
7962 int *atomic_flag_works = &_Py_open_cloexec_works;
7963#elif !defined(MS_WINDOWS)
7964 int *atomic_flag_works = NULL;
7965#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007966
Victor Stinnerdaf45552013-08-28 00:53:59 +02007967#ifdef MS_WINDOWS
7968 flags |= O_NOINHERIT;
7969#elif defined(O_CLOEXEC)
7970 flags |= O_CLOEXEC;
7971#endif
7972
Steve Dower8fc89802015-04-12 00:26:27 -04007973 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007974 do {
7975 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007976#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007977 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007978#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007979#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007980 if (dir_fd != DEFAULT_DIR_FD)
7981 fd = openat(dir_fd, path->narrow, flags, mode);
7982 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007983#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007984 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007985#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007986 Py_END_ALLOW_THREADS
7987 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007988 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007989
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007990 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007991 if (!async_err)
7992 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007993 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007994 }
7995
Victor Stinnerdaf45552013-08-28 00:53:59 +02007996#ifndef MS_WINDOWS
7997 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7998 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007999 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008000 }
8001#endif
8002
Larry Hastings2f936352014-08-05 14:04:04 +10008003 return fd;
8004}
8005
8006
8007/*[clinic input]
8008os.close
8009
8010 fd: int
8011
8012Close a file descriptor.
8013[clinic start generated code]*/
8014
Barry Warsaw53699e91996-12-10 23:23:01 +00008015static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008016os_close_impl(PyObject *module, int fd)
8017/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008018{
Larry Hastings2f936352014-08-05 14:04:04 +10008019 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008020 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8021 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8022 * for more details.
8023 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008025 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008026 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008027 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008028 Py_END_ALLOW_THREADS
8029 if (res < 0)
8030 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008031 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008032}
8033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008034
Larry Hastings2f936352014-08-05 14:04:04 +10008035/*[clinic input]
8036os.closerange
8037
8038 fd_low: int
8039 fd_high: int
8040 /
8041
8042Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8043[clinic start generated code]*/
8044
Larry Hastings2f936352014-08-05 14:04:04 +10008045static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008046os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8047/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008048{
8049 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008050 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008051 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008052 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008053 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008054 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008055 Py_END_ALLOW_THREADS
8056 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008057}
8058
8059
Larry Hastings2f936352014-08-05 14:04:04 +10008060/*[clinic input]
8061os.dup -> int
8062
8063 fd: int
8064 /
8065
8066Return a duplicate of a file descriptor.
8067[clinic start generated code]*/
8068
Larry Hastings2f936352014-08-05 14:04:04 +10008069static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008070os_dup_impl(PyObject *module, int fd)
8071/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008072{
8073 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008074}
8075
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008076
Larry Hastings2f936352014-08-05 14:04:04 +10008077/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008078os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008079 fd: int
8080 fd2: int
8081 inheritable: bool=True
8082
8083Duplicate file descriptor.
8084[clinic start generated code]*/
8085
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008086static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008087os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008088/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008089{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008090 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008091#if defined(HAVE_DUP3) && \
8092 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8093 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008094 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008095#endif
8096
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008097 if (fd < 0 || fd2 < 0) {
8098 posix_error();
8099 return -1;
8100 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008101
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008102 /* dup2() can fail with EINTR if the target FD is already open, because it
8103 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8104 * upon close(), and therefore below.
8105 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008106#ifdef MS_WINDOWS
8107 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008108 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008109 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008110 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008111 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008112 if (res < 0) {
8113 posix_error();
8114 return -1;
8115 }
8116 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008117
8118 /* Character files like console cannot be make non-inheritable */
8119 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8120 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008121 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008122 }
8123
8124#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8125 Py_BEGIN_ALLOW_THREADS
8126 if (!inheritable)
8127 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8128 else
8129 res = dup2(fd, fd2);
8130 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008131 if (res < 0) {
8132 posix_error();
8133 return -1;
8134 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008135
8136#else
8137
8138#ifdef HAVE_DUP3
8139 if (!inheritable && dup3_works != 0) {
8140 Py_BEGIN_ALLOW_THREADS
8141 res = dup3(fd, fd2, O_CLOEXEC);
8142 Py_END_ALLOW_THREADS
8143 if (res < 0) {
8144 if (dup3_works == -1)
8145 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008146 if (dup3_works) {
8147 posix_error();
8148 return -1;
8149 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008150 }
8151 }
8152
8153 if (inheritable || dup3_works == 0)
8154 {
8155#endif
8156 Py_BEGIN_ALLOW_THREADS
8157 res = dup2(fd, fd2);
8158 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008159 if (res < 0) {
8160 posix_error();
8161 return -1;
8162 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008163
8164 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8165 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008166 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008167 }
8168#ifdef HAVE_DUP3
8169 }
8170#endif
8171
8172#endif
8173
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008174 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008175}
8176
Larry Hastings2f936352014-08-05 14:04:04 +10008177
Ross Lagerwall7807c352011-03-17 20:20:30 +02008178#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008179/*[clinic input]
8180os.lockf
8181
8182 fd: int
8183 An open file descriptor.
8184 command: int
8185 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8186 length: Py_off_t
8187 The number of bytes to lock, starting at the current position.
8188 /
8189
8190Apply, test or remove a POSIX lock on an open file descriptor.
8191
8192[clinic start generated code]*/
8193
Larry Hastings2f936352014-08-05 14:04:04 +10008194static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008195os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8196/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008197{
8198 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008199
8200 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008201 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008202 Py_END_ALLOW_THREADS
8203
8204 if (res < 0)
8205 return posix_error();
8206
8207 Py_RETURN_NONE;
8208}
Larry Hastings2f936352014-08-05 14:04:04 +10008209#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008210
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008211
Larry Hastings2f936352014-08-05 14:04:04 +10008212/*[clinic input]
8213os.lseek -> Py_off_t
8214
8215 fd: int
8216 position: Py_off_t
8217 how: int
8218 /
8219
8220Set the position of a file descriptor. Return the new position.
8221
8222Return the new cursor position in number of bytes
8223relative to the beginning of the file.
8224[clinic start generated code]*/
8225
Larry Hastings2f936352014-08-05 14:04:04 +10008226static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008227os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8228/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008229{
8230 Py_off_t result;
8231
Guido van Rossum687dd131993-05-17 08:34:16 +00008232#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008233 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8234 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008235 case 0: how = SEEK_SET; break;
8236 case 1: how = SEEK_CUR; break;
8237 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008238 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008239#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008240
Victor Stinner8c62be82010-05-06 00:08:46 +00008241 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10008242 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008243
Victor Stinner8c62be82010-05-06 00:08:46 +00008244 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008245 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008246#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008247 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008248#else
Larry Hastings2f936352014-08-05 14:04:04 +10008249 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008250#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008251 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008252 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008253 if (result < 0)
8254 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008255
Larry Hastings2f936352014-08-05 14:04:04 +10008256 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008257}
8258
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008259
Larry Hastings2f936352014-08-05 14:04:04 +10008260/*[clinic input]
8261os.read
8262 fd: int
8263 length: Py_ssize_t
8264 /
8265
8266Read from a file descriptor. Returns a bytes object.
8267[clinic start generated code]*/
8268
Larry Hastings2f936352014-08-05 14:04:04 +10008269static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008270os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8271/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008272{
Victor Stinner8c62be82010-05-06 00:08:46 +00008273 Py_ssize_t n;
8274 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008275
8276 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008277 errno = EINVAL;
8278 return posix_error();
8279 }
Larry Hastings2f936352014-08-05 14:04:04 +10008280
8281#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008282 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008283 if (length > INT_MAX)
8284 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008285#endif
8286
8287 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008288 if (buffer == NULL)
8289 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008290
Victor Stinner66aab0c2015-03-19 22:53:20 +01008291 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8292 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008293 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008294 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008295 }
Larry Hastings2f936352014-08-05 14:04:04 +10008296
8297 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008298 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008299
Victor Stinner8c62be82010-05-06 00:08:46 +00008300 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008301}
8302
Ross Lagerwall7807c352011-03-17 20:20:30 +02008303#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8304 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008305static Py_ssize_t
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008306iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008307{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008308 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008309 Py_ssize_t blen, total = 0;
8310
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008311 *iov = PyMem_New(struct iovec, cnt);
8312 if (*iov == NULL) {
8313 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008314 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008315 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008316
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008317 *buf = PyMem_New(Py_buffer, cnt);
8318 if (*buf == NULL) {
8319 PyMem_Del(*iov);
8320 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008321 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008322 }
8323
8324 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008325 PyObject *item = PySequence_GetItem(seq, i);
8326 if (item == NULL)
8327 goto fail;
8328 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8329 Py_DECREF(item);
8330 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008331 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008332 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008333 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008334 blen = (*buf)[i].len;
8335 (*iov)[i].iov_len = blen;
8336 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008337 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008338 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008339
8340fail:
8341 PyMem_Del(*iov);
8342 for (j = 0; j < i; j++) {
8343 PyBuffer_Release(&(*buf)[j]);
8344 }
8345 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008346 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008347}
8348
8349static void
8350iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8351{
8352 int i;
8353 PyMem_Del(iov);
8354 for (i = 0; i < cnt; i++) {
8355 PyBuffer_Release(&buf[i]);
8356 }
8357 PyMem_Del(buf);
8358}
8359#endif
8360
Larry Hastings2f936352014-08-05 14:04:04 +10008361
Ross Lagerwall7807c352011-03-17 20:20:30 +02008362#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008363/*[clinic input]
8364os.readv -> Py_ssize_t
8365
8366 fd: int
8367 buffers: object
8368 /
8369
8370Read from a file descriptor fd into an iterable of buffers.
8371
8372The buffers should be mutable buffers accepting bytes.
8373readv will transfer data into each buffer until it is full
8374and then move on to the next buffer in the sequence to hold
8375the rest of the data.
8376
8377readv returns the total number of bytes read,
8378which may be less than the total capacity of all the buffers.
8379[clinic start generated code]*/
8380
Larry Hastings2f936352014-08-05 14:04:04 +10008381static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008382os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8383/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008384{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008385 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008386 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008387 struct iovec *iov;
8388 Py_buffer *buf;
8389
Larry Hastings2f936352014-08-05 14:04:04 +10008390 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008391 PyErr_SetString(PyExc_TypeError,
8392 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008393 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008394 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008395
Larry Hastings2f936352014-08-05 14:04:04 +10008396 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008397 if (cnt < 0)
8398 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008399
8400 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8401 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008402
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008403 do {
8404 Py_BEGIN_ALLOW_THREADS
8405 n = readv(fd, iov, cnt);
8406 Py_END_ALLOW_THREADS
8407 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008408
8409 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008410 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008411 if (!async_err)
8412 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008413 return -1;
8414 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008415
Larry Hastings2f936352014-08-05 14:04:04 +10008416 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008417}
Larry Hastings2f936352014-08-05 14:04:04 +10008418#endif /* HAVE_READV */
8419
Ross Lagerwall7807c352011-03-17 20:20:30 +02008420
8421#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008422/*[clinic input]
8423# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8424os.pread
8425
8426 fd: int
8427 length: int
8428 offset: Py_off_t
8429 /
8430
8431Read a number of bytes from a file descriptor starting at a particular offset.
8432
8433Read length bytes from file descriptor fd, starting at offset bytes from
8434the beginning of the file. The file offset remains unchanged.
8435[clinic start generated code]*/
8436
Larry Hastings2f936352014-08-05 14:04:04 +10008437static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008438os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8439/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008440{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008441 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008442 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008443 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008444
Larry Hastings2f936352014-08-05 14:04:04 +10008445 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008446 errno = EINVAL;
8447 return posix_error();
8448 }
Larry Hastings2f936352014-08-05 14:04:04 +10008449 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008450 if (buffer == NULL)
8451 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008452
8453 do {
8454 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008455 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008456 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008457 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008458 Py_END_ALLOW_THREADS
8459 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8460
Ross Lagerwall7807c352011-03-17 20:20:30 +02008461 if (n < 0) {
8462 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008463 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008464 }
Larry Hastings2f936352014-08-05 14:04:04 +10008465 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008466 _PyBytes_Resize(&buffer, n);
8467 return buffer;
8468}
Larry Hastings2f936352014-08-05 14:04:04 +10008469#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008470
Pablo Galindo4defba32018-01-27 16:16:37 +00008471#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8472/*[clinic input]
8473os.preadv -> Py_ssize_t
8474
8475 fd: int
8476 buffers: object
8477 offset: Py_off_t
8478 flags: int = 0
8479 /
8480
8481Reads from a file descriptor into a number of mutable bytes-like objects.
8482
8483Combines the functionality of readv() and pread(). As readv(), it will
8484transfer data into each buffer until it is full and then move on to the next
8485buffer in the sequence to hold the rest of the data. Its fourth argument,
8486specifies the file offset at which the input operation is to be performed. It
8487will return the total number of bytes read (which can be less than the total
8488capacity of all the objects).
8489
8490The flags argument contains a bitwise OR of zero or more of the following flags:
8491
8492- RWF_HIPRI
8493- RWF_NOWAIT
8494
8495Using non-zero flags requires Linux 4.6 or newer.
8496[clinic start generated code]*/
8497
8498static Py_ssize_t
8499os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8500 int flags)
8501/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8502{
8503 Py_ssize_t cnt, n;
8504 int async_err = 0;
8505 struct iovec *iov;
8506 Py_buffer *buf;
8507
8508 if (!PySequence_Check(buffers)) {
8509 PyErr_SetString(PyExc_TypeError,
8510 "preadv2() arg 2 must be a sequence");
8511 return -1;
8512 }
8513
8514 cnt = PySequence_Size(buffers);
8515 if (cnt < 0) {
8516 return -1;
8517 }
8518
8519#ifndef HAVE_PREADV2
8520 if(flags != 0) {
8521 argument_unavailable_error("preadv2", "flags");
8522 return -1;
8523 }
8524#endif
8525
8526 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8527 return -1;
8528 }
8529#ifdef HAVE_PREADV2
8530 do {
8531 Py_BEGIN_ALLOW_THREADS
8532 _Py_BEGIN_SUPPRESS_IPH
8533 n = preadv2(fd, iov, cnt, offset, flags);
8534 _Py_END_SUPPRESS_IPH
8535 Py_END_ALLOW_THREADS
8536 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8537#else
8538 do {
8539 Py_BEGIN_ALLOW_THREADS
8540 _Py_BEGIN_SUPPRESS_IPH
8541 n = preadv(fd, iov, cnt, offset);
8542 _Py_END_SUPPRESS_IPH
8543 Py_END_ALLOW_THREADS
8544 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8545#endif
8546
8547 iov_cleanup(iov, buf, cnt);
8548 if (n < 0) {
8549 if (!async_err) {
8550 posix_error();
8551 }
8552 return -1;
8553 }
8554
8555 return n;
8556}
8557#endif /* HAVE_PREADV */
8558
Larry Hastings2f936352014-08-05 14:04:04 +10008559
8560/*[clinic input]
8561os.write -> Py_ssize_t
8562
8563 fd: int
8564 data: Py_buffer
8565 /
8566
8567Write a bytes object to a file descriptor.
8568[clinic start generated code]*/
8569
Larry Hastings2f936352014-08-05 14:04:04 +10008570static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008571os_write_impl(PyObject *module, int fd, Py_buffer *data)
8572/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008573{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008574 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008575}
8576
8577#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008578PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008579"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008580sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008581 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008582Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008583
Larry Hastings2f936352014-08-05 14:04:04 +10008584/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008585static PyObject *
8586posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8587{
8588 int in, out;
8589 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008590 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008591 off_t offset;
8592
8593#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8594#ifndef __APPLE__
8595 Py_ssize_t len;
8596#endif
8597 PyObject *headers = NULL, *trailers = NULL;
8598 Py_buffer *hbuf, *tbuf;
8599 off_t sbytes;
8600 struct sf_hdtr sf;
8601 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008602 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008603 static char *keywords[] = {"out", "in",
8604 "offset", "count",
8605 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008606
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008607 sf.headers = NULL;
8608 sf.trailers = NULL;
8609
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008610#ifdef __APPLE__
8611 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008612 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008613#else
8614 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008615 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008616#endif
8617 &headers, &trailers, &flags))
8618 return NULL;
8619 if (headers != NULL) {
8620 if (!PySequence_Check(headers)) {
8621 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008622 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008623 return NULL;
8624 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008625 Py_ssize_t i = PySequence_Size(headers);
8626 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008627 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008628 if (i > INT_MAX) {
8629 PyErr_SetString(PyExc_OverflowError,
8630 "sendfile() header is too large");
8631 return NULL;
8632 }
8633 if (i > 0) {
8634 sf.hdr_cnt = (int)i;
8635 i = iov_setup(&(sf.headers), &hbuf,
8636 headers, sf.hdr_cnt, PyBUF_SIMPLE);
8637 if (i < 0)
8638 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008639#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008640 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008641#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008642 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008643 }
8644 }
8645 if (trailers != NULL) {
8646 if (!PySequence_Check(trailers)) {
8647 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008648 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008649 return NULL;
8650 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008651 Py_ssize_t i = PySequence_Size(trailers);
8652 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008653 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008654 if (i > INT_MAX) {
8655 PyErr_SetString(PyExc_OverflowError,
8656 "sendfile() trailer is too large");
8657 return NULL;
8658 }
8659 if (i > 0) {
8660 sf.trl_cnt = (int)i;
8661 i = iov_setup(&(sf.trailers), &tbuf,
8662 trailers, sf.trl_cnt, PyBUF_SIMPLE);
8663 if (i < 0)
8664 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008665#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008666 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008667#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008668 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008669 }
8670 }
8671
Steve Dower8fc89802015-04-12 00:26:27 -04008672 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008673 do {
8674 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008675#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008676 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008677#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008678 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008679#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008680 Py_END_ALLOW_THREADS
8681 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008682 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008683
8684 if (sf.headers != NULL)
8685 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8686 if (sf.trailers != NULL)
8687 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8688
8689 if (ret < 0) {
8690 if ((errno == EAGAIN) || (errno == EBUSY)) {
8691 if (sbytes != 0) {
8692 // some data has been sent
8693 goto done;
8694 }
8695 else {
8696 // no data has been sent; upper application is supposed
8697 // to retry on EAGAIN or EBUSY
8698 return posix_error();
8699 }
8700 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008701 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008702 }
8703 goto done;
8704
8705done:
8706 #if !defined(HAVE_LARGEFILE_SUPPORT)
8707 return Py_BuildValue("l", sbytes);
8708 #else
8709 return Py_BuildValue("L", sbytes);
8710 #endif
8711
8712#else
8713 Py_ssize_t count;
8714 PyObject *offobj;
8715 static char *keywords[] = {"out", "in",
8716 "offset", "count", NULL};
8717 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8718 keywords, &out, &in, &offobj, &count))
8719 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008720#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008721 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008722 do {
8723 Py_BEGIN_ALLOW_THREADS
8724 ret = sendfile(out, in, NULL, count);
8725 Py_END_ALLOW_THREADS
8726 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008727 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008728 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008729 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008730 }
8731#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008732 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008733 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008734
8735 do {
8736 Py_BEGIN_ALLOW_THREADS
8737 ret = sendfile(out, in, &offset, count);
8738 Py_END_ALLOW_THREADS
8739 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008740 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008741 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008742 return Py_BuildValue("n", ret);
8743#endif
8744}
Larry Hastings2f936352014-08-05 14:04:04 +10008745#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008746
Larry Hastings2f936352014-08-05 14:04:04 +10008747
8748/*[clinic input]
8749os.fstat
8750
8751 fd : int
8752
8753Perform a stat system call on the given file descriptor.
8754
8755Like stat(), but for an open file descriptor.
8756Equivalent to os.stat(fd).
8757[clinic start generated code]*/
8758
Larry Hastings2f936352014-08-05 14:04:04 +10008759static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008760os_fstat_impl(PyObject *module, int fd)
8761/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008762{
Victor Stinner8c62be82010-05-06 00:08:46 +00008763 STRUCT_STAT st;
8764 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008765 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008766
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008767 do {
8768 Py_BEGIN_ALLOW_THREADS
8769 res = FSTAT(fd, &st);
8770 Py_END_ALLOW_THREADS
8771 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008772 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008773#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008774 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008775#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008776 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008777#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008778 }
Tim Peters5aa91602002-01-30 05:46:57 +00008779
Victor Stinner4195b5c2012-02-08 23:03:19 +01008780 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008781}
8782
Larry Hastings2f936352014-08-05 14:04:04 +10008783
8784/*[clinic input]
8785os.isatty -> bool
8786 fd: int
8787 /
8788
8789Return True if the fd is connected to a terminal.
8790
8791Return True if the file descriptor is an open file descriptor
8792connected to the slave end of a terminal.
8793[clinic start generated code]*/
8794
Larry Hastings2f936352014-08-05 14:04:04 +10008795static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008796os_isatty_impl(PyObject *module, int fd)
8797/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008798{
Steve Dower8fc89802015-04-12 00:26:27 -04008799 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008800 _Py_BEGIN_SUPPRESS_IPH
8801 return_value = isatty(fd);
8802 _Py_END_SUPPRESS_IPH
8803 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008804}
8805
8806
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008807#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008808/*[clinic input]
8809os.pipe
8810
8811Create a pipe.
8812
8813Returns a tuple of two file descriptors:
8814 (read_fd, write_fd)
8815[clinic start generated code]*/
8816
Larry Hastings2f936352014-08-05 14:04:04 +10008817static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008818os_pipe_impl(PyObject *module)
8819/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008820{
Victor Stinner8c62be82010-05-06 00:08:46 +00008821 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008822#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008823 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008824 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008825 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008826#else
8827 int res;
8828#endif
8829
8830#ifdef MS_WINDOWS
8831 attr.nLength = sizeof(attr);
8832 attr.lpSecurityDescriptor = NULL;
8833 attr.bInheritHandle = FALSE;
8834
8835 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008836 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008837 ok = CreatePipe(&read, &write, &attr, 0);
8838 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008839 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8840 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008841 if (fds[0] == -1 || fds[1] == -1) {
8842 CloseHandle(read);
8843 CloseHandle(write);
8844 ok = 0;
8845 }
8846 }
Steve Dowerc3630612016-11-19 18:41:16 -08008847 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008848 Py_END_ALLOW_THREADS
8849
Victor Stinner8c62be82010-05-06 00:08:46 +00008850 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008851 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008852#else
8853
8854#ifdef HAVE_PIPE2
8855 Py_BEGIN_ALLOW_THREADS
8856 res = pipe2(fds, O_CLOEXEC);
8857 Py_END_ALLOW_THREADS
8858
8859 if (res != 0 && errno == ENOSYS)
8860 {
8861#endif
8862 Py_BEGIN_ALLOW_THREADS
8863 res = pipe(fds);
8864 Py_END_ALLOW_THREADS
8865
8866 if (res == 0) {
8867 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8868 close(fds[0]);
8869 close(fds[1]);
8870 return NULL;
8871 }
8872 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8873 close(fds[0]);
8874 close(fds[1]);
8875 return NULL;
8876 }
8877 }
8878#ifdef HAVE_PIPE2
8879 }
8880#endif
8881
8882 if (res != 0)
8883 return PyErr_SetFromErrno(PyExc_OSError);
8884#endif /* !MS_WINDOWS */
8885 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008886}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008887#endif /* HAVE_PIPE */
8888
Larry Hastings2f936352014-08-05 14:04:04 +10008889
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008890#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008891/*[clinic input]
8892os.pipe2
8893
8894 flags: int
8895 /
8896
8897Create a pipe with flags set atomically.
8898
8899Returns a tuple of two file descriptors:
8900 (read_fd, write_fd)
8901
8902flags can be constructed by ORing together one or more of these values:
8903O_NONBLOCK, O_CLOEXEC.
8904[clinic start generated code]*/
8905
Larry Hastings2f936352014-08-05 14:04:04 +10008906static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008907os_pipe2_impl(PyObject *module, int flags)
8908/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008909{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008910 int fds[2];
8911 int res;
8912
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008913 res = pipe2(fds, flags);
8914 if (res != 0)
8915 return posix_error();
8916 return Py_BuildValue("(ii)", fds[0], fds[1]);
8917}
8918#endif /* HAVE_PIPE2 */
8919
Larry Hastings2f936352014-08-05 14:04:04 +10008920
Ross Lagerwall7807c352011-03-17 20:20:30 +02008921#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008922/*[clinic input]
8923os.writev -> Py_ssize_t
8924 fd: int
8925 buffers: object
8926 /
8927
8928Iterate over buffers, and write the contents of each to a file descriptor.
8929
8930Returns the total number of bytes written.
8931buffers must be a sequence of bytes-like objects.
8932[clinic start generated code]*/
8933
Larry Hastings2f936352014-08-05 14:04:04 +10008934static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008935os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8936/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008937{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008938 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008939 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008940 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008941 struct iovec *iov;
8942 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008943
8944 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008945 PyErr_SetString(PyExc_TypeError,
8946 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008947 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008948 }
Larry Hastings2f936352014-08-05 14:04:04 +10008949 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008950 if (cnt < 0)
8951 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008952
Larry Hastings2f936352014-08-05 14:04:04 +10008953 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8954 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008955 }
8956
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008957 do {
8958 Py_BEGIN_ALLOW_THREADS
8959 result = writev(fd, iov, cnt);
8960 Py_END_ALLOW_THREADS
8961 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008962
8963 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008964 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008965 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008966
Georg Brandl306336b2012-06-24 12:55:33 +02008967 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008968}
Larry Hastings2f936352014-08-05 14:04:04 +10008969#endif /* HAVE_WRITEV */
8970
8971
8972#ifdef HAVE_PWRITE
8973/*[clinic input]
8974os.pwrite -> Py_ssize_t
8975
8976 fd: int
8977 buffer: Py_buffer
8978 offset: Py_off_t
8979 /
8980
8981Write bytes to a file descriptor starting at a particular offset.
8982
8983Write buffer to fd, starting at offset bytes from the beginning of
8984the file. Returns the number of bytes writte. Does not change the
8985current file offset.
8986[clinic start generated code]*/
8987
Larry Hastings2f936352014-08-05 14:04:04 +10008988static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008989os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8990/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008991{
8992 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008993 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008994
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008995 do {
8996 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008997 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008998 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008999 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009000 Py_END_ALLOW_THREADS
9001 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009002
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009003 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009004 posix_error();
9005 return size;
9006}
9007#endif /* HAVE_PWRITE */
9008
Pablo Galindo4defba32018-01-27 16:16:37 +00009009#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9010/*[clinic input]
9011os.pwritev -> Py_ssize_t
9012
9013 fd: int
9014 buffers: object
9015 offset: Py_off_t
9016 flags: int = 0
9017 /
9018
9019Writes the contents of bytes-like objects to a file descriptor at a given offset.
9020
9021Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9022of bytes-like objects. Buffers are processed in array order. Entire contents of first
9023buffer is written before proceeding to second, and so on. The operating system may
9024set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9025This function writes the contents of each object to the file descriptor and returns
9026the total number of bytes written.
9027
9028The flags argument contains a bitwise OR of zero or more of the following flags:
9029
9030- RWF_DSYNC
9031- RWF_SYNC
9032
9033Using non-zero flags requires Linux 4.7 or newer.
9034[clinic start generated code]*/
9035
9036static Py_ssize_t
9037os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9038 int flags)
9039/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9040{
9041 Py_ssize_t cnt;
9042 Py_ssize_t result;
9043 int async_err = 0;
9044 struct iovec *iov;
9045 Py_buffer *buf;
9046
9047 if (!PySequence_Check(buffers)) {
9048 PyErr_SetString(PyExc_TypeError,
9049 "pwritev() arg 2 must be a sequence");
9050 return -1;
9051 }
9052
9053 cnt = PySequence_Size(buffers);
9054 if (cnt < 0) {
9055 return -1;
9056 }
9057
9058#ifndef HAVE_PWRITEV2
9059 if(flags != 0) {
9060 argument_unavailable_error("pwritev2", "flags");
9061 return -1;
9062 }
9063#endif
9064
9065 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9066 return -1;
9067 }
9068#ifdef HAVE_PWRITEV2
9069 do {
9070 Py_BEGIN_ALLOW_THREADS
9071 _Py_BEGIN_SUPPRESS_IPH
9072 result = pwritev2(fd, iov, cnt, offset, flags);
9073 _Py_END_SUPPRESS_IPH
9074 Py_END_ALLOW_THREADS
9075 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9076#else
9077 do {
9078 Py_BEGIN_ALLOW_THREADS
9079 _Py_BEGIN_SUPPRESS_IPH
9080 result = pwritev(fd, iov, cnt, offset);
9081 _Py_END_SUPPRESS_IPH
9082 Py_END_ALLOW_THREADS
9083 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9084#endif
9085
9086 iov_cleanup(iov, buf, cnt);
9087 if (result < 0) {
9088 if (!async_err) {
9089 posix_error();
9090 }
9091 return -1;
9092 }
9093
9094 return result;
9095}
9096#endif /* HAVE_PWRITEV */
9097
9098
9099
Larry Hastings2f936352014-08-05 14:04:04 +10009100
9101#ifdef HAVE_MKFIFO
9102/*[clinic input]
9103os.mkfifo
9104
9105 path: path_t
9106 mode: int=0o666
9107 *
9108 dir_fd: dir_fd(requires='mkfifoat')=None
9109
9110Create a "fifo" (a POSIX named pipe).
9111
9112If dir_fd is not None, it should be a file descriptor open to a directory,
9113 and path should be relative; path will then be relative to that directory.
9114dir_fd may not be implemented on your platform.
9115 If it is unavailable, using it will raise a NotImplementedError.
9116[clinic start generated code]*/
9117
Larry Hastings2f936352014-08-05 14:04:04 +10009118static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009119os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9120/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009121{
9122 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009123 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009124
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009125 do {
9126 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009127#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009128 if (dir_fd != DEFAULT_DIR_FD)
9129 result = mkfifoat(dir_fd, path->narrow, mode);
9130 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009131#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009132 result = mkfifo(path->narrow, mode);
9133 Py_END_ALLOW_THREADS
9134 } while (result != 0 && errno == EINTR &&
9135 !(async_err = PyErr_CheckSignals()));
9136 if (result != 0)
9137 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009138
9139 Py_RETURN_NONE;
9140}
9141#endif /* HAVE_MKFIFO */
9142
9143
9144#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9145/*[clinic input]
9146os.mknod
9147
9148 path: path_t
9149 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009150 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009151 *
9152 dir_fd: dir_fd(requires='mknodat')=None
9153
9154Create a node in the file system.
9155
9156Create a node in the file system (file, device special file or named pipe)
9157at path. mode specifies both the permissions to use and the
9158type of node to be created, being combined (bitwise OR) with one of
9159S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9160device defines the newly created device special file (probably using
9161os.makedev()). Otherwise device is ignored.
9162
9163If dir_fd is not None, it should be a file descriptor open to a directory,
9164 and path should be relative; path will then be relative to that directory.
9165dir_fd may not be implemented on your platform.
9166 If it is unavailable, using it will raise a NotImplementedError.
9167[clinic start generated code]*/
9168
Larry Hastings2f936352014-08-05 14:04:04 +10009169static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009170os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009171 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009172/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009173{
9174 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009175 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009176
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009177 do {
9178 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009179#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009180 if (dir_fd != DEFAULT_DIR_FD)
9181 result = mknodat(dir_fd, path->narrow, mode, device);
9182 else
Larry Hastings2f936352014-08-05 14:04:04 +10009183#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009184 result = mknod(path->narrow, mode, device);
9185 Py_END_ALLOW_THREADS
9186 } while (result != 0 && errno == EINTR &&
9187 !(async_err = PyErr_CheckSignals()));
9188 if (result != 0)
9189 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009190
9191 Py_RETURN_NONE;
9192}
9193#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9194
9195
9196#ifdef HAVE_DEVICE_MACROS
9197/*[clinic input]
9198os.major -> unsigned_int
9199
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009200 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009201 /
9202
9203Extracts a device major number from a raw device number.
9204[clinic start generated code]*/
9205
Larry Hastings2f936352014-08-05 14:04:04 +10009206static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009207os_major_impl(PyObject *module, dev_t device)
9208/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009209{
9210 return major(device);
9211}
9212
9213
9214/*[clinic input]
9215os.minor -> unsigned_int
9216
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009217 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009218 /
9219
9220Extracts a device minor number from a raw device number.
9221[clinic start generated code]*/
9222
Larry Hastings2f936352014-08-05 14:04:04 +10009223static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009224os_minor_impl(PyObject *module, dev_t device)
9225/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009226{
9227 return minor(device);
9228}
9229
9230
9231/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009232os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009233
9234 major: int
9235 minor: int
9236 /
9237
9238Composes a raw device number from the major and minor device numbers.
9239[clinic start generated code]*/
9240
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009241static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009242os_makedev_impl(PyObject *module, int major, int minor)
9243/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009244{
9245 return makedev(major, minor);
9246}
9247#endif /* HAVE_DEVICE_MACROS */
9248
9249
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009250#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009251/*[clinic input]
9252os.ftruncate
9253
9254 fd: int
9255 length: Py_off_t
9256 /
9257
9258Truncate a file, specified by file descriptor, to a specific length.
9259[clinic start generated code]*/
9260
Larry Hastings2f936352014-08-05 14:04:04 +10009261static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009262os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9263/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009264{
9265 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009266 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009267
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009268 do {
9269 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009270 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009271#ifdef MS_WINDOWS
9272 result = _chsize_s(fd, length);
9273#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009274 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009275#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009276 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009277 Py_END_ALLOW_THREADS
9278 } while (result != 0 && errno == EINTR &&
9279 !(async_err = PyErr_CheckSignals()));
9280 if (result != 0)
9281 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009282 Py_RETURN_NONE;
9283}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009284#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009285
9286
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009287#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009288/*[clinic input]
9289os.truncate
9290 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9291 length: Py_off_t
9292
9293Truncate a file, specified by path, to a specific length.
9294
9295On some platforms, path may also be specified as an open file descriptor.
9296 If this functionality is unavailable, using it raises an exception.
9297[clinic start generated code]*/
9298
Larry Hastings2f936352014-08-05 14:04:04 +10009299static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009300os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9301/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009302{
9303 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009304#ifdef MS_WINDOWS
9305 int fd;
9306#endif
9307
9308 if (path->fd != -1)
9309 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009310
9311 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009312 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009313#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009314 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009315 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009316 result = -1;
9317 else {
9318 result = _chsize_s(fd, length);
9319 close(fd);
9320 if (result < 0)
9321 errno = result;
9322 }
9323#else
9324 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009325#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009326 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009327 Py_END_ALLOW_THREADS
9328 if (result < 0)
9329 return path_error(path);
9330
9331 Py_RETURN_NONE;
9332}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009333#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009334
Ross Lagerwall7807c352011-03-17 20:20:30 +02009335
Victor Stinnerd6b17692014-09-30 12:20:05 +02009336/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9337 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9338 defined, which is the case in Python on AIX. AIX bug report:
9339 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9340#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9341# define POSIX_FADVISE_AIX_BUG
9342#endif
9343
Victor Stinnerec39e262014-09-30 12:35:58 +02009344
Victor Stinnerd6b17692014-09-30 12:20:05 +02009345#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009346/*[clinic input]
9347os.posix_fallocate
9348
9349 fd: int
9350 offset: Py_off_t
9351 length: Py_off_t
9352 /
9353
9354Ensure a file has allocated at least a particular number of bytes on disk.
9355
9356Ensure that the file specified by fd encompasses a range of bytes
9357starting at offset bytes from the beginning and continuing for length bytes.
9358[clinic start generated code]*/
9359
Larry Hastings2f936352014-08-05 14:04:04 +10009360static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009361os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009362 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009363/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009364{
9365 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009366 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009367
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009368 do {
9369 Py_BEGIN_ALLOW_THREADS
9370 result = posix_fallocate(fd, offset, length);
9371 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009372 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9373
9374 if (result == 0)
9375 Py_RETURN_NONE;
9376
9377 if (async_err)
9378 return NULL;
9379
9380 errno = result;
9381 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009382}
Victor Stinnerec39e262014-09-30 12:35:58 +02009383#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009384
Ross Lagerwall7807c352011-03-17 20:20:30 +02009385
Victor Stinnerd6b17692014-09-30 12:20:05 +02009386#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009387/*[clinic input]
9388os.posix_fadvise
9389
9390 fd: int
9391 offset: Py_off_t
9392 length: Py_off_t
9393 advice: int
9394 /
9395
9396Announce an intention to access data in a specific pattern.
9397
9398Announce an intention to access data in a specific pattern, thus allowing
9399the kernel to make optimizations.
9400The advice applies to the region of the file specified by fd starting at
9401offset and continuing for length bytes.
9402advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9403POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9404POSIX_FADV_DONTNEED.
9405[clinic start generated code]*/
9406
Larry Hastings2f936352014-08-05 14:04:04 +10009407static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009408os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009409 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009410/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009411{
9412 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009413 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009414
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009415 do {
9416 Py_BEGIN_ALLOW_THREADS
9417 result = posix_fadvise(fd, offset, length, advice);
9418 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009419 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9420
9421 if (result == 0)
9422 Py_RETURN_NONE;
9423
9424 if (async_err)
9425 return NULL;
9426
9427 errno = result;
9428 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009429}
Victor Stinnerec39e262014-09-30 12:35:58 +02009430#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009431
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009432#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009433
Fred Drake762e2061999-08-26 17:23:54 +00009434/* Save putenv() parameters as values here, so we can collect them when they
9435 * get re-set with another call for the same key. */
9436static PyObject *posix_putenv_garbage;
9437
Larry Hastings2f936352014-08-05 14:04:04 +10009438static void
9439posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009440{
Larry Hastings2f936352014-08-05 14:04:04 +10009441 /* Install the first arg and newstr in posix_putenv_garbage;
9442 * this will cause previous value to be collected. This has to
9443 * happen after the real putenv() call because the old value
9444 * was still accessible until then. */
9445 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9446 /* really not much we can do; just leak */
9447 PyErr_Clear();
9448 else
9449 Py_DECREF(value);
9450}
9451
9452
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009453#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009454/*[clinic input]
9455os.putenv
9456
9457 name: unicode
9458 value: unicode
9459 /
9460
9461Change or add an environment variable.
9462[clinic start generated code]*/
9463
Larry Hastings2f936352014-08-05 14:04:04 +10009464static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009465os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9466/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009467{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009468 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009469 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009470
Serhiy Storchaka77703942017-06-25 07:33:01 +03009471 /* Search from index 1 because on Windows starting '=' is allowed for
9472 defining hidden environment variables. */
9473 if (PyUnicode_GET_LENGTH(name) == 0 ||
9474 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9475 {
9476 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9477 return NULL;
9478 }
Larry Hastings2f936352014-08-05 14:04:04 +10009479 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9480 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009481 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009482 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009483
9484 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9485 if (env == NULL)
9486 goto error;
9487 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009488 PyErr_Format(PyExc_ValueError,
9489 "the environment variable is longer than %u characters",
9490 _MAX_ENV);
9491 goto error;
9492 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009493 if (wcslen(env) != (size_t)size) {
9494 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009495 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009496 }
9497
Larry Hastings2f936352014-08-05 14:04:04 +10009498 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009499 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009500 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009501 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009502
Larry Hastings2f936352014-08-05 14:04:04 +10009503 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009504 Py_RETURN_NONE;
9505
9506error:
Larry Hastings2f936352014-08-05 14:04:04 +10009507 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009508 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009509}
Larry Hastings2f936352014-08-05 14:04:04 +10009510#else /* MS_WINDOWS */
9511/*[clinic input]
9512os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009513
Larry Hastings2f936352014-08-05 14:04:04 +10009514 name: FSConverter
9515 value: FSConverter
9516 /
9517
9518Change or add an environment variable.
9519[clinic start generated code]*/
9520
Larry Hastings2f936352014-08-05 14:04:04 +10009521static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009522os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9523/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009524{
9525 PyObject *bytes = NULL;
9526 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009527 const char *name_string = PyBytes_AS_STRING(name);
9528 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009529
Serhiy Storchaka77703942017-06-25 07:33:01 +03009530 if (strchr(name_string, '=') != NULL) {
9531 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9532 return NULL;
9533 }
Larry Hastings2f936352014-08-05 14:04:04 +10009534 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9535 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009536 return NULL;
9537 }
9538
9539 env = PyBytes_AS_STRING(bytes);
9540 if (putenv(env)) {
9541 Py_DECREF(bytes);
9542 return posix_error();
9543 }
9544
9545 posix_putenv_garbage_setitem(name, bytes);
9546 Py_RETURN_NONE;
9547}
9548#endif /* MS_WINDOWS */
9549#endif /* HAVE_PUTENV */
9550
9551
9552#ifdef HAVE_UNSETENV
9553/*[clinic input]
9554os.unsetenv
9555 name: FSConverter
9556 /
9557
9558Delete an environment variable.
9559[clinic start generated code]*/
9560
Larry Hastings2f936352014-08-05 14:04:04 +10009561static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009562os_unsetenv_impl(PyObject *module, PyObject *name)
9563/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009564{
Victor Stinner984890f2011-11-24 13:53:38 +01009565#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009566 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009567#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009568
Victor Stinner984890f2011-11-24 13:53:38 +01009569#ifdef HAVE_BROKEN_UNSETENV
9570 unsetenv(PyBytes_AS_STRING(name));
9571#else
Victor Stinner65170952011-11-22 22:16:17 +01009572 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009573 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009574 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009575#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009576
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 /* Remove the key from posix_putenv_garbage;
9578 * this will cause it to be collected. This has to
9579 * happen after the real unsetenv() call because the
9580 * old value was still accessible until then.
9581 */
Victor Stinner65170952011-11-22 22:16:17 +01009582 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 /* really not much we can do; just leak */
9584 PyErr_Clear();
9585 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009586 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009587}
Larry Hastings2f936352014-08-05 14:04:04 +10009588#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009589
Larry Hastings2f936352014-08-05 14:04:04 +10009590
9591/*[clinic input]
9592os.strerror
9593
9594 code: int
9595 /
9596
9597Translate an error code to a message string.
9598[clinic start generated code]*/
9599
Larry Hastings2f936352014-08-05 14:04:04 +10009600static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009601os_strerror_impl(PyObject *module, int code)
9602/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009603{
9604 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009605 if (message == NULL) {
9606 PyErr_SetString(PyExc_ValueError,
9607 "strerror() argument out of range");
9608 return NULL;
9609 }
Victor Stinner1b579672011-12-17 05:47:23 +01009610 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009611}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009612
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009613
Guido van Rossumc9641791998-08-04 15:26:23 +00009614#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009615#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009616/*[clinic input]
9617os.WCOREDUMP -> bool
9618
9619 status: int
9620 /
9621
9622Return True if the process returning status was dumped to a core file.
9623[clinic start generated code]*/
9624
Larry Hastings2f936352014-08-05 14:04:04 +10009625static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009626os_WCOREDUMP_impl(PyObject *module, int status)
9627/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009628{
9629 WAIT_TYPE wait_status;
9630 WAIT_STATUS_INT(wait_status) = status;
9631 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009632}
9633#endif /* WCOREDUMP */
9634
Larry Hastings2f936352014-08-05 14:04:04 +10009635
Fred Drake106c1a02002-04-23 15:58:02 +00009636#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009637/*[clinic input]
9638os.WIFCONTINUED -> bool
9639
9640 status: int
9641
9642Return True if a particular process was continued from a job control stop.
9643
9644Return True if the process returning status was continued from a
9645job control stop.
9646[clinic start generated code]*/
9647
Larry Hastings2f936352014-08-05 14:04:04 +10009648static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009649os_WIFCONTINUED_impl(PyObject *module, int status)
9650/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009651{
9652 WAIT_TYPE wait_status;
9653 WAIT_STATUS_INT(wait_status) = status;
9654 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009655}
9656#endif /* WIFCONTINUED */
9657
Larry Hastings2f936352014-08-05 14:04:04 +10009658
Guido van Rossumc9641791998-08-04 15:26:23 +00009659#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009660/*[clinic input]
9661os.WIFSTOPPED -> bool
9662
9663 status: int
9664
9665Return True if the process returning status was stopped.
9666[clinic start generated code]*/
9667
Larry Hastings2f936352014-08-05 14:04:04 +10009668static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009669os_WIFSTOPPED_impl(PyObject *module, int status)
9670/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009671{
9672 WAIT_TYPE wait_status;
9673 WAIT_STATUS_INT(wait_status) = status;
9674 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009675}
9676#endif /* WIFSTOPPED */
9677
Larry Hastings2f936352014-08-05 14:04:04 +10009678
Guido van Rossumc9641791998-08-04 15:26:23 +00009679#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009680/*[clinic input]
9681os.WIFSIGNALED -> bool
9682
9683 status: int
9684
9685Return True if the process returning status was terminated by a signal.
9686[clinic start generated code]*/
9687
Larry Hastings2f936352014-08-05 14:04:04 +10009688static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009689os_WIFSIGNALED_impl(PyObject *module, int status)
9690/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009691{
9692 WAIT_TYPE wait_status;
9693 WAIT_STATUS_INT(wait_status) = status;
9694 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009695}
9696#endif /* WIFSIGNALED */
9697
Larry Hastings2f936352014-08-05 14:04:04 +10009698
Guido van Rossumc9641791998-08-04 15:26:23 +00009699#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009700/*[clinic input]
9701os.WIFEXITED -> bool
9702
9703 status: int
9704
9705Return True if the process returning status exited via the exit() system call.
9706[clinic start generated code]*/
9707
Larry Hastings2f936352014-08-05 14:04:04 +10009708static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009709os_WIFEXITED_impl(PyObject *module, int status)
9710/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009711{
9712 WAIT_TYPE wait_status;
9713 WAIT_STATUS_INT(wait_status) = status;
9714 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009715}
9716#endif /* WIFEXITED */
9717
Larry Hastings2f936352014-08-05 14:04:04 +10009718
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009719#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009720/*[clinic input]
9721os.WEXITSTATUS -> int
9722
9723 status: int
9724
9725Return the process return code from status.
9726[clinic start generated code]*/
9727
Larry Hastings2f936352014-08-05 14:04:04 +10009728static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009729os_WEXITSTATUS_impl(PyObject *module, int status)
9730/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009731{
9732 WAIT_TYPE wait_status;
9733 WAIT_STATUS_INT(wait_status) = status;
9734 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009735}
9736#endif /* WEXITSTATUS */
9737
Larry Hastings2f936352014-08-05 14:04:04 +10009738
Guido van Rossumc9641791998-08-04 15:26:23 +00009739#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009740/*[clinic input]
9741os.WTERMSIG -> int
9742
9743 status: int
9744
9745Return the signal that terminated the process that provided the status value.
9746[clinic start generated code]*/
9747
Larry Hastings2f936352014-08-05 14:04:04 +10009748static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009749os_WTERMSIG_impl(PyObject *module, int status)
9750/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009751{
9752 WAIT_TYPE wait_status;
9753 WAIT_STATUS_INT(wait_status) = status;
9754 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009755}
9756#endif /* WTERMSIG */
9757
Larry Hastings2f936352014-08-05 14:04:04 +10009758
Guido van Rossumc9641791998-08-04 15:26:23 +00009759#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009760/*[clinic input]
9761os.WSTOPSIG -> int
9762
9763 status: int
9764
9765Return the signal that stopped the process that provided the status value.
9766[clinic start generated code]*/
9767
Larry Hastings2f936352014-08-05 14:04:04 +10009768static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009769os_WSTOPSIG_impl(PyObject *module, int status)
9770/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009771{
9772 WAIT_TYPE wait_status;
9773 WAIT_STATUS_INT(wait_status) = status;
9774 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009775}
9776#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009777#endif /* HAVE_SYS_WAIT_H */
9778
9779
Thomas Wouters477c8d52006-05-27 19:21:47 +00009780#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009781#ifdef _SCO_DS
9782/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9783 needed definitions in sys/statvfs.h */
9784#define _SVID3
9785#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009786#include <sys/statvfs.h>
9787
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009788static PyObject*
9789_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9791 if (v == NULL)
9792 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009793
9794#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9796 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9797 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9798 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9799 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9800 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9801 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9802 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9803 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9804 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009805#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9807 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9808 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009809 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009811 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009813 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009815 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009817 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009819 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9821 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009822#endif
Michael Felt502d5512018-01-05 13:01:58 +01009823/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9824 * (issue #32390). */
9825#if defined(_AIX) && defined(_ALL_SOURCE)
9826 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9827#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009828 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009829#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009830 if (PyErr_Occurred()) {
9831 Py_DECREF(v);
9832 return NULL;
9833 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009834
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009836}
9837
Larry Hastings2f936352014-08-05 14:04:04 +10009838
9839/*[clinic input]
9840os.fstatvfs
9841 fd: int
9842 /
9843
9844Perform an fstatvfs system call on the given fd.
9845
9846Equivalent to statvfs(fd).
9847[clinic start generated code]*/
9848
Larry Hastings2f936352014-08-05 14:04:04 +10009849static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009850os_fstatvfs_impl(PyObject *module, int fd)
9851/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009852{
9853 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009854 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009856
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009857 do {
9858 Py_BEGIN_ALLOW_THREADS
9859 result = fstatvfs(fd, &st);
9860 Py_END_ALLOW_THREADS
9861 } while (result != 0 && errno == EINTR &&
9862 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009863 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009864 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009865
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009867}
Larry Hastings2f936352014-08-05 14:04:04 +10009868#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009869
9870
Thomas Wouters477c8d52006-05-27 19:21:47 +00009871#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009872#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009873/*[clinic input]
9874os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009875
Larry Hastings2f936352014-08-05 14:04:04 +10009876 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9877
9878Perform a statvfs system call on the given path.
9879
9880path may always be specified as a string.
9881On some platforms, path may also be specified as an open file descriptor.
9882 If this functionality is unavailable, using it raises an exception.
9883[clinic start generated code]*/
9884
Larry Hastings2f936352014-08-05 14:04:04 +10009885static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009886os_statvfs_impl(PyObject *module, path_t *path)
9887/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009888{
9889 int result;
9890 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009891
9892 Py_BEGIN_ALLOW_THREADS
9893#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009894 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009895#ifdef __APPLE__
9896 /* handle weak-linking on Mac OS X 10.3 */
9897 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009898 fd_specified("statvfs", path->fd);
9899 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009900 }
9901#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009902 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009903 }
9904 else
9905#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009906 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009907 Py_END_ALLOW_THREADS
9908
9909 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009910 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009911 }
9912
Larry Hastings2f936352014-08-05 14:04:04 +10009913 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009914}
Larry Hastings2f936352014-08-05 14:04:04 +10009915#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9916
Guido van Rossum94f6f721999-01-06 18:42:14 +00009917
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009918#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009919/*[clinic input]
9920os._getdiskusage
9921
Steve Dower23ad6d02018-02-22 10:39:10 -08009922 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10009923
9924Return disk usage statistics about the given path as a (total, free) tuple.
9925[clinic start generated code]*/
9926
Larry Hastings2f936352014-08-05 14:04:04 +10009927static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08009928os__getdiskusage_impl(PyObject *module, path_t *path)
9929/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009930{
9931 BOOL retval;
9932 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009933
9934 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08009935 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009936 Py_END_ALLOW_THREADS
9937 if (retval == 0)
9938 return PyErr_SetFromWindowsErr(0);
9939
9940 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9941}
Larry Hastings2f936352014-08-05 14:04:04 +10009942#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009943
9944
Fred Drakec9680921999-12-13 16:37:25 +00009945/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9946 * It maps strings representing configuration variable names to
9947 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009948 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009949 * rarely-used constants. There are three separate tables that use
9950 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009951 *
9952 * This code is always included, even if none of the interfaces that
9953 * need it are included. The #if hackery needed to avoid it would be
9954 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009955 */
9956struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009957 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009958 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009959};
9960
Fred Drake12c6e2d1999-12-14 21:25:03 +00009961static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009962conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009963 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009964{
Christian Heimes217cfd12007-12-02 14:31:20 +00009965 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009966 int value = _PyLong_AsInt(arg);
9967 if (value == -1 && PyErr_Occurred())
9968 return 0;
9969 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009970 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009971 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009972 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009973 /* look up the value in the table using a binary search */
9974 size_t lo = 0;
9975 size_t mid;
9976 size_t hi = tablesize;
9977 int cmp;
9978 const char *confname;
9979 if (!PyUnicode_Check(arg)) {
9980 PyErr_SetString(PyExc_TypeError,
9981 "configuration names must be strings or integers");
9982 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009984 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009985 if (confname == NULL)
9986 return 0;
9987 while (lo < hi) {
9988 mid = (lo + hi) / 2;
9989 cmp = strcmp(confname, table[mid].name);
9990 if (cmp < 0)
9991 hi = mid;
9992 else if (cmp > 0)
9993 lo = mid + 1;
9994 else {
9995 *valuep = table[mid].value;
9996 return 1;
9997 }
9998 }
9999 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10000 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010002}
10003
10004
10005#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10006static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010007#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010009#endif
10010#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010012#endif
Fred Drakec9680921999-12-13 16:37:25 +000010013#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010058#ifdef _PC_ACL_ENABLED
10059 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10060#endif
10061#ifdef _PC_MIN_HOLE_SIZE
10062 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10063#endif
10064#ifdef _PC_ALLOC_SIZE_MIN
10065 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10066#endif
10067#ifdef _PC_REC_INCR_XFER_SIZE
10068 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10069#endif
10070#ifdef _PC_REC_MAX_XFER_SIZE
10071 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10072#endif
10073#ifdef _PC_REC_MIN_XFER_SIZE
10074 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10075#endif
10076#ifdef _PC_REC_XFER_ALIGN
10077 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10078#endif
10079#ifdef _PC_SYMLINK_MAX
10080 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10081#endif
10082#ifdef _PC_XATTR_ENABLED
10083 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10084#endif
10085#ifdef _PC_XATTR_EXISTS
10086 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10087#endif
10088#ifdef _PC_TIMESTAMP_RESOLUTION
10089 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10090#endif
Fred Drakec9680921999-12-13 16:37:25 +000010091};
10092
Fred Drakec9680921999-12-13 16:37:25 +000010093static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010094conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010095{
10096 return conv_confname(arg, valuep, posix_constants_pathconf,
10097 sizeof(posix_constants_pathconf)
10098 / sizeof(struct constdef));
10099}
10100#endif
10101
Larry Hastings2f936352014-08-05 14:04:04 +100010102
Fred Drakec9680921999-12-13 16:37:25 +000010103#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010104/*[clinic input]
10105os.fpathconf -> long
10106
10107 fd: int
10108 name: path_confname
10109 /
10110
10111Return the configuration limit name for the file descriptor fd.
10112
10113If there is no limit, return -1.
10114[clinic start generated code]*/
10115
Larry Hastings2f936352014-08-05 14:04:04 +100010116static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010117os_fpathconf_impl(PyObject *module, int fd, int name)
10118/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010119{
10120 long limit;
10121
10122 errno = 0;
10123 limit = fpathconf(fd, name);
10124 if (limit == -1 && errno != 0)
10125 posix_error();
10126
10127 return limit;
10128}
10129#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010130
10131
10132#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010133/*[clinic input]
10134os.pathconf -> long
10135 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10136 name: path_confname
10137
10138Return the configuration limit name for the file or directory path.
10139
10140If there is no limit, return -1.
10141On some platforms, path may also be specified as an open file descriptor.
10142 If this functionality is unavailable, using it raises an exception.
10143[clinic start generated code]*/
10144
Larry Hastings2f936352014-08-05 14:04:04 +100010145static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010146os_pathconf_impl(PyObject *module, path_t *path, int name)
10147/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010148{
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010150
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010152#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010153 if (path->fd != -1)
10154 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010155 else
10156#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010157 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 if (limit == -1 && errno != 0) {
10159 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010160 /* could be a path or name problem */
10161 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010162 else
Larry Hastings2f936352014-08-05 14:04:04 +100010163 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 }
Larry Hastings2f936352014-08-05 14:04:04 +100010165
10166 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010167}
Larry Hastings2f936352014-08-05 14:04:04 +100010168#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010169
10170#ifdef HAVE_CONFSTR
10171static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010172#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010174#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010175#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010177#endif
10178#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010180#endif
Fred Draked86ed291999-12-15 15:34:33 +000010181#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010183#endif
10184#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010186#endif
10187#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010189#endif
10190#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010192#endif
Fred Drakec9680921999-12-13 16:37:25 +000010193#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
Fred Draked86ed291999-12-15 15:34:33 +000010217#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010219#endif
Fred Drakec9680921999-12-13 16:37:25 +000010220#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
Fred Draked86ed291999-12-15 15:34:33 +000010223#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010225#endif
10226#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010228#endif
10229#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010231#endif
10232#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010234#endif
Fred Drakec9680921999-12-13 16:37:25 +000010235#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
10259#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
10262#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
10265#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
10268#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
10271#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010273#endif
10274#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
10277#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010279#endif
10280#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010282#endif
Fred Draked86ed291999-12-15 15:34:33 +000010283#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010285#endif
10286#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010288#endif
10289#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010291#endif
10292#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010294#endif
10295#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010297#endif
10298#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010300#endif
10301#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010303#endif
10304#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010306#endif
10307#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010309#endif
10310#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010312#endif
10313#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010315#endif
10316#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010318#endif
10319#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010321#endif
Fred Drakec9680921999-12-13 16:37:25 +000010322};
10323
10324static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010325conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010326{
10327 return conv_confname(arg, valuep, posix_constants_confstr,
10328 sizeof(posix_constants_confstr)
10329 / sizeof(struct constdef));
10330}
10331
Larry Hastings2f936352014-08-05 14:04:04 +100010332
10333/*[clinic input]
10334os.confstr
10335
10336 name: confstr_confname
10337 /
10338
10339Return a string-valued system configuration variable.
10340[clinic start generated code]*/
10341
Larry Hastings2f936352014-08-05 14:04:04 +100010342static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010343os_confstr_impl(PyObject *module, int name)
10344/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010345{
10346 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010347 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010348 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010349
Victor Stinnercb043522010-09-10 23:49:04 +000010350 errno = 0;
10351 len = confstr(name, buffer, sizeof(buffer));
10352 if (len == 0) {
10353 if (errno) {
10354 posix_error();
10355 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010356 }
10357 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010358 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010359 }
10360 }
Victor Stinnercb043522010-09-10 23:49:04 +000010361
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010362 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010363 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010364 char *buf = PyMem_Malloc(len);
10365 if (buf == NULL)
10366 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010367 len2 = confstr(name, buf, len);
10368 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010369 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010370 PyMem_Free(buf);
10371 }
10372 else
10373 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010374 return result;
10375}
Larry Hastings2f936352014-08-05 14:04:04 +100010376#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010377
10378
10379#ifdef HAVE_SYSCONF
10380static struct constdef posix_constants_sysconf[] = {
10381#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010383#endif
10384#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010386#endif
10387#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010389#endif
10390#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010392#endif
10393#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010394 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010395#endif
10396#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010397 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010398#endif
10399#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010400 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010401#endif
10402#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010403 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010404#endif
10405#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010406 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010407#endif
10408#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010409 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010410#endif
Fred Draked86ed291999-12-15 15:34:33 +000010411#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010412 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010413#endif
10414#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010415 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010416#endif
Fred Drakec9680921999-12-13 16:37:25 +000010417#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010419#endif
Fred Drakec9680921999-12-13 16:37:25 +000010420#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010421 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010422#endif
10423#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010424 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010425#endif
10426#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010427 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010428#endif
10429#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010430 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010431#endif
10432#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010433 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010434#endif
Fred Draked86ed291999-12-15 15:34:33 +000010435#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010436 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010437#endif
Fred Drakec9680921999-12-13 16:37:25 +000010438#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010440#endif
10441#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010443#endif
10444#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010445 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010446#endif
10447#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010448 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010449#endif
10450#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010452#endif
Fred Draked86ed291999-12-15 15:34:33 +000010453#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010455#endif
Fred Drakec9680921999-12-13 16:37:25 +000010456#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010458#endif
10459#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010461#endif
10462#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010463 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010464#endif
10465#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010467#endif
10468#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010470#endif
10471#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010473#endif
10474#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010475 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010476#endif
10477#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010479#endif
10480#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010482#endif
10483#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010485#endif
10486#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010488#endif
10489#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010491#endif
10492#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010493 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010494#endif
10495#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010496 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010497#endif
10498#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010500#endif
10501#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010502 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010503#endif
10504#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010506#endif
10507#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010509#endif
10510#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010511 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010512#endif
10513#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010514 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010515#endif
10516#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010517 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010518#endif
10519#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010521#endif
10522#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010524#endif
Fred Draked86ed291999-12-15 15:34:33 +000010525#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010527#endif
Fred Drakec9680921999-12-13 16:37:25 +000010528#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010529 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010530#endif
10531#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010532 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010533#endif
10534#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010535 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010536#endif
Fred Draked86ed291999-12-15 15:34:33 +000010537#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010538 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010539#endif
Fred Drakec9680921999-12-13 16:37:25 +000010540#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010542#endif
Fred Draked86ed291999-12-15 15:34:33 +000010543#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010545#endif
10546#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010547 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010548#endif
Fred Drakec9680921999-12-13 16:37:25 +000010549#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010550 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010551#endif
10552#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010554#endif
10555#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010556 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010557#endif
10558#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010560#endif
Fred Draked86ed291999-12-15 15:34:33 +000010561#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010562 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010563#endif
Fred Drakec9680921999-12-13 16:37:25 +000010564#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010566#endif
10567#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010569#endif
10570#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010572#endif
10573#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010574 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010575#endif
10576#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010578#endif
10579#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010580 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010581#endif
10582#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010583 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010584#endif
Fred Draked86ed291999-12-15 15:34:33 +000010585#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010586 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010587#endif
Fred Drakec9680921999-12-13 16:37:25 +000010588#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010589 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010590#endif
10591#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010592 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010593#endif
Fred Draked86ed291999-12-15 15:34:33 +000010594#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010596#endif
Fred Drakec9680921999-12-13 16:37:25 +000010597#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010598 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010599#endif
10600#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010602#endif
10603#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010605#endif
10606#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010608#endif
10609#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010610 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010611#endif
10612#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010613 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010614#endif
10615#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010616 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010617#endif
10618#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010619 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010620#endif
10621#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010622 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010623#endif
Fred Draked86ed291999-12-15 15:34:33 +000010624#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010625 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010626#endif
10627#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010628 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010629#endif
Fred Drakec9680921999-12-13 16:37:25 +000010630#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010631 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010632#endif
10633#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010634 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010635#endif
10636#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010637 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010638#endif
10639#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010640 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010641#endif
10642#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010643 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010644#endif
10645#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010646 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010647#endif
10648#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010649 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010650#endif
10651#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010652 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010653#endif
10654#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010655 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010656#endif
10657#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010658 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010659#endif
10660#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010661 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010662#endif
10663#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010664 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010665#endif
10666#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010667 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010668#endif
10669#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010670 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010671#endif
10672#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010673 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010674#endif
10675#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010676 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010677#endif
10678#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010680#endif
10681#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010682 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010683#endif
10684#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010686#endif
10687#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010688 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010689#endif
10690#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010691 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010692#endif
10693#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010694 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010695#endif
10696#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010697 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010698#endif
10699#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010700 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010701#endif
10702#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010703 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010704#endif
10705#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010706 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010707#endif
10708#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010709 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010710#endif
10711#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010712 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010713#endif
10714#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010715 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010716#endif
10717#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010718 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010719#endif
10720#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010721 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010722#endif
10723#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010724 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010725#endif
10726#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010727 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010728#endif
10729#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010730 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010731#endif
10732#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010733 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010734#endif
Fred Draked86ed291999-12-15 15:34:33 +000010735#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010736 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010737#endif
Fred Drakec9680921999-12-13 16:37:25 +000010738#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010739 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010740#endif
10741#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010742 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010743#endif
10744#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010745 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010746#endif
10747#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010748 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010749#endif
10750#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010751 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010752#endif
10753#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010754 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010755#endif
10756#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010757 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010758#endif
10759#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010760 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010761#endif
10762#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010763 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010764#endif
10765#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010766 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010767#endif
10768#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010769 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010770#endif
10771#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010772 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010773#endif
10774#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010775 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010776#endif
10777#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010778 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010779#endif
10780#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010781 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010782#endif
10783#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010785#endif
10786#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010788#endif
10789#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010791#endif
10792#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010794#endif
10795#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010797#endif
10798#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010800#endif
10801#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010802 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010803#endif
10804#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010806#endif
10807#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010809#endif
10810#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010812#endif
10813#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010815#endif
10816#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010818#endif
10819#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010821#endif
10822#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010824#endif
10825#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010826 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010827#endif
10828#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010829 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010830#endif
10831#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010832 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010833#endif
10834#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010835 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010836#endif
10837#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010838 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010839#endif
10840#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010841 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010842#endif
10843#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010844 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010845#endif
10846#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010847 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010848#endif
10849#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010851#endif
10852#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010853 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010854#endif
10855#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010856 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010857#endif
10858#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010859 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010860#endif
10861#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010862 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010863#endif
10864#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010865 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010866#endif
10867#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010868 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010869#endif
10870#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010871 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010872#endif
10873};
10874
10875static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010876conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010877{
10878 return conv_confname(arg, valuep, posix_constants_sysconf,
10879 sizeof(posix_constants_sysconf)
10880 / sizeof(struct constdef));
10881}
10882
Larry Hastings2f936352014-08-05 14:04:04 +100010883
10884/*[clinic input]
10885os.sysconf -> long
10886 name: sysconf_confname
10887 /
10888
10889Return an integer-valued system configuration variable.
10890[clinic start generated code]*/
10891
Larry Hastings2f936352014-08-05 14:04:04 +100010892static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010893os_sysconf_impl(PyObject *module, int name)
10894/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010895{
10896 long value;
10897
10898 errno = 0;
10899 value = sysconf(name);
10900 if (value == -1 && errno != 0)
10901 posix_error();
10902 return value;
10903}
10904#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010905
10906
Fred Drakebec628d1999-12-15 18:31:10 +000010907/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010908 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010909 * the exported dictionaries that are used to publish information about the
10910 * names available on the host platform.
10911 *
10912 * Sorting the table at runtime ensures that the table is properly ordered
10913 * when used, even for platforms we're not able to test on. It also makes
10914 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010915 */
Fred Drakebec628d1999-12-15 18:31:10 +000010916
10917static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010918cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010919{
10920 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010922 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010923 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010924
10925 return strcmp(c1->name, c2->name);
10926}
10927
10928static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010929setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010930 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010931{
Fred Drakebec628d1999-12-15 18:31:10 +000010932 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010933 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010934
10935 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10936 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010937 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010939
Barry Warsaw3155db32000-04-13 15:20:40 +000010940 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 PyObject *o = PyLong_FromLong(table[i].value);
10942 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10943 Py_XDECREF(o);
10944 Py_DECREF(d);
10945 return -1;
10946 }
10947 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010948 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010949 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010950}
10951
Fred Drakebec628d1999-12-15 18:31:10 +000010952/* Return -1 on failure, 0 on success. */
10953static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010954setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010955{
10956#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010957 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010958 sizeof(posix_constants_pathconf)
10959 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010960 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010961 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010962#endif
10963#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010964 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010965 sizeof(posix_constants_confstr)
10966 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010967 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010968 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010969#endif
10970#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010971 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010972 sizeof(posix_constants_sysconf)
10973 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010974 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010975 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010976#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010977 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010978}
Fred Draked86ed291999-12-15 15:34:33 +000010979
10980
Larry Hastings2f936352014-08-05 14:04:04 +100010981/*[clinic input]
10982os.abort
10983
10984Abort the interpreter immediately.
10985
10986This function 'dumps core' or otherwise fails in the hardest way possible
10987on the hosting operating system. This function never returns.
10988[clinic start generated code]*/
10989
Larry Hastings2f936352014-08-05 14:04:04 +100010990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010991os_abort_impl(PyObject *module)
10992/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010993{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010994 abort();
10995 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010996#ifndef __clang__
10997 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10998 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10999 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011000 Py_FatalError("abort() called from Python code didn't abort!");
11001 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011002#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011003}
Fred Drakebec628d1999-12-15 18:31:10 +000011004
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011005#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011006/* Grab ShellExecute dynamically from shell32 */
11007static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011008static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11009 LPCWSTR, INT);
11010static int
11011check_ShellExecute()
11012{
11013 HINSTANCE hShell32;
11014
11015 /* only recheck */
11016 if (-1 == has_ShellExecute) {
11017 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011018 /* Security note: this call is not vulnerable to "DLL hijacking".
11019 SHELL32 is part of "KnownDLLs" and so Windows always load
11020 the system SHELL32.DLL, even if there is another SHELL32.DLL
11021 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011022 hShell32 = LoadLibraryW(L"SHELL32");
11023 Py_END_ALLOW_THREADS
11024 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011025 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11026 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011027 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011028 } else {
11029 has_ShellExecute = 0;
11030 }
11031 }
11032 return has_ShellExecute;
11033}
11034
11035
Steve Dowercc16be82016-09-08 10:35:16 -070011036/*[clinic input]
11037os.startfile
11038 filepath: path_t
11039 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011040
Steve Dowercc16be82016-09-08 10:35:16 -070011041startfile(filepath [, operation])
11042
11043Start a file with its associated application.
11044
11045When "operation" is not specified or "open", this acts like
11046double-clicking the file in Explorer, or giving the file name as an
11047argument to the DOS "start" command: the file is opened with whatever
11048application (if any) its extension is associated.
11049When another "operation" is given, it specifies what should be done with
11050the file. A typical operation is "print".
11051
11052startfile returns as soon as the associated application is launched.
11053There is no option to wait for the application to close, and no way
11054to retrieve the application's exit status.
11055
11056The filepath is relative to the current directory. If you want to use
11057an absolute path, make sure the first character is not a slash ("/");
11058the underlying Win32 ShellExecute function doesn't work if it is.
11059[clinic start generated code]*/
11060
11061static PyObject *
11062os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
11063/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
11064{
11065 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011066
11067 if(!check_ShellExecute()) {
11068 /* If the OS doesn't have ShellExecute, return a
11069 NotImplementedError. */
11070 return PyErr_Format(PyExc_NotImplementedError,
11071 "startfile not available on this platform");
11072 }
11073
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011075 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011076 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 Py_END_ALLOW_THREADS
11078
Victor Stinner8c62be82010-05-06 00:08:46 +000011079 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011080 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011081 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011082 }
Steve Dowercc16be82016-09-08 10:35:16 -070011083 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011084}
Larry Hastings2f936352014-08-05 14:04:04 +100011085#endif /* MS_WINDOWS */
11086
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011087
Martin v. Löwis438b5342002-12-27 10:16:42 +000011088#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011089/*[clinic input]
11090os.getloadavg
11091
11092Return average recent system load information.
11093
11094Return the number of processes in the system run queue averaged over
11095the last 1, 5, and 15 minutes as a tuple of three floats.
11096Raises OSError if the load average was unobtainable.
11097[clinic start generated code]*/
11098
Larry Hastings2f936352014-08-05 14:04:04 +100011099static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011100os_getloadavg_impl(PyObject *module)
11101/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011102{
11103 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011104 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011105 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11106 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011107 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011108 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011109}
Larry Hastings2f936352014-08-05 14:04:04 +100011110#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011111
Larry Hastings2f936352014-08-05 14:04:04 +100011112
11113/*[clinic input]
11114os.device_encoding
11115 fd: int
11116
11117Return a string describing the encoding of a terminal's file descriptor.
11118
11119The file descriptor must be attached to a terminal.
11120If the device is not a terminal, return None.
11121[clinic start generated code]*/
11122
Larry Hastings2f936352014-08-05 14:04:04 +100011123static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011124os_device_encoding_impl(PyObject *module, int fd)
11125/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011126{
Brett Cannonefb00c02012-02-29 18:31:31 -050011127 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011128}
11129
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011130
Larry Hastings2f936352014-08-05 14:04:04 +100011131#ifdef HAVE_SETRESUID
11132/*[clinic input]
11133os.setresuid
11134
11135 ruid: uid_t
11136 euid: uid_t
11137 suid: uid_t
11138 /
11139
11140Set the current process's real, effective, and saved user ids.
11141[clinic start generated code]*/
11142
Larry Hastings2f936352014-08-05 14:04:04 +100011143static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011144os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11145/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011146{
Victor Stinner8c62be82010-05-06 00:08:46 +000011147 if (setresuid(ruid, euid, suid) < 0)
11148 return posix_error();
11149 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011150}
Larry Hastings2f936352014-08-05 14:04:04 +100011151#endif /* HAVE_SETRESUID */
11152
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011153
11154#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011155/*[clinic input]
11156os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011157
Larry Hastings2f936352014-08-05 14:04:04 +100011158 rgid: gid_t
11159 egid: gid_t
11160 sgid: gid_t
11161 /
11162
11163Set the current process's real, effective, and saved group ids.
11164[clinic start generated code]*/
11165
Larry Hastings2f936352014-08-05 14:04:04 +100011166static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011167os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11168/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011169{
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 if (setresgid(rgid, egid, sgid) < 0)
11171 return posix_error();
11172 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011173}
Larry Hastings2f936352014-08-05 14:04:04 +100011174#endif /* HAVE_SETRESGID */
11175
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011176
11177#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011178/*[clinic input]
11179os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011180
Larry Hastings2f936352014-08-05 14:04:04 +100011181Return a tuple of the current process's real, effective, and saved user ids.
11182[clinic start generated code]*/
11183
Larry Hastings2f936352014-08-05 14:04:04 +100011184static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011185os_getresuid_impl(PyObject *module)
11186/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011187{
Victor Stinner8c62be82010-05-06 00:08:46 +000011188 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011189 if (getresuid(&ruid, &euid, &suid) < 0)
11190 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011191 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11192 _PyLong_FromUid(euid),
11193 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011194}
Larry Hastings2f936352014-08-05 14:04:04 +100011195#endif /* HAVE_GETRESUID */
11196
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011197
11198#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011199/*[clinic input]
11200os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011201
Larry Hastings2f936352014-08-05 14:04:04 +100011202Return a tuple of the current process's real, effective, and saved group ids.
11203[clinic start generated code]*/
11204
Larry Hastings2f936352014-08-05 14:04:04 +100011205static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011206os_getresgid_impl(PyObject *module)
11207/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011208{
11209 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011210 if (getresgid(&rgid, &egid, &sgid) < 0)
11211 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011212 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11213 _PyLong_FromGid(egid),
11214 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011215}
Larry Hastings2f936352014-08-05 14:04:04 +100011216#endif /* HAVE_GETRESGID */
11217
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011218
Benjamin Peterson9428d532011-09-14 11:45:52 -040011219#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011220/*[clinic input]
11221os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011222
Larry Hastings2f936352014-08-05 14:04:04 +100011223 path: path_t(allow_fd=True)
11224 attribute: path_t
11225 *
11226 follow_symlinks: bool = True
11227
11228Return the value of extended attribute attribute on path.
11229
11230path may be either a string or an open file descriptor.
11231If follow_symlinks is False, and the last element of the path is a symbolic
11232 link, getxattr will examine the symbolic link itself instead of the file
11233 the link points to.
11234
11235[clinic start generated code]*/
11236
Larry Hastings2f936352014-08-05 14:04:04 +100011237static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011238os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011239 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011240/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011241{
11242 Py_ssize_t i;
11243 PyObject *buffer = NULL;
11244
11245 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11246 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011247
Larry Hastings9cf065c2012-06-22 16:30:09 -070011248 for (i = 0; ; i++) {
11249 void *ptr;
11250 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011251 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011252 Py_ssize_t buffer_size = buffer_sizes[i];
11253 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011254 path_error(path);
11255 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011256 }
11257 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11258 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011259 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011260 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011261
Larry Hastings9cf065c2012-06-22 16:30:09 -070011262 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011263 if (path->fd >= 0)
11264 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011265 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011266 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011267 else
Larry Hastings2f936352014-08-05 14:04:04 +100011268 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011269 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011270
Larry Hastings9cf065c2012-06-22 16:30:09 -070011271 if (result < 0) {
11272 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011273 if (errno == ERANGE)
11274 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011275 path_error(path);
11276 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011277 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011278
Larry Hastings9cf065c2012-06-22 16:30:09 -070011279 if (result != buffer_size) {
11280 /* Can only shrink. */
11281 _PyBytes_Resize(&buffer, result);
11282 }
11283 break;
11284 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011285
Larry Hastings9cf065c2012-06-22 16:30:09 -070011286 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011287}
11288
Larry Hastings2f936352014-08-05 14:04:04 +100011289
11290/*[clinic input]
11291os.setxattr
11292
11293 path: path_t(allow_fd=True)
11294 attribute: path_t
11295 value: Py_buffer
11296 flags: int = 0
11297 *
11298 follow_symlinks: bool = True
11299
11300Set extended attribute attribute on path to value.
11301
11302path may be either a string or an open file descriptor.
11303If follow_symlinks is False, and the last element of the path is a symbolic
11304 link, setxattr will modify the symbolic link itself instead of the file
11305 the link points to.
11306
11307[clinic start generated code]*/
11308
Benjamin Peterson799bd802011-08-31 22:15:17 -040011309static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011310os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011311 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011312/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011313{
Larry Hastings2f936352014-08-05 14:04:04 +100011314 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011315
Larry Hastings2f936352014-08-05 14:04:04 +100011316 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011317 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011318
Benjamin Peterson799bd802011-08-31 22:15:17 -040011319 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011320 if (path->fd > -1)
11321 result = fsetxattr(path->fd, attribute->narrow,
11322 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011323 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011324 result = setxattr(path->narrow, attribute->narrow,
11325 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011326 else
Larry Hastings2f936352014-08-05 14:04:04 +100011327 result = lsetxattr(path->narrow, attribute->narrow,
11328 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011329 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011330
Larry Hastings9cf065c2012-06-22 16:30:09 -070011331 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011332 path_error(path);
11333 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011334 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011335
Larry Hastings2f936352014-08-05 14:04:04 +100011336 Py_RETURN_NONE;
11337}
11338
11339
11340/*[clinic input]
11341os.removexattr
11342
11343 path: path_t(allow_fd=True)
11344 attribute: path_t
11345 *
11346 follow_symlinks: bool = True
11347
11348Remove extended attribute attribute on path.
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, removexattr will modify the symbolic link itself instead of the file
11353 the link points to.
11354
11355[clinic start generated code]*/
11356
Larry Hastings2f936352014-08-05 14:04:04 +100011357static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011358os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011359 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011360/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011361{
11362 ssize_t result;
11363
11364 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11365 return NULL;
11366
11367 Py_BEGIN_ALLOW_THREADS;
11368 if (path->fd > -1)
11369 result = fremovexattr(path->fd, attribute->narrow);
11370 else if (follow_symlinks)
11371 result = removexattr(path->narrow, attribute->narrow);
11372 else
11373 result = lremovexattr(path->narrow, attribute->narrow);
11374 Py_END_ALLOW_THREADS;
11375
11376 if (result) {
11377 return path_error(path);
11378 }
11379
11380 Py_RETURN_NONE;
11381}
11382
11383
11384/*[clinic input]
11385os.listxattr
11386
11387 path: path_t(allow_fd=True, nullable=True) = None
11388 *
11389 follow_symlinks: bool = True
11390
11391Return a list of extended attributes on path.
11392
11393path may be either None, a string, or an open file descriptor.
11394if path is None, listxattr will examine the current directory.
11395If follow_symlinks is False, and the last element of the path is a symbolic
11396 link, listxattr will examine the symbolic link itself instead of the file
11397 the link points to.
11398[clinic start generated code]*/
11399
Larry Hastings2f936352014-08-05 14:04:04 +100011400static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011401os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
11402/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011403{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011404 Py_ssize_t i;
11405 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011406 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011407 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011408
Larry Hastings2f936352014-08-05 14:04:04 +100011409 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011410 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011411
Larry Hastings2f936352014-08-05 14:04:04 +100011412 name = path->narrow ? path->narrow : ".";
11413
Larry Hastings9cf065c2012-06-22 16:30:09 -070011414 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011415 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011416 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011417 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011418 Py_ssize_t buffer_size = buffer_sizes[i];
11419 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011420 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011421 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011422 break;
11423 }
11424 buffer = PyMem_MALLOC(buffer_size);
11425 if (!buffer) {
11426 PyErr_NoMemory();
11427 break;
11428 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011429
Larry Hastings9cf065c2012-06-22 16:30:09 -070011430 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011431 if (path->fd > -1)
11432 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011433 else if (follow_symlinks)
11434 length = listxattr(name, buffer, buffer_size);
11435 else
11436 length = llistxattr(name, buffer, buffer_size);
11437 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011438
Larry Hastings9cf065c2012-06-22 16:30:09 -070011439 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011440 if (errno == ERANGE) {
11441 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011442 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011443 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011444 }
Larry Hastings2f936352014-08-05 14:04:04 +100011445 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011446 break;
11447 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011448
Larry Hastings9cf065c2012-06-22 16:30:09 -070011449 result = PyList_New(0);
11450 if (!result) {
11451 goto exit;
11452 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011453
Larry Hastings9cf065c2012-06-22 16:30:09 -070011454 end = buffer + length;
11455 for (trace = start = buffer; trace != end; trace++) {
11456 if (!*trace) {
11457 int error;
11458 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11459 trace - start);
11460 if (!attribute) {
11461 Py_DECREF(result);
11462 result = NULL;
11463 goto exit;
11464 }
11465 error = PyList_Append(result, attribute);
11466 Py_DECREF(attribute);
11467 if (error) {
11468 Py_DECREF(result);
11469 result = NULL;
11470 goto exit;
11471 }
11472 start = trace + 1;
11473 }
11474 }
11475 break;
11476 }
11477exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011478 if (buffer)
11479 PyMem_FREE(buffer);
11480 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011481}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011482#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011483
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011484
Larry Hastings2f936352014-08-05 14:04:04 +100011485/*[clinic input]
11486os.urandom
11487
11488 size: Py_ssize_t
11489 /
11490
11491Return a bytes object containing random bytes suitable for cryptographic use.
11492[clinic start generated code]*/
11493
Larry Hastings2f936352014-08-05 14:04:04 +100011494static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011495os_urandom_impl(PyObject *module, Py_ssize_t size)
11496/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011497{
11498 PyObject *bytes;
11499 int result;
11500
Georg Brandl2fb477c2012-02-21 00:33:36 +010011501 if (size < 0)
11502 return PyErr_Format(PyExc_ValueError,
11503 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011504 bytes = PyBytes_FromStringAndSize(NULL, size);
11505 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011506 return NULL;
11507
Victor Stinnere66987e2016-09-06 16:33:52 -070011508 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011509 if (result == -1) {
11510 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011511 return NULL;
11512 }
Larry Hastings2f936352014-08-05 14:04:04 +100011513 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011514}
11515
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011516/* Terminal size querying */
11517
11518static PyTypeObject TerminalSizeType;
11519
11520PyDoc_STRVAR(TerminalSize_docstring,
11521 "A tuple of (columns, lines) for holding terminal window size");
11522
11523static PyStructSequence_Field TerminalSize_fields[] = {
11524 {"columns", "width of the terminal window in characters"},
11525 {"lines", "height of the terminal window in characters"},
11526 {NULL, NULL}
11527};
11528
11529static PyStructSequence_Desc TerminalSize_desc = {
11530 "os.terminal_size",
11531 TerminalSize_docstring,
11532 TerminalSize_fields,
11533 2,
11534};
11535
11536#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011537/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011538PyDoc_STRVAR(termsize__doc__,
11539 "Return the size of the terminal window as (columns, lines).\n" \
11540 "\n" \
11541 "The optional argument fd (default standard output) specifies\n" \
11542 "which file descriptor should be queried.\n" \
11543 "\n" \
11544 "If the file descriptor is not connected to a terminal, an OSError\n" \
11545 "is thrown.\n" \
11546 "\n" \
11547 "This function will only be defined if an implementation is\n" \
11548 "available for this system.\n" \
11549 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080011550 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011551 "normally be used, os.get_terminal_size is the low-level implementation.");
11552
11553static PyObject*
11554get_terminal_size(PyObject *self, PyObject *args)
11555{
11556 int columns, lines;
11557 PyObject *termsize;
11558
11559 int fd = fileno(stdout);
11560 /* Under some conditions stdout may not be connected and
11561 * fileno(stdout) may point to an invalid file descriptor. For example
11562 * GUI apps don't have valid standard streams by default.
11563 *
11564 * If this happens, and the optional fd argument is not present,
11565 * the ioctl below will fail returning EBADF. This is what we want.
11566 */
11567
11568 if (!PyArg_ParseTuple(args, "|i", &fd))
11569 return NULL;
11570
11571#ifdef TERMSIZE_USE_IOCTL
11572 {
11573 struct winsize w;
11574 if (ioctl(fd, TIOCGWINSZ, &w))
11575 return PyErr_SetFromErrno(PyExc_OSError);
11576 columns = w.ws_col;
11577 lines = w.ws_row;
11578 }
11579#endif /* TERMSIZE_USE_IOCTL */
11580
11581#ifdef TERMSIZE_USE_CONIO
11582 {
11583 DWORD nhandle;
11584 HANDLE handle;
11585 CONSOLE_SCREEN_BUFFER_INFO csbi;
11586 switch (fd) {
11587 case 0: nhandle = STD_INPUT_HANDLE;
11588 break;
11589 case 1: nhandle = STD_OUTPUT_HANDLE;
11590 break;
11591 case 2: nhandle = STD_ERROR_HANDLE;
11592 break;
11593 default:
11594 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11595 }
11596 handle = GetStdHandle(nhandle);
11597 if (handle == NULL)
11598 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11599 if (handle == INVALID_HANDLE_VALUE)
11600 return PyErr_SetFromWindowsErr(0);
11601
11602 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11603 return PyErr_SetFromWindowsErr(0);
11604
11605 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11606 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11607 }
11608#endif /* TERMSIZE_USE_CONIO */
11609
11610 termsize = PyStructSequence_New(&TerminalSizeType);
11611 if (termsize == NULL)
11612 return NULL;
11613 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11614 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11615 if (PyErr_Occurred()) {
11616 Py_DECREF(termsize);
11617 return NULL;
11618 }
11619 return termsize;
11620}
11621#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11622
Larry Hastings2f936352014-08-05 14:04:04 +100011623
11624/*[clinic input]
11625os.cpu_count
11626
Charles-François Natali80d62e62015-08-13 20:37:08 +010011627Return the number of CPUs in the system; return None if indeterminable.
11628
11629This number is not equivalent to the number of CPUs the current process can
11630use. The number of usable CPUs can be obtained with
11631``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011632[clinic start generated code]*/
11633
Larry Hastings2f936352014-08-05 14:04:04 +100011634static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011635os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011636/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011637{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011638 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011639#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011640 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11641 Need to fallback to Vista behavior if this call isn't present */
11642 HINSTANCE hKernel32;
11643 hKernel32 = GetModuleHandleW(L"KERNEL32");
11644
11645 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11646 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11647 "GetMaximumProcessorCount");
11648 if (_GetMaximumProcessorCount != NULL) {
11649 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11650 }
11651 else {
11652 SYSTEM_INFO sysinfo;
11653 GetSystemInfo(&sysinfo);
11654 ncpu = sysinfo.dwNumberOfProcessors;
11655 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011656#elif defined(__hpux)
11657 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11658#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11659 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011660#elif defined(__DragonFly__) || \
11661 defined(__OpenBSD__) || \
11662 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011663 defined(__NetBSD__) || \
11664 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011665 int mib[2];
11666 size_t len = sizeof(ncpu);
11667 mib[0] = CTL_HW;
11668 mib[1] = HW_NCPU;
11669 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11670 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011671#endif
11672 if (ncpu >= 1)
11673 return PyLong_FromLong(ncpu);
11674 else
11675 Py_RETURN_NONE;
11676}
11677
Victor Stinnerdaf45552013-08-28 00:53:59 +020011678
Larry Hastings2f936352014-08-05 14:04:04 +100011679/*[clinic input]
11680os.get_inheritable -> bool
11681
11682 fd: int
11683 /
11684
11685Get the close-on-exe flag of the specified file descriptor.
11686[clinic start generated code]*/
11687
Larry Hastings2f936352014-08-05 14:04:04 +100011688static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011689os_get_inheritable_impl(PyObject *module, int fd)
11690/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011691{
Steve Dower8fc89802015-04-12 00:26:27 -040011692 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011693 _Py_BEGIN_SUPPRESS_IPH
11694 return_value = _Py_get_inheritable(fd);
11695 _Py_END_SUPPRESS_IPH
11696 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011697}
11698
11699
11700/*[clinic input]
11701os.set_inheritable
11702 fd: int
11703 inheritable: int
11704 /
11705
11706Set the inheritable flag of the specified file descriptor.
11707[clinic start generated code]*/
11708
Larry Hastings2f936352014-08-05 14:04:04 +100011709static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011710os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11711/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011712{
Steve Dower8fc89802015-04-12 00:26:27 -040011713 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011714
Steve Dower8fc89802015-04-12 00:26:27 -040011715 _Py_BEGIN_SUPPRESS_IPH
11716 result = _Py_set_inheritable(fd, inheritable, NULL);
11717 _Py_END_SUPPRESS_IPH
11718 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011719 return NULL;
11720 Py_RETURN_NONE;
11721}
11722
11723
11724#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011725/*[clinic input]
11726os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011727 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011728 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011729
Larry Hastings2f936352014-08-05 14:04:04 +100011730Get the close-on-exe flag of the specified file descriptor.
11731[clinic start generated code]*/
11732
Larry Hastings2f936352014-08-05 14:04:04 +100011733static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011734os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011735/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011736{
11737 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011738
11739 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11740 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011741 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011742 }
11743
Larry Hastings2f936352014-08-05 14:04:04 +100011744 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011745}
11746
Victor Stinnerdaf45552013-08-28 00:53:59 +020011747
Larry Hastings2f936352014-08-05 14:04:04 +100011748/*[clinic input]
11749os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011750 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011751 inheritable: bool
11752 /
11753
11754Set the inheritable flag of the specified handle.
11755[clinic start generated code]*/
11756
Larry Hastings2f936352014-08-05 14:04:04 +100011757static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011758os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011759 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011760/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011761{
11762 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011763 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11764 PyErr_SetFromWindowsErr(0);
11765 return NULL;
11766 }
11767 Py_RETURN_NONE;
11768}
Larry Hastings2f936352014-08-05 14:04:04 +100011769#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011770
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011771#ifndef MS_WINDOWS
11772PyDoc_STRVAR(get_blocking__doc__,
11773 "get_blocking(fd) -> bool\n" \
11774 "\n" \
11775 "Get the blocking mode of the file descriptor:\n" \
11776 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11777
11778static PyObject*
11779posix_get_blocking(PyObject *self, PyObject *args)
11780{
11781 int fd;
11782 int blocking;
11783
11784 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11785 return NULL;
11786
Steve Dower8fc89802015-04-12 00:26:27 -040011787 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011788 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011789 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011790 if (blocking < 0)
11791 return NULL;
11792 return PyBool_FromLong(blocking);
11793}
11794
11795PyDoc_STRVAR(set_blocking__doc__,
11796 "set_blocking(fd, blocking)\n" \
11797 "\n" \
11798 "Set the blocking mode of the specified file descriptor.\n" \
11799 "Set the O_NONBLOCK flag if blocking is False,\n" \
11800 "clear the O_NONBLOCK flag otherwise.");
11801
11802static PyObject*
11803posix_set_blocking(PyObject *self, PyObject *args)
11804{
Steve Dower8fc89802015-04-12 00:26:27 -040011805 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011806
11807 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11808 return NULL;
11809
Steve Dower8fc89802015-04-12 00:26:27 -040011810 _Py_BEGIN_SUPPRESS_IPH
11811 result = _Py_set_blocking(fd, blocking);
11812 _Py_END_SUPPRESS_IPH
11813 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011814 return NULL;
11815 Py_RETURN_NONE;
11816}
11817#endif /* !MS_WINDOWS */
11818
11819
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011820/*[clinic input]
11821class os.DirEntry "DirEntry *" "&DirEntryType"
11822[clinic start generated code]*/
11823/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011824
11825typedef struct {
11826 PyObject_HEAD
11827 PyObject *name;
11828 PyObject *path;
11829 PyObject *stat;
11830 PyObject *lstat;
11831#ifdef MS_WINDOWS
11832 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011833 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011834 int got_file_index;
11835#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011836#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011837 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011838#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011839 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011840 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011841#endif
11842} DirEntry;
11843
11844static void
11845DirEntry_dealloc(DirEntry *entry)
11846{
11847 Py_XDECREF(entry->name);
11848 Py_XDECREF(entry->path);
11849 Py_XDECREF(entry->stat);
11850 Py_XDECREF(entry->lstat);
11851 Py_TYPE(entry)->tp_free((PyObject *)entry);
11852}
11853
11854/* Forward reference */
11855static int
11856DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11857
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011858/*[clinic input]
11859os.DirEntry.is_symlink -> bool
11860
11861Return True if the entry is a symbolic link; cached per entry.
11862[clinic start generated code]*/
11863
Victor Stinner6036e442015-03-08 01:58:04 +010011864static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011865os_DirEntry_is_symlink_impl(DirEntry *self)
11866/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011867{
11868#ifdef MS_WINDOWS
11869 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011870#elif defined(HAVE_DIRENT_D_TYPE)
11871 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011872 if (self->d_type != DT_UNKNOWN)
11873 return self->d_type == DT_LNK;
11874 else
11875 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011876#else
11877 /* POSIX without d_type */
11878 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011879#endif
11880}
11881
11882static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011883DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11884{
11885 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011886 STRUCT_STAT st;
11887 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011888
11889#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011890 if (!PyUnicode_FSDecoder(self->path, &ub))
11891 return NULL;
11892 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011893#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011894 if (!PyUnicode_FSConverter(self->path, &ub))
11895 return NULL;
11896 const char *path = PyBytes_AS_STRING(ub);
11897 if (self->dir_fd != DEFAULT_DIR_FD) {
11898#ifdef HAVE_FSTATAT
11899 result = fstatat(self->dir_fd, path, &st,
11900 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11901#else
11902 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11903 return NULL;
11904#endif /* HAVE_FSTATAT */
11905 }
11906 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011907#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011908 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011909 if (follow_symlinks)
11910 result = STAT(path, &st);
11911 else
11912 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011913 }
11914 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011915
11916 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011917 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011918
11919 return _pystat_fromstructstat(&st);
11920}
11921
11922static PyObject *
11923DirEntry_get_lstat(DirEntry *self)
11924{
11925 if (!self->lstat) {
11926#ifdef MS_WINDOWS
11927 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11928#else /* POSIX */
11929 self->lstat = DirEntry_fetch_stat(self, 0);
11930#endif
11931 }
11932 Py_XINCREF(self->lstat);
11933 return self->lstat;
11934}
11935
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011936/*[clinic input]
11937os.DirEntry.stat
11938 *
11939 follow_symlinks: bool = True
11940
11941Return stat_result object for the entry; cached per entry.
11942[clinic start generated code]*/
11943
Victor Stinner6036e442015-03-08 01:58:04 +010011944static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011945os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11946/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011947{
11948 if (!follow_symlinks)
11949 return DirEntry_get_lstat(self);
11950
11951 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011952 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011953 if (result == -1)
11954 return NULL;
11955 else if (result)
11956 self->stat = DirEntry_fetch_stat(self, 1);
11957 else
11958 self->stat = DirEntry_get_lstat(self);
11959 }
11960
11961 Py_XINCREF(self->stat);
11962 return self->stat;
11963}
11964
Victor Stinner6036e442015-03-08 01:58:04 +010011965/* Set exception and return -1 on error, 0 for False, 1 for True */
11966static int
11967DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11968{
11969 PyObject *stat = NULL;
11970 PyObject *st_mode = NULL;
11971 long mode;
11972 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011973#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011974 int is_symlink;
11975 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011976#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011977#ifdef MS_WINDOWS
11978 unsigned long dir_bits;
11979#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011980 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011981
11982#ifdef MS_WINDOWS
11983 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11984 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011985#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011986 is_symlink = self->d_type == DT_LNK;
11987 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11988#endif
11989
Victor Stinner35a97c02015-03-08 02:59:09 +010011990#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011991 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011992#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011993 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011994 if (!stat) {
11995 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11996 /* If file doesn't exist (anymore), then return False
11997 (i.e., say it's not a file/directory) */
11998 PyErr_Clear();
11999 return 0;
12000 }
12001 goto error;
12002 }
12003 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12004 if (!st_mode)
12005 goto error;
12006
12007 mode = PyLong_AsLong(st_mode);
12008 if (mode == -1 && PyErr_Occurred())
12009 goto error;
12010 Py_CLEAR(st_mode);
12011 Py_CLEAR(stat);
12012 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012013#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012014 }
12015 else if (is_symlink) {
12016 assert(mode_bits != S_IFLNK);
12017 result = 0;
12018 }
12019 else {
12020 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12021#ifdef MS_WINDOWS
12022 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12023 if (mode_bits == S_IFDIR)
12024 result = dir_bits != 0;
12025 else
12026 result = dir_bits == 0;
12027#else /* POSIX */
12028 if (mode_bits == S_IFDIR)
12029 result = self->d_type == DT_DIR;
12030 else
12031 result = self->d_type == DT_REG;
12032#endif
12033 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012034#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012035
12036 return result;
12037
12038error:
12039 Py_XDECREF(st_mode);
12040 Py_XDECREF(stat);
12041 return -1;
12042}
12043
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012044/*[clinic input]
12045os.DirEntry.is_dir -> bool
12046 *
12047 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012048
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012049Return True if the entry is a directory; cached per entry.
12050[clinic start generated code]*/
12051
12052static int
12053os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12054/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12055{
12056 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012057}
12058
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012059/*[clinic input]
12060os.DirEntry.is_file -> bool
12061 *
12062 follow_symlinks: bool = True
12063
12064Return True if the entry is a file; cached per entry.
12065[clinic start generated code]*/
12066
12067static int
12068os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12069/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012070{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012071 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012072}
12073
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012074/*[clinic input]
12075os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012076
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012077Return inode of the entry; cached per entry.
12078[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012079
12080static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012081os_DirEntry_inode_impl(DirEntry *self)
12082/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012083{
12084#ifdef MS_WINDOWS
12085 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012086 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012087 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012088 STRUCT_STAT stat;
12089 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012090
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012091 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012092 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012093 path = PyUnicode_AsUnicode(unicode);
12094 result = LSTAT(path, &stat);
12095 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012096
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012097 if (result != 0)
12098 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012099
12100 self->win32_file_index = stat.st_ino;
12101 self->got_file_index = 1;
12102 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012103 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12104 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012105#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012106 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12107 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012108#endif
12109}
12110
12111static PyObject *
12112DirEntry_repr(DirEntry *self)
12113{
12114 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12115}
12116
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012117/*[clinic input]
12118os.DirEntry.__fspath__
12119
12120Returns the path for the entry.
12121[clinic start generated code]*/
12122
Brett Cannon96881cd2016-06-10 14:37:21 -070012123static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012124os_DirEntry___fspath___impl(DirEntry *self)
12125/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012126{
12127 Py_INCREF(self->path);
12128 return self->path;
12129}
12130
Victor Stinner6036e442015-03-08 01:58:04 +010012131static PyMemberDef DirEntry_members[] = {
12132 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12133 "the entry's base filename, relative to scandir() \"path\" argument"},
12134 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12135 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12136 {NULL}
12137};
12138
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012139#include "clinic/posixmodule.c.h"
12140
Victor Stinner6036e442015-03-08 01:58:04 +010012141static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012142 OS_DIRENTRY_IS_DIR_METHODDEF
12143 OS_DIRENTRY_IS_FILE_METHODDEF
12144 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12145 OS_DIRENTRY_STAT_METHODDEF
12146 OS_DIRENTRY_INODE_METHODDEF
12147 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012148 {NULL}
12149};
12150
Benjamin Peterson5646de42015-04-12 17:56:34 -040012151static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012152 PyVarObject_HEAD_INIT(NULL, 0)
12153 MODNAME ".DirEntry", /* tp_name */
12154 sizeof(DirEntry), /* tp_basicsize */
12155 0, /* tp_itemsize */
12156 /* methods */
12157 (destructor)DirEntry_dealloc, /* tp_dealloc */
12158 0, /* tp_print */
12159 0, /* tp_getattr */
12160 0, /* tp_setattr */
12161 0, /* tp_compare */
12162 (reprfunc)DirEntry_repr, /* tp_repr */
12163 0, /* tp_as_number */
12164 0, /* tp_as_sequence */
12165 0, /* tp_as_mapping */
12166 0, /* tp_hash */
12167 0, /* tp_call */
12168 0, /* tp_str */
12169 0, /* tp_getattro */
12170 0, /* tp_setattro */
12171 0, /* tp_as_buffer */
12172 Py_TPFLAGS_DEFAULT, /* tp_flags */
12173 0, /* tp_doc */
12174 0, /* tp_traverse */
12175 0, /* tp_clear */
12176 0, /* tp_richcompare */
12177 0, /* tp_weaklistoffset */
12178 0, /* tp_iter */
12179 0, /* tp_iternext */
12180 DirEntry_methods, /* tp_methods */
12181 DirEntry_members, /* tp_members */
12182};
12183
12184#ifdef MS_WINDOWS
12185
12186static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012187join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012188{
12189 Py_ssize_t path_len;
12190 Py_ssize_t size;
12191 wchar_t *result;
12192 wchar_t ch;
12193
12194 if (!path_wide) { /* Default arg: "." */
12195 path_wide = L".";
12196 path_len = 1;
12197 }
12198 else {
12199 path_len = wcslen(path_wide);
12200 }
12201
12202 /* The +1's are for the path separator and the NUL */
12203 size = path_len + 1 + wcslen(filename) + 1;
12204 result = PyMem_New(wchar_t, size);
12205 if (!result) {
12206 PyErr_NoMemory();
12207 return NULL;
12208 }
12209 wcscpy(result, path_wide);
12210 if (path_len > 0) {
12211 ch = result[path_len - 1];
12212 if (ch != SEP && ch != ALTSEP && ch != L':')
12213 result[path_len++] = SEP;
12214 wcscpy(result + path_len, filename);
12215 }
12216 return result;
12217}
12218
12219static PyObject *
12220DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12221{
12222 DirEntry *entry;
12223 BY_HANDLE_FILE_INFORMATION file_info;
12224 ULONG reparse_tag;
12225 wchar_t *joined_path;
12226
12227 entry = PyObject_New(DirEntry, &DirEntryType);
12228 if (!entry)
12229 return NULL;
12230 entry->name = NULL;
12231 entry->path = NULL;
12232 entry->stat = NULL;
12233 entry->lstat = NULL;
12234 entry->got_file_index = 0;
12235
12236 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12237 if (!entry->name)
12238 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012239 if (path->narrow) {
12240 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12241 if (!entry->name)
12242 goto error;
12243 }
Victor Stinner6036e442015-03-08 01:58:04 +010012244
12245 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12246 if (!joined_path)
12247 goto error;
12248
12249 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12250 PyMem_Free(joined_path);
12251 if (!entry->path)
12252 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012253 if (path->narrow) {
12254 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12255 if (!entry->path)
12256 goto error;
12257 }
Victor Stinner6036e442015-03-08 01:58:04 +010012258
Steve Dowercc16be82016-09-08 10:35:16 -070012259 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012260 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12261
12262 return (PyObject *)entry;
12263
12264error:
12265 Py_DECREF(entry);
12266 return NULL;
12267}
12268
12269#else /* POSIX */
12270
12271static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012272join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012273{
12274 Py_ssize_t path_len;
12275 Py_ssize_t size;
12276 char *result;
12277
12278 if (!path_narrow) { /* Default arg: "." */
12279 path_narrow = ".";
12280 path_len = 1;
12281 }
12282 else {
12283 path_len = strlen(path_narrow);
12284 }
12285
12286 if (filename_len == -1)
12287 filename_len = strlen(filename);
12288
12289 /* The +1's are for the path separator and the NUL */
12290 size = path_len + 1 + filename_len + 1;
12291 result = PyMem_New(char, size);
12292 if (!result) {
12293 PyErr_NoMemory();
12294 return NULL;
12295 }
12296 strcpy(result, path_narrow);
12297 if (path_len > 0 && result[path_len - 1] != '/')
12298 result[path_len++] = '/';
12299 strcpy(result + path_len, filename);
12300 return result;
12301}
12302
12303static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012304DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012305 ino_t d_ino
12306#ifdef HAVE_DIRENT_D_TYPE
12307 , unsigned char d_type
12308#endif
12309 )
Victor Stinner6036e442015-03-08 01:58:04 +010012310{
12311 DirEntry *entry;
12312 char *joined_path;
12313
12314 entry = PyObject_New(DirEntry, &DirEntryType);
12315 if (!entry)
12316 return NULL;
12317 entry->name = NULL;
12318 entry->path = NULL;
12319 entry->stat = NULL;
12320 entry->lstat = NULL;
12321
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012322 if (path->fd != -1) {
12323 entry->dir_fd = path->fd;
12324 joined_path = NULL;
12325 }
12326 else {
12327 entry->dir_fd = DEFAULT_DIR_FD;
12328 joined_path = join_path_filename(path->narrow, name, name_len);
12329 if (!joined_path)
12330 goto error;
12331 }
Victor Stinner6036e442015-03-08 01:58:04 +010012332
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012333 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012334 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012335 if (joined_path)
12336 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012337 }
12338 else {
12339 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012340 if (joined_path)
12341 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012342 }
12343 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012344 if (!entry->name)
12345 goto error;
12346
12347 if (path->fd != -1) {
12348 entry->path = entry->name;
12349 Py_INCREF(entry->path);
12350 }
12351 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012352 goto error;
12353
Victor Stinner35a97c02015-03-08 02:59:09 +010012354#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012355 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012356#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012357 entry->d_ino = d_ino;
12358
12359 return (PyObject *)entry;
12360
12361error:
12362 Py_XDECREF(entry);
12363 return NULL;
12364}
12365
12366#endif
12367
12368
12369typedef struct {
12370 PyObject_HEAD
12371 path_t path;
12372#ifdef MS_WINDOWS
12373 HANDLE handle;
12374 WIN32_FIND_DATAW file_data;
12375 int first_time;
12376#else /* POSIX */
12377 DIR *dirp;
12378#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012379#ifdef HAVE_FDOPENDIR
12380 int fd;
12381#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012382} ScandirIterator;
12383
12384#ifdef MS_WINDOWS
12385
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012386static int
12387ScandirIterator_is_closed(ScandirIterator *iterator)
12388{
12389 return iterator->handle == INVALID_HANDLE_VALUE;
12390}
12391
Victor Stinner6036e442015-03-08 01:58:04 +010012392static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012393ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012394{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012395 HANDLE handle = iterator->handle;
12396
12397 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012398 return;
12399
Victor Stinner6036e442015-03-08 01:58:04 +010012400 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012401 Py_BEGIN_ALLOW_THREADS
12402 FindClose(handle);
12403 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012404}
12405
12406static PyObject *
12407ScandirIterator_iternext(ScandirIterator *iterator)
12408{
12409 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12410 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012411 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012412
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012413 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012414 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012415 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012416
12417 while (1) {
12418 if (!iterator->first_time) {
12419 Py_BEGIN_ALLOW_THREADS
12420 success = FindNextFileW(iterator->handle, file_data);
12421 Py_END_ALLOW_THREADS
12422 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012423 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012424 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012425 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012426 break;
12427 }
12428 }
12429 iterator->first_time = 0;
12430
12431 /* Skip over . and .. */
12432 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012433 wcscmp(file_data->cFileName, L"..") != 0) {
12434 entry = DirEntry_from_find_data(&iterator->path, file_data);
12435 if (!entry)
12436 break;
12437 return entry;
12438 }
Victor Stinner6036e442015-03-08 01:58:04 +010012439
12440 /* Loop till we get a non-dot directory or finish iterating */
12441 }
12442
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012443 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012444 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012445 return NULL;
12446}
12447
12448#else /* POSIX */
12449
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012450static int
12451ScandirIterator_is_closed(ScandirIterator *iterator)
12452{
12453 return !iterator->dirp;
12454}
12455
Victor Stinner6036e442015-03-08 01:58:04 +010012456static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012457ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012458{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012459 DIR *dirp = iterator->dirp;
12460
12461 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012462 return;
12463
Victor Stinner6036e442015-03-08 01:58:04 +010012464 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012465 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012466#ifdef HAVE_FDOPENDIR
12467 if (iterator->path.fd != -1)
12468 rewinddir(dirp);
12469#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012470 closedir(dirp);
12471 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012472 return;
12473}
12474
12475static PyObject *
12476ScandirIterator_iternext(ScandirIterator *iterator)
12477{
12478 struct dirent *direntp;
12479 Py_ssize_t name_len;
12480 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012481 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012482
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012483 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012484 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012485 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012486
12487 while (1) {
12488 errno = 0;
12489 Py_BEGIN_ALLOW_THREADS
12490 direntp = readdir(iterator->dirp);
12491 Py_END_ALLOW_THREADS
12492
12493 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012494 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012495 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012496 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012497 break;
12498 }
12499
12500 /* Skip over . and .. */
12501 name_len = NAMLEN(direntp);
12502 is_dot = direntp->d_name[0] == '.' &&
12503 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12504 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012505 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012506 name_len, direntp->d_ino
12507#ifdef HAVE_DIRENT_D_TYPE
12508 , direntp->d_type
12509#endif
12510 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012511 if (!entry)
12512 break;
12513 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012514 }
12515
12516 /* Loop till we get a non-dot directory or finish iterating */
12517 }
12518
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012519 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012520 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012521 return NULL;
12522}
12523
12524#endif
12525
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012526static PyObject *
12527ScandirIterator_close(ScandirIterator *self, PyObject *args)
12528{
12529 ScandirIterator_closedir(self);
12530 Py_RETURN_NONE;
12531}
12532
12533static PyObject *
12534ScandirIterator_enter(PyObject *self, PyObject *args)
12535{
12536 Py_INCREF(self);
12537 return self;
12538}
12539
12540static PyObject *
12541ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12542{
12543 ScandirIterator_closedir(self);
12544 Py_RETURN_NONE;
12545}
12546
Victor Stinner6036e442015-03-08 01:58:04 +010012547static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012548ScandirIterator_finalize(ScandirIterator *iterator)
12549{
12550 PyObject *error_type, *error_value, *error_traceback;
12551
12552 /* Save the current exception, if any. */
12553 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12554
12555 if (!ScandirIterator_is_closed(iterator)) {
12556 ScandirIterator_closedir(iterator);
12557
12558 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12559 "unclosed scandir iterator %R", iterator)) {
12560 /* Spurious errors can appear at shutdown */
12561 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12562 PyErr_WriteUnraisable((PyObject *) iterator);
12563 }
12564 }
12565 }
12566
Victor Stinner7bfa4092016-03-23 00:43:54 +010012567 path_cleanup(&iterator->path);
12568
12569 /* Restore the saved exception. */
12570 PyErr_Restore(error_type, error_value, error_traceback);
12571}
12572
12573static void
Victor Stinner6036e442015-03-08 01:58:04 +010012574ScandirIterator_dealloc(ScandirIterator *iterator)
12575{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012576 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12577 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012578
Victor Stinner6036e442015-03-08 01:58:04 +010012579 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12580}
12581
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012582static PyMethodDef ScandirIterator_methods[] = {
12583 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12584 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12585 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12586 {NULL}
12587};
12588
Benjamin Peterson5646de42015-04-12 17:56:34 -040012589static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012590 PyVarObject_HEAD_INIT(NULL, 0)
12591 MODNAME ".ScandirIterator", /* tp_name */
12592 sizeof(ScandirIterator), /* tp_basicsize */
12593 0, /* tp_itemsize */
12594 /* methods */
12595 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12596 0, /* tp_print */
12597 0, /* tp_getattr */
12598 0, /* tp_setattr */
12599 0, /* tp_compare */
12600 0, /* tp_repr */
12601 0, /* tp_as_number */
12602 0, /* tp_as_sequence */
12603 0, /* tp_as_mapping */
12604 0, /* tp_hash */
12605 0, /* tp_call */
12606 0, /* tp_str */
12607 0, /* tp_getattro */
12608 0, /* tp_setattro */
12609 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012610 Py_TPFLAGS_DEFAULT
12611 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012612 0, /* tp_doc */
12613 0, /* tp_traverse */
12614 0, /* tp_clear */
12615 0, /* tp_richcompare */
12616 0, /* tp_weaklistoffset */
12617 PyObject_SelfIter, /* tp_iter */
12618 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012619 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012620 0, /* tp_members */
12621 0, /* tp_getset */
12622 0, /* tp_base */
12623 0, /* tp_dict */
12624 0, /* tp_descr_get */
12625 0, /* tp_descr_set */
12626 0, /* tp_dictoffset */
12627 0, /* tp_init */
12628 0, /* tp_alloc */
12629 0, /* tp_new */
12630 0, /* tp_free */
12631 0, /* tp_is_gc */
12632 0, /* tp_bases */
12633 0, /* tp_mro */
12634 0, /* tp_cache */
12635 0, /* tp_subclasses */
12636 0, /* tp_weaklist */
12637 0, /* tp_del */
12638 0, /* tp_version_tag */
12639 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012640};
12641
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012642/*[clinic input]
12643os.scandir
12644
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012645 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012646
12647Return an iterator of DirEntry objects for given path.
12648
12649path can be specified as either str, bytes or path-like object. If path
12650is bytes, the names of yielded DirEntry objects will also be bytes; in
12651all other circumstances they will be str.
12652
12653If path is None, uses the path='.'.
12654[clinic start generated code]*/
12655
Victor Stinner6036e442015-03-08 01:58:04 +010012656static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012657os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012658/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012659{
12660 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012661#ifdef MS_WINDOWS
12662 wchar_t *path_strW;
12663#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012664 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012665#ifdef HAVE_FDOPENDIR
12666 int fd = -1;
12667#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012668#endif
12669
12670 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12671 if (!iterator)
12672 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012673
12674#ifdef MS_WINDOWS
12675 iterator->handle = INVALID_HANDLE_VALUE;
12676#else
12677 iterator->dirp = NULL;
12678#endif
12679
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012680 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012681 /* Move the ownership to iterator->path */
12682 path->object = NULL;
12683 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012684
12685#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012686 iterator->first_time = 1;
12687
12688 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12689 if (!path_strW)
12690 goto error;
12691
12692 Py_BEGIN_ALLOW_THREADS
12693 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12694 Py_END_ALLOW_THREADS
12695
12696 PyMem_Free(path_strW);
12697
12698 if (iterator->handle == INVALID_HANDLE_VALUE) {
12699 path_error(&iterator->path);
12700 goto error;
12701 }
12702#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012703 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012704#ifdef HAVE_FDOPENDIR
12705 if (path->fd != -1) {
12706 /* closedir() closes the FD, so we duplicate it */
12707 fd = _Py_dup(path->fd);
12708 if (fd == -1)
12709 goto error;
12710
12711 Py_BEGIN_ALLOW_THREADS
12712 iterator->dirp = fdopendir(fd);
12713 Py_END_ALLOW_THREADS
12714 }
12715 else
12716#endif
12717 {
12718 if (iterator->path.narrow)
12719 path_str = iterator->path.narrow;
12720 else
12721 path_str = ".";
12722
12723 Py_BEGIN_ALLOW_THREADS
12724 iterator->dirp = opendir(path_str);
12725 Py_END_ALLOW_THREADS
12726 }
Victor Stinner6036e442015-03-08 01:58:04 +010012727
12728 if (!iterator->dirp) {
12729 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012730#ifdef HAVE_FDOPENDIR
12731 if (fd != -1) {
12732 Py_BEGIN_ALLOW_THREADS
12733 close(fd);
12734 Py_END_ALLOW_THREADS
12735 }
12736#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012737 goto error;
12738 }
12739#endif
12740
12741 return (PyObject *)iterator;
12742
12743error:
12744 Py_DECREF(iterator);
12745 return NULL;
12746}
12747
Ethan Furman410ef8e2016-06-04 12:06:26 -070012748/*
12749 Return the file system path representation of the object.
12750
12751 If the object is str or bytes, then allow it to pass through with
12752 an incremented refcount. If the object defines __fspath__(), then
12753 return the result of that method. All other types raise a TypeError.
12754*/
12755PyObject *
12756PyOS_FSPath(PyObject *path)
12757{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012758 /* For error message reasons, this function is manually inlined in
12759 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012760 _Py_IDENTIFIER(__fspath__);
12761 PyObject *func = NULL;
12762 PyObject *path_repr = NULL;
12763
12764 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12765 Py_INCREF(path);
12766 return path;
12767 }
12768
12769 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12770 if (NULL == func) {
12771 return PyErr_Format(PyExc_TypeError,
12772 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012773 "not %.200s",
12774 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012775 }
12776
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012777 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012778 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012779 if (NULL == path_repr) {
12780 return NULL;
12781 }
12782
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012783 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12784 PyErr_Format(PyExc_TypeError,
12785 "expected %.200s.__fspath__() to return str or bytes, "
12786 "not %.200s", Py_TYPE(path)->tp_name,
12787 Py_TYPE(path_repr)->tp_name);
12788 Py_DECREF(path_repr);
12789 return NULL;
12790 }
12791
Ethan Furman410ef8e2016-06-04 12:06:26 -070012792 return path_repr;
12793}
12794
12795/*[clinic input]
12796os.fspath
12797
12798 path: object
12799
12800Return the file system path representation of the object.
12801
Brett Cannonb4f43e92016-06-09 14:32:08 -070012802If the object is str or bytes, then allow it to pass through as-is. If the
12803object defines __fspath__(), then return the result of that method. All other
12804types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012805[clinic start generated code]*/
12806
12807static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012808os_fspath_impl(PyObject *module, PyObject *path)
12809/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012810{
12811 return PyOS_FSPath(path);
12812}
Victor Stinner6036e442015-03-08 01:58:04 +010012813
Victor Stinner9b1f4742016-09-06 16:18:52 -070012814#ifdef HAVE_GETRANDOM_SYSCALL
12815/*[clinic input]
12816os.getrandom
12817
12818 size: Py_ssize_t
12819 flags: int=0
12820
12821Obtain a series of random bytes.
12822[clinic start generated code]*/
12823
12824static PyObject *
12825os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12826/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12827{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012828 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012829 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012830
12831 if (size < 0) {
12832 errno = EINVAL;
12833 return posix_error();
12834 }
12835
Victor Stinnerec2319c2016-09-20 23:00:59 +020012836 bytes = PyBytes_FromStringAndSize(NULL, size);
12837 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012838 PyErr_NoMemory();
12839 return NULL;
12840 }
12841
12842 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012843 n = syscall(SYS_getrandom,
12844 PyBytes_AS_STRING(bytes),
12845 PyBytes_GET_SIZE(bytes),
12846 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012847 if (n < 0 && errno == EINTR) {
12848 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012849 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012850 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012851
12852 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012853 continue;
12854 }
12855 break;
12856 }
12857
12858 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012859 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012860 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012861 }
12862
Victor Stinnerec2319c2016-09-20 23:00:59 +020012863 if (n != size) {
12864 _PyBytes_Resize(&bytes, n);
12865 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012866
12867 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012868
12869error:
12870 Py_DECREF(bytes);
12871 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012872}
12873#endif /* HAVE_GETRANDOM_SYSCALL */
12874
Larry Hastings31826802013-10-19 00:09:25 -070012875
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012876static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012877
12878 OS_STAT_METHODDEF
12879 OS_ACCESS_METHODDEF
12880 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012881 OS_CHDIR_METHODDEF
12882 OS_CHFLAGS_METHODDEF
12883 OS_CHMOD_METHODDEF
12884 OS_FCHMOD_METHODDEF
12885 OS_LCHMOD_METHODDEF
12886 OS_CHOWN_METHODDEF
12887 OS_FCHOWN_METHODDEF
12888 OS_LCHOWN_METHODDEF
12889 OS_LCHFLAGS_METHODDEF
12890 OS_CHROOT_METHODDEF
12891 OS_CTERMID_METHODDEF
12892 OS_GETCWD_METHODDEF
12893 OS_GETCWDB_METHODDEF
12894 OS_LINK_METHODDEF
12895 OS_LISTDIR_METHODDEF
12896 OS_LSTAT_METHODDEF
12897 OS_MKDIR_METHODDEF
12898 OS_NICE_METHODDEF
12899 OS_GETPRIORITY_METHODDEF
12900 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000012901 OS_POSIX_SPAWN_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012902#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012903 {"readlink", (PyCFunction)posix_readlink,
12904 METH_VARARGS | METH_KEYWORDS,
12905 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012906#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012907#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012908 {"readlink", (PyCFunction)win_readlink,
12909 METH_VARARGS | METH_KEYWORDS,
12910 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012911#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012912 OS_RENAME_METHODDEF
12913 OS_REPLACE_METHODDEF
12914 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012915 OS_SYMLINK_METHODDEF
12916 OS_SYSTEM_METHODDEF
12917 OS_UMASK_METHODDEF
12918 OS_UNAME_METHODDEF
12919 OS_UNLINK_METHODDEF
12920 OS_REMOVE_METHODDEF
12921 OS_UTIME_METHODDEF
12922 OS_TIMES_METHODDEF
12923 OS__EXIT_METHODDEF
12924 OS_EXECV_METHODDEF
12925 OS_EXECVE_METHODDEF
12926 OS_SPAWNV_METHODDEF
12927 OS_SPAWNVE_METHODDEF
12928 OS_FORK1_METHODDEF
12929 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012930 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012931 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12932 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12933 OS_SCHED_GETPARAM_METHODDEF
12934 OS_SCHED_GETSCHEDULER_METHODDEF
12935 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12936 OS_SCHED_SETPARAM_METHODDEF
12937 OS_SCHED_SETSCHEDULER_METHODDEF
12938 OS_SCHED_YIELD_METHODDEF
12939 OS_SCHED_SETAFFINITY_METHODDEF
12940 OS_SCHED_GETAFFINITY_METHODDEF
12941 OS_OPENPTY_METHODDEF
12942 OS_FORKPTY_METHODDEF
12943 OS_GETEGID_METHODDEF
12944 OS_GETEUID_METHODDEF
12945 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012946#ifdef HAVE_GETGROUPLIST
12947 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12948#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012949 OS_GETGROUPS_METHODDEF
12950 OS_GETPID_METHODDEF
12951 OS_GETPGRP_METHODDEF
12952 OS_GETPPID_METHODDEF
12953 OS_GETUID_METHODDEF
12954 OS_GETLOGIN_METHODDEF
12955 OS_KILL_METHODDEF
12956 OS_KILLPG_METHODDEF
12957 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012958#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012959 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012960#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012961 OS_SETUID_METHODDEF
12962 OS_SETEUID_METHODDEF
12963 OS_SETREUID_METHODDEF
12964 OS_SETGID_METHODDEF
12965 OS_SETEGID_METHODDEF
12966 OS_SETREGID_METHODDEF
12967 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012968#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012969 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012970#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012971 OS_GETPGID_METHODDEF
12972 OS_SETPGRP_METHODDEF
12973 OS_WAIT_METHODDEF
12974 OS_WAIT3_METHODDEF
12975 OS_WAIT4_METHODDEF
12976 OS_WAITID_METHODDEF
12977 OS_WAITPID_METHODDEF
12978 OS_GETSID_METHODDEF
12979 OS_SETSID_METHODDEF
12980 OS_SETPGID_METHODDEF
12981 OS_TCGETPGRP_METHODDEF
12982 OS_TCSETPGRP_METHODDEF
12983 OS_OPEN_METHODDEF
12984 OS_CLOSE_METHODDEF
12985 OS_CLOSERANGE_METHODDEF
12986 OS_DEVICE_ENCODING_METHODDEF
12987 OS_DUP_METHODDEF
12988 OS_DUP2_METHODDEF
12989 OS_LOCKF_METHODDEF
12990 OS_LSEEK_METHODDEF
12991 OS_READ_METHODDEF
12992 OS_READV_METHODDEF
12993 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012994 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012995 OS_WRITE_METHODDEF
12996 OS_WRITEV_METHODDEF
12997 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012998 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012999#ifdef HAVE_SENDFILE
13000 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
13001 posix_sendfile__doc__},
13002#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013003 OS_FSTAT_METHODDEF
13004 OS_ISATTY_METHODDEF
13005 OS_PIPE_METHODDEF
13006 OS_PIPE2_METHODDEF
13007 OS_MKFIFO_METHODDEF
13008 OS_MKNOD_METHODDEF
13009 OS_MAJOR_METHODDEF
13010 OS_MINOR_METHODDEF
13011 OS_MAKEDEV_METHODDEF
13012 OS_FTRUNCATE_METHODDEF
13013 OS_TRUNCATE_METHODDEF
13014 OS_POSIX_FALLOCATE_METHODDEF
13015 OS_POSIX_FADVISE_METHODDEF
13016 OS_PUTENV_METHODDEF
13017 OS_UNSETENV_METHODDEF
13018 OS_STRERROR_METHODDEF
13019 OS_FCHDIR_METHODDEF
13020 OS_FSYNC_METHODDEF
13021 OS_SYNC_METHODDEF
13022 OS_FDATASYNC_METHODDEF
13023 OS_WCOREDUMP_METHODDEF
13024 OS_WIFCONTINUED_METHODDEF
13025 OS_WIFSTOPPED_METHODDEF
13026 OS_WIFSIGNALED_METHODDEF
13027 OS_WIFEXITED_METHODDEF
13028 OS_WEXITSTATUS_METHODDEF
13029 OS_WTERMSIG_METHODDEF
13030 OS_WSTOPSIG_METHODDEF
13031 OS_FSTATVFS_METHODDEF
13032 OS_STATVFS_METHODDEF
13033 OS_CONFSTR_METHODDEF
13034 OS_SYSCONF_METHODDEF
13035 OS_FPATHCONF_METHODDEF
13036 OS_PATHCONF_METHODDEF
13037 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013038 OS__GETFULLPATHNAME_METHODDEF
13039 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013040 OS__GETDISKUSAGE_METHODDEF
13041 OS__GETFINALPATHNAME_METHODDEF
13042 OS__GETVOLUMEPATHNAME_METHODDEF
13043 OS_GETLOADAVG_METHODDEF
13044 OS_URANDOM_METHODDEF
13045 OS_SETRESUID_METHODDEF
13046 OS_SETRESGID_METHODDEF
13047 OS_GETRESUID_METHODDEF
13048 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013049
Larry Hastings2f936352014-08-05 14:04:04 +100013050 OS_GETXATTR_METHODDEF
13051 OS_SETXATTR_METHODDEF
13052 OS_REMOVEXATTR_METHODDEF
13053 OS_LISTXATTR_METHODDEF
13054
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013055#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13056 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13057#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013058 OS_CPU_COUNT_METHODDEF
13059 OS_GET_INHERITABLE_METHODDEF
13060 OS_SET_INHERITABLE_METHODDEF
13061 OS_GET_HANDLE_INHERITABLE_METHODDEF
13062 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013063#ifndef MS_WINDOWS
13064 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
13065 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
13066#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013067 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013068 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013069 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000013070 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013071};
13072
13073
Brian Curtin52173d42010-12-02 18:29:18 +000013074#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013075static int
Brian Curtin52173d42010-12-02 18:29:18 +000013076enable_symlink()
13077{
13078 HANDLE tok;
13079 TOKEN_PRIVILEGES tok_priv;
13080 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000013081
13082 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013083 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013084
13085 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013086 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013087
13088 tok_priv.PrivilegeCount = 1;
13089 tok_priv.Privileges[0].Luid = luid;
13090 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
13091
13092 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
13093 sizeof(TOKEN_PRIVILEGES),
13094 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013095 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013096
Brian Curtin3b4499c2010-12-28 14:31:47 +000013097 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
13098 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000013099}
13100#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
13101
Barry Warsaw4a342091996-12-19 23:50:02 +000013102static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013103all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013104{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013105#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013106 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013107#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013108#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013109 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013110#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013111#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013112 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013113#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013114#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013115 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013116#endif
Fred Drakec9680921999-12-13 16:37:25 +000013117#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013118 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013119#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013120#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013121 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013122#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013123#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013124 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013125#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013126#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013127 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013128#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013129#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013130 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013131#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013132#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013133 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013134#endif
13135#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013136 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013137#endif
13138#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013139 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013140#endif
13141#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013142 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013143#endif
13144#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013145 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013146#endif
13147#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013148 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013149#endif
13150#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013151 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013152#endif
13153#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013154 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013155#endif
13156#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013157 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013158#endif
13159#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013160 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013161#endif
13162#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013163 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013164#endif
13165#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013166 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013167#endif
13168#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013169 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013170#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013171#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013172 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013173#endif
13174#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013175 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013176#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013177#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013178 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013179#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013180#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013181 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013182#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013183#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013184#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013185 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013186#endif
13187#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013188 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013189#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013190#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013191#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013192 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013193#endif
13194#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013195 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013196#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013197#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013198 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013199#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013200#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013201 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013202#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013203#ifdef O_TMPFILE
13204 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13205#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013206#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013207 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013208#endif
13209#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013210 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013211#endif
13212#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013213 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013214#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013215#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013216 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013217#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013218#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013219 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013220#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013221
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013222
Jesus Cea94363612012-06-22 18:32:07 +020013223#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013224 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013225#endif
13226#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013227 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013228#endif
13229
Tim Peters5aa91602002-01-30 05:46:57 +000013230/* MS Windows */
13231#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013232 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013233 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013234#endif
13235#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013236 /* Optimize for short life (keep in memory). */
13237 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013238 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013239#endif
13240#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013241 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013242 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013243#endif
13244#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013245 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013246 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013247#endif
13248#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013249 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013250 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013251#endif
13252
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013253/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013254#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013255 /* Send a SIGIO signal whenever input or output
13256 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013257 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013258#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013259#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013260 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013261 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013262#endif
13263#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013264 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013265 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013266#endif
13267#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013268 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013269 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013270#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013271#ifdef O_NOLINKS
13272 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013273 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013274#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013275#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013276 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013277 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013278#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013279
Victor Stinner8c62be82010-05-06 00:08:46 +000013280 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013281#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013282 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013283#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013284#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013285 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013286#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013287#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013288 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013289#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013290#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013291 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013292#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013293#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013294 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013295#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013296#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013297 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013298#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013299#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013300 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013301#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013302#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013303 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013304#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013305#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013306 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013307#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013308#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013309 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013310#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013311#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013312 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013313#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013314#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013315 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013316#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013317#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013318 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013319#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013320#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013321 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013322#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013323#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013324 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013325#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013326#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013327 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013328#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013329#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013330 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013331#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013332
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013333 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013334#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013335 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013336#endif /* ST_RDONLY */
13337#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013338 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013339#endif /* ST_NOSUID */
13340
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013341 /* GNU extensions */
13342#ifdef ST_NODEV
13343 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13344#endif /* ST_NODEV */
13345#ifdef ST_NOEXEC
13346 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13347#endif /* ST_NOEXEC */
13348#ifdef ST_SYNCHRONOUS
13349 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13350#endif /* ST_SYNCHRONOUS */
13351#ifdef ST_MANDLOCK
13352 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13353#endif /* ST_MANDLOCK */
13354#ifdef ST_WRITE
13355 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13356#endif /* ST_WRITE */
13357#ifdef ST_APPEND
13358 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13359#endif /* ST_APPEND */
13360#ifdef ST_NOATIME
13361 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13362#endif /* ST_NOATIME */
13363#ifdef ST_NODIRATIME
13364 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13365#endif /* ST_NODIRATIME */
13366#ifdef ST_RELATIME
13367 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13368#endif /* ST_RELATIME */
13369
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013370 /* FreeBSD sendfile() constants */
13371#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013372 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013373#endif
13374#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013375 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013376#endif
13377#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013378 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013379#endif
13380
Ross Lagerwall7807c352011-03-17 20:20:30 +020013381 /* constants for posix_fadvise */
13382#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013383 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013384#endif
13385#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013386 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013387#endif
13388#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013389 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013390#endif
13391#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013392 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013393#endif
13394#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013395 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013396#endif
13397#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013398 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013399#endif
13400
13401 /* constants for waitid */
13402#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013403 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13404 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13405 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013406#endif
13407#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013408 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013409#endif
13410#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013411 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013412#endif
13413#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013414 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013415#endif
13416#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013417 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013418#endif
13419#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013420 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013421#endif
13422#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013423 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013424#endif
13425#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013426 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013427#endif
13428
13429 /* constants for lockf */
13430#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013431 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013432#endif
13433#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013434 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013435#endif
13436#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013437 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013438#endif
13439#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013440 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013441#endif
13442
Pablo Galindo4defba32018-01-27 16:16:37 +000013443#ifdef RWF_DSYNC
13444 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13445#endif
13446#ifdef RWF_HIPRI
13447 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13448#endif
13449#ifdef RWF_SYNC
13450 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13451#endif
13452#ifdef RWF_NOWAIT
13453 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13454#endif
13455
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013456/* constants for posix_spawn */
13457#ifdef HAVE_POSIX_SPAWN
13458 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
13459 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
13460 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
13461#endif
13462
Guido van Rossum246bc171999-02-01 23:54:31 +000013463#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013464 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13465 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13466 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13467 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13468 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013469#endif
13470
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013471#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013472#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013473 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013474#endif
13475#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013476 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013477#endif
13478#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013479 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013480#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013481#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013482 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013483#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013484#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013485 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013486#endif
13487#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013488 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013489#endif
13490#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013491 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013492#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013493#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013494 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013495#endif
13496#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013497 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013498#endif
13499#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013500 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013501#endif
13502#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013503 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013504#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013505#endif
13506
Benjamin Peterson9428d532011-09-14 11:45:52 -040013507#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013508 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13509 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13510 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013511#endif
13512
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013513#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013514 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013515#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013516#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013517 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013518#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013519#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013520 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013521#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013522#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013523 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013524#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013525#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013526 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013527#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013528#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013529 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013530#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013531#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013532 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013533#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013534#if HAVE_DECL_RTLD_MEMBER
13535 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13536#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013537
Victor Stinner9b1f4742016-09-06 16:18:52 -070013538#ifdef HAVE_GETRANDOM_SYSCALL
13539 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13540 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13541#endif
13542
Victor Stinner8c62be82010-05-06 00:08:46 +000013543 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013544}
13545
13546
Martin v. Löwis1a214512008-06-11 05:26:20 +000013547static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013548 PyModuleDef_HEAD_INIT,
13549 MODNAME,
13550 posix__doc__,
13551 -1,
13552 posix_methods,
13553 NULL,
13554 NULL,
13555 NULL,
13556 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013557};
13558
13559
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013560static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013561
13562#ifdef HAVE_FACCESSAT
13563 "HAVE_FACCESSAT",
13564#endif
13565
13566#ifdef HAVE_FCHDIR
13567 "HAVE_FCHDIR",
13568#endif
13569
13570#ifdef HAVE_FCHMOD
13571 "HAVE_FCHMOD",
13572#endif
13573
13574#ifdef HAVE_FCHMODAT
13575 "HAVE_FCHMODAT",
13576#endif
13577
13578#ifdef HAVE_FCHOWN
13579 "HAVE_FCHOWN",
13580#endif
13581
Larry Hastings00964ed2013-08-12 13:49:30 -040013582#ifdef HAVE_FCHOWNAT
13583 "HAVE_FCHOWNAT",
13584#endif
13585
Larry Hastings9cf065c2012-06-22 16:30:09 -070013586#ifdef HAVE_FEXECVE
13587 "HAVE_FEXECVE",
13588#endif
13589
13590#ifdef HAVE_FDOPENDIR
13591 "HAVE_FDOPENDIR",
13592#endif
13593
Georg Brandl306336b2012-06-24 12:55:33 +020013594#ifdef HAVE_FPATHCONF
13595 "HAVE_FPATHCONF",
13596#endif
13597
Larry Hastings9cf065c2012-06-22 16:30:09 -070013598#ifdef HAVE_FSTATAT
13599 "HAVE_FSTATAT",
13600#endif
13601
13602#ifdef HAVE_FSTATVFS
13603 "HAVE_FSTATVFS",
13604#endif
13605
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013606#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013607 "HAVE_FTRUNCATE",
13608#endif
13609
Larry Hastings9cf065c2012-06-22 16:30:09 -070013610#ifdef HAVE_FUTIMENS
13611 "HAVE_FUTIMENS",
13612#endif
13613
13614#ifdef HAVE_FUTIMES
13615 "HAVE_FUTIMES",
13616#endif
13617
13618#ifdef HAVE_FUTIMESAT
13619 "HAVE_FUTIMESAT",
13620#endif
13621
13622#ifdef HAVE_LINKAT
13623 "HAVE_LINKAT",
13624#endif
13625
13626#ifdef HAVE_LCHFLAGS
13627 "HAVE_LCHFLAGS",
13628#endif
13629
13630#ifdef HAVE_LCHMOD
13631 "HAVE_LCHMOD",
13632#endif
13633
13634#ifdef HAVE_LCHOWN
13635 "HAVE_LCHOWN",
13636#endif
13637
13638#ifdef HAVE_LSTAT
13639 "HAVE_LSTAT",
13640#endif
13641
13642#ifdef HAVE_LUTIMES
13643 "HAVE_LUTIMES",
13644#endif
13645
13646#ifdef HAVE_MKDIRAT
13647 "HAVE_MKDIRAT",
13648#endif
13649
13650#ifdef HAVE_MKFIFOAT
13651 "HAVE_MKFIFOAT",
13652#endif
13653
13654#ifdef HAVE_MKNODAT
13655 "HAVE_MKNODAT",
13656#endif
13657
13658#ifdef HAVE_OPENAT
13659 "HAVE_OPENAT",
13660#endif
13661
13662#ifdef HAVE_READLINKAT
13663 "HAVE_READLINKAT",
13664#endif
13665
13666#ifdef HAVE_RENAMEAT
13667 "HAVE_RENAMEAT",
13668#endif
13669
13670#ifdef HAVE_SYMLINKAT
13671 "HAVE_SYMLINKAT",
13672#endif
13673
13674#ifdef HAVE_UNLINKAT
13675 "HAVE_UNLINKAT",
13676#endif
13677
13678#ifdef HAVE_UTIMENSAT
13679 "HAVE_UTIMENSAT",
13680#endif
13681
13682#ifdef MS_WINDOWS
13683 "MS_WINDOWS",
13684#endif
13685
13686 NULL
13687};
13688
13689
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013690PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013691INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013692{
Victor Stinner8c62be82010-05-06 00:08:46 +000013693 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013694 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013695 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013696
Brian Curtin52173d42010-12-02 18:29:18 +000013697#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013698 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013699#endif
13700
Victor Stinner8c62be82010-05-06 00:08:46 +000013701 m = PyModule_Create(&posixmodule);
13702 if (m == NULL)
13703 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013704
Victor Stinner8c62be82010-05-06 00:08:46 +000013705 /* Initialize environ dictionary */
13706 v = convertenviron();
13707 Py_XINCREF(v);
13708 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13709 return NULL;
13710 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013711
Victor Stinner8c62be82010-05-06 00:08:46 +000013712 if (all_ins(m))
13713 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013714
Victor Stinner8c62be82010-05-06 00:08:46 +000013715 if (setup_confname_tables(m))
13716 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013717
Victor Stinner8c62be82010-05-06 00:08:46 +000013718 Py_INCREF(PyExc_OSError);
13719 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013720
Guido van Rossumb3d39562000-01-31 18:41:26 +000013721#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013722 if (posix_putenv_garbage == NULL)
13723 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013724#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013725
Victor Stinner8c62be82010-05-06 00:08:46 +000013726 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013727#if defined(HAVE_WAITID) && !defined(__APPLE__)
13728 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013729 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13730 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013731#endif
13732
Christian Heimes25827622013-10-12 01:27:08 +020013733 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013734 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13735 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13736 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013737 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13738 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013739 structseq_new = StatResultType.tp_new;
13740 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013741
Christian Heimes25827622013-10-12 01:27:08 +020013742 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013743 if (PyStructSequence_InitType2(&StatVFSResultType,
13744 &statvfs_result_desc) < 0)
13745 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013746#ifdef NEED_TICKS_PER_SECOND
13747# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013748 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013749# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013750 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013751# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013752 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013753# endif
13754#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013755
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013756#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013757 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013758 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13759 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013760 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013761#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013762
13763 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013764 if (PyStructSequence_InitType2(&TerminalSizeType,
13765 &TerminalSize_desc) < 0)
13766 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013767
13768 /* initialize scandir types */
13769 if (PyType_Ready(&ScandirIteratorType) < 0)
13770 return NULL;
13771 if (PyType_Ready(&DirEntryType) < 0)
13772 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013773 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013774#if defined(HAVE_WAITID) && !defined(__APPLE__)
13775 Py_INCREF((PyObject*) &WaitidResultType);
13776 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13777#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013778 Py_INCREF((PyObject*) &StatResultType);
13779 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13780 Py_INCREF((PyObject*) &StatVFSResultType);
13781 PyModule_AddObject(m, "statvfs_result",
13782 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013783
13784#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013785 Py_INCREF(&SchedParamType);
13786 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013787#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013788
Larry Hastings605a62d2012-06-24 04:33:36 -070013789 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013790 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13791 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013792 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13793
13794 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013795 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13796 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013797 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13798
Thomas Wouters477c8d52006-05-27 19:21:47 +000013799#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013800 /*
13801 * Step 2 of weak-linking support on Mac OS X.
13802 *
13803 * The code below removes functions that are not available on the
13804 * currently active platform.
13805 *
13806 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013807 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013808 * OSX 10.4.
13809 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013810#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013811 if (fstatvfs == NULL) {
13812 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13813 return NULL;
13814 }
13815 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013816#endif /* HAVE_FSTATVFS */
13817
13818#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013819 if (statvfs == NULL) {
13820 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13821 return NULL;
13822 }
13823 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013824#endif /* HAVE_STATVFS */
13825
13826# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013827 if (lchown == NULL) {
13828 if (PyObject_DelAttrString(m, "lchown") == -1) {
13829 return NULL;
13830 }
13831 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013832#endif /* HAVE_LCHOWN */
13833
13834
13835#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013836
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013837 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013838 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13839
Larry Hastings6fe20b32012-04-19 15:07:49 -070013840 billion = PyLong_FromLong(1000000000);
13841 if (!billion)
13842 return NULL;
13843
Larry Hastings9cf065c2012-06-22 16:30:09 -070013844 /* suppress "function not used" warnings */
13845 {
13846 int ignored;
13847 fd_specified("", -1);
13848 follow_symlinks_specified("", 1);
13849 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13850 dir_fd_converter(Py_None, &ignored);
13851 dir_fd_unavailable(Py_None, &ignored);
13852 }
13853
13854 /*
13855 * provide list of locally available functions
13856 * so os.py can populate support_* lists
13857 */
13858 list = PyList_New(0);
13859 if (!list)
13860 return NULL;
13861 for (trace = have_functions; *trace; trace++) {
13862 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13863 if (!unicode)
13864 return NULL;
13865 if (PyList_Append(list, unicode))
13866 return NULL;
13867 Py_DECREF(unicode);
13868 }
13869 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013870
13871 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013872 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013873
13874 initialized = 1;
13875
Victor Stinner8c62be82010-05-06 00:08:46 +000013876 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013877}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013878
13879#ifdef __cplusplus
13880}
13881#endif