blob: 83135e536a51b23b775fa854b8b512295ae397ca [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 Rossum8e9ebfd1997-11-22 21:53:48 +0000213#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000214extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000215#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000216#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000220#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000221#endif
222#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000223extern int chdir(char *);
224extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000225#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000226extern int chdir(const char *);
227extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000228#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000229extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000230/*#ifdef HAVE_FCHMOD
231extern int fchmod(int, mode_t);
232#endif*/
233/*#ifdef HAVE_LCHMOD
234extern int lchmod(const char *, mode_t);
235#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000236extern int chown(const char *, uid_t, gid_t);
237extern char *getcwd(char *, int);
238extern char *strerror(int);
239extern int link(const char *, const char *);
240extern int rename(const char *, const char *);
241extern int stat(const char *, struct stat *);
242extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000244extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000245#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000247extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000248#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000250
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000251#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000252
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 VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000307#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000308#endif
309#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000310#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000311#endif
312#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000313#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000314#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100315#ifndef IO_REPARSE_TAG_MOUNT_POINT
316#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
317#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000318#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000319#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000320#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000321#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000322#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000323#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
324#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000325static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000326#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000327#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000328
Tim Petersbc2e10e2002-03-03 23:17:02 +0000329#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000330#if defined(PATH_MAX) && PATH_MAX > 1024
331#define MAXPATHLEN PATH_MAX
332#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000333#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000334#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000335#endif /* MAXPATHLEN */
336
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000337#ifdef UNION_WAIT
338/* Emulate some macros on systems that have a union instead of macros */
339
340#ifndef WIFEXITED
341#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
342#endif
343
344#ifndef WEXITSTATUS
345#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
346#endif
347
348#ifndef WTERMSIG
349#define WTERMSIG(u_wait) ((u_wait).w_termsig)
350#endif
351
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000352#define WAIT_TYPE union wait
353#define WAIT_STATUS_INT(s) (s.w_status)
354
355#else /* !UNION_WAIT */
356#define WAIT_TYPE int
357#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000358#endif /* UNION_WAIT */
359
Greg Wardb48bc172000-03-01 21:51:56 +0000360/* Don't use the "_r" form if we don't need it (also, won't have a
361 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200362#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000363#define USE_CTERMID_R
364#endif
365
Fred Drake699f3522000-06-29 21:12:41 +0000366/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000367#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000368#undef FSTAT
369#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200370#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000371# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700372# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200373# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800374# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000375#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000376# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700377# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000378# define FSTAT fstat
379# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000380#endif
381
Tim Peters11b23062003-04-23 02:39:17 +0000382#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000383#include <sys/mkdev.h>
384#else
385#if defined(MAJOR_IN_SYSMACROS)
386#include <sys/sysmacros.h>
387#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000388#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
389#include <sys/mkdev.h>
390#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000391#endif
Fred Drake699f3522000-06-29 21:12:41 +0000392
Victor Stinner6edddfa2013-11-24 19:22:57 +0100393#define DWORD_MAX 4294967295U
394
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200395#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100396#define INITFUNC PyInit_nt
397#define MODNAME "nt"
398#else
399#define INITFUNC PyInit_posix
400#define MODNAME "posix"
401#endif
402
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200403
404#ifdef HAVE_FORK
405static void
406run_at_forkers(PyObject *lst, int reverse)
407{
408 Py_ssize_t i;
409 PyObject *cpy;
410
411 if (lst != NULL) {
412 assert(PyList_CheckExact(lst));
413
414 /* Use a list copy in case register_at_fork() is called from
415 * one of the callbacks.
416 */
417 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
418 if (cpy == NULL)
419 PyErr_WriteUnraisable(lst);
420 else {
421 if (reverse)
422 PyList_Reverse(cpy);
423 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
424 PyObject *func, *res;
425 func = PyList_GET_ITEM(cpy, i);
426 res = PyObject_CallObject(func, NULL);
427 if (res == NULL)
428 PyErr_WriteUnraisable(func);
429 else
430 Py_DECREF(res);
431 }
432 Py_DECREF(cpy);
433 }
434 }
435}
436
437void
438PyOS_BeforeFork(void)
439{
440 run_at_forkers(PyThreadState_Get()->interp->before_forkers, 1);
441
442 _PyImport_AcquireLock();
443}
444
445void
446PyOS_AfterFork_Parent(void)
447{
448 if (_PyImport_ReleaseLock() <= 0)
449 Py_FatalError("failed releasing import lock after fork");
450
451 run_at_forkers(PyThreadState_Get()->interp->after_forkers_parent, 0);
452}
453
454void
455PyOS_AfterFork_Child(void)
456{
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200457 /* PyThread_ReInitTLS() must be called early, to make sure that the TLS API
458 * can be called safely. */
459 PyThread_ReInitTLS();
460 _PyGILState_Reinit();
461 PyEval_ReInitThreads();
462 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200463 _PySignal_AfterFork();
464
465 run_at_forkers(PyThreadState_Get()->interp->after_forkers_child, 0);
466}
467
468static int
469register_at_forker(PyObject **lst, PyObject *func)
470{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700471 if (func == NULL) /* nothing to register? do nothing. */
472 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200473 if (*lst == NULL) {
474 *lst = PyList_New(0);
475 if (*lst == NULL)
476 return -1;
477 }
478 return PyList_Append(*lst, func);
479}
480#endif
481
482/* Legacy wrapper */
483void
484PyOS_AfterFork(void)
485{
486#ifdef HAVE_FORK
487 PyOS_AfterFork_Child();
488#endif
489}
490
491
Victor Stinner6036e442015-03-08 01:58:04 +0100492#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200493/* defined in fileutils.c */
494PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
495PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
496 ULONG, struct _Py_stat_struct *);
497#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700498
499#ifdef MS_WINDOWS
500static int
501win32_warn_bytes_api()
502{
503 return PyErr_WarnEx(PyExc_DeprecationWarning,
504 "The Windows bytes API has been deprecated, "
505 "use Unicode filenames instead",
506 1);
507}
508#endif
509
510
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200511#ifndef MS_WINDOWS
512PyObject *
513_PyLong_FromUid(uid_t uid)
514{
515 if (uid == (uid_t)-1)
516 return PyLong_FromLong(-1);
517 return PyLong_FromUnsignedLong(uid);
518}
519
520PyObject *
521_PyLong_FromGid(gid_t gid)
522{
523 if (gid == (gid_t)-1)
524 return PyLong_FromLong(-1);
525 return PyLong_FromUnsignedLong(gid);
526}
527
528int
529_Py_Uid_Converter(PyObject *obj, void *p)
530{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700531 uid_t uid;
532 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200533 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200534 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700535 unsigned long uresult;
536
537 index = PyNumber_Index(obj);
538 if (index == NULL) {
539 PyErr_Format(PyExc_TypeError,
540 "uid should be integer, not %.200s",
541 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200542 return 0;
543 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700544
545 /*
546 * Handling uid_t is complicated for two reasons:
547 * * Although uid_t is (always?) unsigned, it still
548 * accepts -1.
549 * * We don't know its size in advance--it may be
550 * bigger than an int, or it may be smaller than
551 * a long.
552 *
553 * So a bit of defensive programming is in order.
554 * Start with interpreting the value passed
555 * in as a signed long and see if it works.
556 */
557
558 result = PyLong_AsLongAndOverflow(index, &overflow);
559
560 if (!overflow) {
561 uid = (uid_t)result;
562
563 if (result == -1) {
564 if (PyErr_Occurred())
565 goto fail;
566 /* It's a legitimate -1, we're done. */
567 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200568 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700569
570 /* Any other negative number is disallowed. */
571 if (result < 0)
572 goto underflow;
573
574 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200575 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700576 (long)uid != result)
577 goto underflow;
578 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200579 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700580
581 if (overflow < 0)
582 goto underflow;
583
584 /*
585 * Okay, the value overflowed a signed long. If it
586 * fits in an *unsigned* long, it may still be okay,
587 * as uid_t may be unsigned long on this platform.
588 */
589 uresult = PyLong_AsUnsignedLong(index);
590 if (PyErr_Occurred()) {
591 if (PyErr_ExceptionMatches(PyExc_OverflowError))
592 goto overflow;
593 goto fail;
594 }
595
596 uid = (uid_t)uresult;
597
598 /*
599 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
600 * but this value would get interpreted as (uid_t)-1 by chown
601 * and its siblings. That's not what the user meant! So we
602 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100603 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700604 */
605 if (uid == (uid_t)-1)
606 goto overflow;
607
608 /* Ensure the value wasn't truncated. */
609 if (sizeof(uid_t) < sizeof(long) &&
610 (unsigned long)uid != uresult)
611 goto overflow;
612 /* fallthrough */
613
614success:
615 Py_DECREF(index);
616 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200617 return 1;
618
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700619underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200620 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700621 "uid is less than minimum");
622 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200623
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700624overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200625 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700626 "uid is greater than maximum");
627 /* fallthrough */
628
629fail:
630 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200631 return 0;
632}
633
634int
635_Py_Gid_Converter(PyObject *obj, void *p)
636{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700637 gid_t gid;
638 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200639 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200640 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700641 unsigned long uresult;
642
643 index = PyNumber_Index(obj);
644 if (index == NULL) {
645 PyErr_Format(PyExc_TypeError,
646 "gid should be integer, not %.200s",
647 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200648 return 0;
649 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700650
651 /*
652 * Handling gid_t is complicated for two reasons:
653 * * Although gid_t is (always?) unsigned, it still
654 * accepts -1.
655 * * We don't know its size in advance--it may be
656 * bigger than an int, or it may be smaller than
657 * a long.
658 *
659 * So a bit of defensive programming is in order.
660 * Start with interpreting the value passed
661 * in as a signed long and see if it works.
662 */
663
664 result = PyLong_AsLongAndOverflow(index, &overflow);
665
666 if (!overflow) {
667 gid = (gid_t)result;
668
669 if (result == -1) {
670 if (PyErr_Occurred())
671 goto fail;
672 /* It's a legitimate -1, we're done. */
673 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200674 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700675
676 /* Any other negative number is disallowed. */
677 if (result < 0) {
678 goto underflow;
679 }
680
681 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200682 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700683 (long)gid != result)
684 goto underflow;
685 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200686 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700687
688 if (overflow < 0)
689 goto underflow;
690
691 /*
692 * Okay, the value overflowed a signed long. If it
693 * fits in an *unsigned* long, it may still be okay,
694 * as gid_t may be unsigned long on this platform.
695 */
696 uresult = PyLong_AsUnsignedLong(index);
697 if (PyErr_Occurred()) {
698 if (PyErr_ExceptionMatches(PyExc_OverflowError))
699 goto overflow;
700 goto fail;
701 }
702
703 gid = (gid_t)uresult;
704
705 /*
706 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
707 * but this value would get interpreted as (gid_t)-1 by chown
708 * and its siblings. That's not what the user meant! So we
709 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100710 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700711 */
712 if (gid == (gid_t)-1)
713 goto overflow;
714
715 /* Ensure the value wasn't truncated. */
716 if (sizeof(gid_t) < sizeof(long) &&
717 (unsigned long)gid != uresult)
718 goto overflow;
719 /* fallthrough */
720
721success:
722 Py_DECREF(index);
723 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200724 return 1;
725
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700726underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200727 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700728 "gid is less than minimum");
729 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200730
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700731overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200732 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700733 "gid is greater than maximum");
734 /* fallthrough */
735
736fail:
737 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200738 return 0;
739}
740#endif /* MS_WINDOWS */
741
742
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700743#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800744
745
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200746#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
747static int
748_Py_Dev_Converter(PyObject *obj, void *p)
749{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200750 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200751 if (PyErr_Occurred())
752 return 0;
753 return 1;
754}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800755#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200756
757
Larry Hastings9cf065c2012-06-22 16:30:09 -0700758#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400759/*
760 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
761 * without the int cast, the value gets interpreted as uint (4291925331),
762 * which doesn't play nicely with all the initializer lines in this file that
763 * look like this:
764 * int dir_fd = DEFAULT_DIR_FD;
765 */
766#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700767#else
768#define DEFAULT_DIR_FD (-100)
769#endif
770
771static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300772_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200773{
774 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700775 long long_value;
776
777 PyObject *index = PyNumber_Index(o);
778 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700779 return 0;
780 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700781
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300782 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700783 long_value = PyLong_AsLongAndOverflow(index, &overflow);
784 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300785 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200786 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700787 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700788 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700789 return 0;
790 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200791 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700792 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700793 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700794 return 0;
795 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700796
Larry Hastings9cf065c2012-06-22 16:30:09 -0700797 *p = (int)long_value;
798 return 1;
799}
800
801static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200802dir_fd_converter(PyObject *o, void *p)
803{
804 if (o == Py_None) {
805 *(int *)p = DEFAULT_DIR_FD;
806 return 1;
807 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300808 else if (PyIndex_Check(o)) {
809 return _fd_converter(o, (int *)p);
810 }
811 else {
812 PyErr_Format(PyExc_TypeError,
813 "argument should be integer or None, not %.200s",
814 Py_TYPE(o)->tp_name);
815 return 0;
816 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700817}
818
819
Larry Hastings9cf065c2012-06-22 16:30:09 -0700820/*
821 * A PyArg_ParseTuple "converter" function
822 * that handles filesystem paths in the manner
823 * preferred by the os module.
824 *
825 * path_converter accepts (Unicode) strings and their
826 * subclasses, and bytes and their subclasses. What
827 * it does with the argument depends on the platform:
828 *
829 * * On Windows, if we get a (Unicode) string we
830 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700831 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700832 *
833 * * On all other platforms, strings are encoded
834 * to bytes using PyUnicode_FSConverter, then we
835 * extract the char * from the bytes object and
836 * return that.
837 *
838 * path_converter also optionally accepts signed
839 * integers (representing open file descriptors) instead
840 * of path strings.
841 *
842 * Input fields:
843 * path.nullable
844 * If nonzero, the path is permitted to be None.
845 * path.allow_fd
846 * If nonzero, the path is permitted to be a file handle
847 * (a signed int) instead of a string.
848 * path.function_name
849 * If non-NULL, path_converter will use that as the name
850 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700851 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700852 * path.argument_name
853 * If non-NULL, path_converter will use that as the name
854 * of the parameter in error messages.
855 * (If path.argument_name is NULL it uses "path".)
856 *
857 * Output fields:
858 * path.wide
859 * Points to the path if it was expressed as Unicode
860 * and was not encoded. (Only used on Windows.)
861 * path.narrow
862 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700863 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000864 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700865 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700866 * path.fd
867 * Contains a file descriptor if path.accept_fd was true
868 * and the caller provided a signed integer instead of any
869 * sort of string.
870 *
871 * WARNING: if your "path" parameter is optional, and is
872 * unspecified, path_converter will never get called.
873 * So if you set allow_fd, you *MUST* initialize path.fd = -1
874 * yourself!
875 * path.length
876 * The length of the path in characters, if specified as
877 * a string.
878 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800879 * The original object passed in (if get a PathLike object,
880 * the result of PyOS_FSPath() is treated as the original object).
881 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700882 * path.cleanup
883 * For internal use only. May point to a temporary object.
884 * (Pay no attention to the man behind the curtain.)
885 *
886 * At most one of path.wide or path.narrow will be non-NULL.
887 * If path was None and path.nullable was set,
888 * or if path was an integer and path.allow_fd was set,
889 * both path.wide and path.narrow will be NULL
890 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200891 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700892 * path_converter takes care to not write to the path_t
893 * unless it's successful. However it must reset the
894 * "cleanup" field each time it's called.
895 *
896 * Use as follows:
897 * path_t path;
898 * memset(&path, 0, sizeof(path));
899 * PyArg_ParseTuple(args, "O&", path_converter, &path);
900 * // ... use values from path ...
901 * path_cleanup(&path);
902 *
903 * (Note that if PyArg_Parse fails you don't need to call
904 * path_cleanup(). However it is safe to do so.)
905 */
906typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100907 const char *function_name;
908 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700909 int nullable;
910 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300911 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700912#ifdef MS_WINDOWS
913 BOOL narrow;
914#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300915 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700916#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700917 int fd;
918 Py_ssize_t length;
919 PyObject *object;
920 PyObject *cleanup;
921} path_t;
922
Steve Dowercc16be82016-09-08 10:35:16 -0700923#ifdef MS_WINDOWS
924#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
925 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
926#else
Larry Hastings2f936352014-08-05 14:04:04 +1000927#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
928 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700929#endif
Larry Hastings31826802013-10-19 00:09:25 -0700930
Larry Hastings9cf065c2012-06-22 16:30:09 -0700931static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800932path_cleanup(path_t *path)
933{
934 Py_CLEAR(path->object);
935 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700936}
937
938static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300939path_converter(PyObject *o, void *p)
940{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800942 PyObject *bytes = NULL;
943 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700944 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300945 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700946#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800947 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700948 const wchar_t *wide;
949#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700950
951#define FORMAT_EXCEPTION(exc, fmt) \
952 PyErr_Format(exc, "%s%s" fmt, \
953 path->function_name ? path->function_name : "", \
954 path->function_name ? ": " : "", \
955 path->argument_name ? path->argument_name : "path")
956
957 /* Py_CLEANUP_SUPPORTED support */
958 if (o == NULL) {
959 path_cleanup(path);
960 return 1;
961 }
962
Brett Cannon3f9183b2016-08-26 14:44:48 -0700963 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800964 path->object = path->cleanup = NULL;
965 /* path->object owns a reference to the original object */
966 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700967
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300968 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700969 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700970#ifdef MS_WINDOWS
971 path->narrow = FALSE;
972#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700973 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700974#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700975 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800976 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700977 }
978
Brett Cannon3f9183b2016-08-26 14:44:48 -0700979 /* Only call this here so that we don't treat the return value of
980 os.fspath() as an fd or buffer. */
981 is_index = path->allow_fd && PyIndex_Check(o);
982 is_buffer = PyObject_CheckBuffer(o);
983 is_bytes = PyBytes_Check(o);
984 is_unicode = PyUnicode_Check(o);
985
986 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
987 /* Inline PyOS_FSPath() for better error messages. */
988 _Py_IDENTIFIER(__fspath__);
989 PyObject *func = NULL;
990
991 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
992 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800993 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700994 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800995 /* still owns a reference to the original object */
996 Py_DECREF(o);
997 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700998 Py_DECREF(func);
999 if (NULL == o) {
1000 goto error_exit;
1001 }
1002 else if (PyUnicode_Check(o)) {
1003 is_unicode = 1;
1004 }
1005 else if (PyBytes_Check(o)) {
1006 is_bytes = 1;
1007 }
1008 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001009 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001010 }
1011 }
1012
1013 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001014#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001015 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001016 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001017 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001018 }
Victor Stinner59799a82013-11-13 14:17:30 +01001019 if (length > 32767) {
1020 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001021 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001022 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001023 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001024 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001025 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001026 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001027
1028 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001029 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001030 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001031 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001032#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001033 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001034 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001035 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001036#endif
1037 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001038 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001039 bytes = o;
1040 Py_INCREF(bytes);
1041 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001042 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001043 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001044 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001045 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1046 "%s%s%s should be %s, not %.200s",
1047 path->function_name ? path->function_name : "",
1048 path->function_name ? ": " : "",
1049 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001050 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1051 "integer or None" :
1052 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1053 path->nullable ? "string, bytes, os.PathLike or None" :
1054 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001055 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001056 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001057 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001058 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001059 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001060 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001061 }
1062 }
Steve Dowercc16be82016-09-08 10:35:16 -07001063 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001064 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001065 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001066 }
1067 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001068#ifdef MS_WINDOWS
1069 path->narrow = FALSE;
1070#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001071 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001072#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001073 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001074 }
1075 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001076 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001077 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1078 path->function_name ? path->function_name : "",
1079 path->function_name ? ": " : "",
1080 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001081 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1082 "integer or None" :
1083 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1084 path->nullable ? "string, bytes, os.PathLike or None" :
1085 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001086 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001087 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001088 }
1089
Larry Hastings9cf065c2012-06-22 16:30:09 -07001090 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001091 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001092 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001093 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001094 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001095 }
1096
Steve Dowercc16be82016-09-08 10:35:16 -07001097#ifdef MS_WINDOWS
1098 wo = PyUnicode_DecodeFSDefaultAndSize(
1099 narrow,
1100 length
1101 );
1102 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001103 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001104 }
1105
Xiang Zhang04316c42017-01-08 23:26:57 +08001106 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001107 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001108 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001109 }
1110 if (length > 32767) {
1111 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001112 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001113 }
1114 if (wcslen(wide) != length) {
1115 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001116 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001117 }
1118 path->wide = wide;
1119 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001120 path->cleanup = wo;
1121 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001122#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001123 path->wide = NULL;
1124 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001125 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001126 /* Still a reference owned by path->object, don't have to
1127 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001128 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001129 }
1130 else {
1131 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001132 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001133#endif
1134 path->fd = -1;
1135
1136 success_exit:
1137 path->length = length;
1138 path->object = o;
1139 return Py_CLEANUP_SUPPORTED;
1140
1141 error_exit:
1142 Py_XDECREF(o);
1143 Py_XDECREF(bytes);
1144#ifdef MS_WINDOWS
1145 Py_XDECREF(wo);
1146#endif
1147 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001148}
1149
1150static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001151argument_unavailable_error(const char *function_name, const char *argument_name)
1152{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001153 PyErr_Format(PyExc_NotImplementedError,
1154 "%s%s%s unavailable on this platform",
1155 (function_name != NULL) ? function_name : "",
1156 (function_name != NULL) ? ": ": "",
1157 argument_name);
1158}
1159
1160static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001161dir_fd_unavailable(PyObject *o, void *p)
1162{
1163 int dir_fd;
1164 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001165 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001166 if (dir_fd != DEFAULT_DIR_FD) {
1167 argument_unavailable_error(NULL, "dir_fd");
1168 return 0;
1169 }
1170 *(int *)p = dir_fd;
1171 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001172}
1173
1174static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001175fd_specified(const char *function_name, int fd)
1176{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001177 if (fd == -1)
1178 return 0;
1179
1180 argument_unavailable_error(function_name, "fd");
1181 return 1;
1182}
1183
1184static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001185follow_symlinks_specified(const char *function_name, int follow_symlinks)
1186{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001187 if (follow_symlinks)
1188 return 0;
1189
1190 argument_unavailable_error(function_name, "follow_symlinks");
1191 return 1;
1192}
1193
1194static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001195path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1196{
Steve Dowercc16be82016-09-08 10:35:16 -07001197 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1198#ifndef MS_WINDOWS
1199 && !path->narrow
1200#endif
1201 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001202 PyErr_Format(PyExc_ValueError,
1203 "%s: can't specify dir_fd without matching path",
1204 function_name);
1205 return 1;
1206 }
1207 return 0;
1208}
1209
1210static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001211dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1212{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001213 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1214 PyErr_Format(PyExc_ValueError,
1215 "%s: can't specify both dir_fd and fd",
1216 function_name);
1217 return 1;
1218 }
1219 return 0;
1220}
1221
1222static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001223fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1224 int follow_symlinks)
1225{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001226 if ((fd > 0) && (!follow_symlinks)) {
1227 PyErr_Format(PyExc_ValueError,
1228 "%s: cannot use fd and follow_symlinks together",
1229 function_name);
1230 return 1;
1231 }
1232 return 0;
1233}
1234
1235static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001236dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1237 int follow_symlinks)
1238{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001239 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1240 PyErr_Format(PyExc_ValueError,
1241 "%s: cannot use dir_fd and follow_symlinks together",
1242 function_name);
1243 return 1;
1244 }
1245 return 0;
1246}
1247
Larry Hastings2f936352014-08-05 14:04:04 +10001248#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001249 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001250#else
Larry Hastings2f936352014-08-05 14:04:04 +10001251 typedef off_t Py_off_t;
1252#endif
1253
1254static int
1255Py_off_t_converter(PyObject *arg, void *addr)
1256{
1257#ifdef HAVE_LARGEFILE_SUPPORT
1258 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1259#else
1260 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001261#endif
1262 if (PyErr_Occurred())
1263 return 0;
1264 return 1;
1265}
Larry Hastings2f936352014-08-05 14:04:04 +10001266
1267static PyObject *
1268PyLong_FromPy_off_t(Py_off_t offset)
1269{
1270#ifdef HAVE_LARGEFILE_SUPPORT
1271 return PyLong_FromLongLong(offset);
1272#else
1273 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001274#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001275}
1276
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001277#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001278
1279static int
Brian Curtind25aef52011-06-13 15:16:04 -05001280win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001281{
Martin Panter70214ad2016-08-04 02:38:59 +00001282 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1283 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001284 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001285
1286 if (0 == DeviceIoControl(
1287 reparse_point_handle,
1288 FSCTL_GET_REPARSE_POINT,
1289 NULL, 0, /* in buffer */
1290 target_buffer, sizeof(target_buffer),
1291 &n_bytes_returned,
1292 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001293 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001294
1295 if (reparse_tag)
1296 *reparse_tag = rdb->ReparseTag;
1297
Brian Curtind25aef52011-06-13 15:16:04 -05001298 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001299}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001300
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001301#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001302
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001304#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001305/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001306** environ directly, we must obtain it with _NSGetEnviron(). See also
1307** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001308*/
1309#include <crt_externs.h>
1310static char **environ;
1311#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001312extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001313#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001314
Barry Warsaw53699e91996-12-10 23:23:01 +00001315static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001316convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001317{
Victor Stinner8c62be82010-05-06 00:08:46 +00001318 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001319#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001320 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001321#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001322 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001323#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001324
Victor Stinner8c62be82010-05-06 00:08:46 +00001325 d = PyDict_New();
1326 if (d == NULL)
1327 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001328#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001329 if (environ == NULL)
1330 environ = *_NSGetEnviron();
1331#endif
1332#ifdef MS_WINDOWS
1333 /* _wenviron must be initialized in this way if the program is started
1334 through main() instead of wmain(). */
1335 _wgetenv(L"");
1336 if (_wenviron == NULL)
1337 return d;
1338 /* This part ignores errors */
1339 for (e = _wenviron; *e != NULL; e++) {
1340 PyObject *k;
1341 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001342 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001343 if (p == NULL)
1344 continue;
1345 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1346 if (k == NULL) {
1347 PyErr_Clear();
1348 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001349 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001350 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1351 if (v == NULL) {
1352 PyErr_Clear();
1353 Py_DECREF(k);
1354 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001355 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001356 if (PyDict_GetItem(d, k) == NULL) {
1357 if (PyDict_SetItem(d, k, v) != 0)
1358 PyErr_Clear();
1359 }
1360 Py_DECREF(k);
1361 Py_DECREF(v);
1362 }
1363#else
1364 if (environ == NULL)
1365 return d;
1366 /* This part ignores errors */
1367 for (e = environ; *e != NULL; e++) {
1368 PyObject *k;
1369 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001370 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001371 if (p == NULL)
1372 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001373 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001374 if (k == NULL) {
1375 PyErr_Clear();
1376 continue;
1377 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001378 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001379 if (v == NULL) {
1380 PyErr_Clear();
1381 Py_DECREF(k);
1382 continue;
1383 }
1384 if (PyDict_GetItem(d, k) == NULL) {
1385 if (PyDict_SetItem(d, k, v) != 0)
1386 PyErr_Clear();
1387 }
1388 Py_DECREF(k);
1389 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001390 }
1391#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001392 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001393}
1394
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001395/* Set a POSIX-specific error from errno, and return NULL */
1396
Barry Warsawd58d7641998-07-23 16:14:40 +00001397static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001398posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001399{
Victor Stinner8c62be82010-05-06 00:08:46 +00001400 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001401}
Mark Hammondef8b6542001-05-13 08:04:26 +00001402
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001403#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001404static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001405win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001406{
Victor Stinner8c62be82010-05-06 00:08:46 +00001407 /* XXX We should pass the function name along in the future.
1408 (winreg.c also wants to pass the function name.)
1409 This would however require an additional param to the
1410 Windows error object, which is non-trivial.
1411 */
1412 errno = GetLastError();
1413 if (filename)
1414 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1415 else
1416 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001417}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001418
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001419static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001420win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001421{
1422 /* XXX - see win32_error for comments on 'function' */
1423 errno = GetLastError();
1424 if (filename)
1425 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001426 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001427 errno,
1428 filename);
1429 else
1430 return PyErr_SetFromWindowsErr(errno);
1431}
1432
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001433#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001434
Larry Hastings9cf065c2012-06-22 16:30:09 -07001435static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001436path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001437{
1438#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001439 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1440 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001441#else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001442 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001443#endif
1444}
1445
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001446static PyObject *
1447path_object_error2(PyObject *path, PyObject *path2)
1448{
1449#ifdef MS_WINDOWS
1450 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1451 PyExc_OSError, 0, path, path2);
1452#else
1453 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1454#endif
1455}
1456
1457static PyObject *
1458path_error(path_t *path)
1459{
1460 return path_object_error(path->object);
1461}
Larry Hastings31826802013-10-19 00:09:25 -07001462
Larry Hastingsb0827312014-02-09 22:05:19 -08001463static PyObject *
1464path_error2(path_t *path, path_t *path2)
1465{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001466 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001467}
1468
1469
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001470/* POSIX generic methods */
1471
Larry Hastings2f936352014-08-05 14:04:04 +10001472static int
1473fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001474{
Victor Stinner8c62be82010-05-06 00:08:46 +00001475 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001476 int *pointer = (int *)p;
1477 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001478 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001479 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001480 *pointer = fd;
1481 return 1;
1482}
1483
1484static PyObject *
1485posix_fildes_fd(int fd, int (*func)(int))
1486{
1487 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001488 int async_err = 0;
1489
1490 do {
1491 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001492 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001493 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001494 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001495 Py_END_ALLOW_THREADS
1496 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1497 if (res != 0)
1498 return (!async_err) ? posix_error() : NULL;
1499 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001500}
Guido van Rossum21142a01999-01-08 21:05:37 +00001501
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001502
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001503#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001504/* This is a reimplementation of the C library's chdir function,
1505 but one that produces Win32 errors instead of DOS error codes.
1506 chdir is essentially a wrapper around SetCurrentDirectory; however,
1507 it also needs to set "magic" environment variables indicating
1508 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001509static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510win32_wchdir(LPCWSTR path)
1511{
Victor Stinnered537822015-12-13 21:40:26 +01001512 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001513 int result;
1514 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001515
Victor Stinner8c62be82010-05-06 00:08:46 +00001516 if(!SetCurrentDirectoryW(path))
1517 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001518 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001519 if (!result)
1520 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001521 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001522 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001523 if (!new_path) {
1524 SetLastError(ERROR_OUTOFMEMORY);
1525 return FALSE;
1526 }
1527 result = GetCurrentDirectoryW(result, new_path);
1528 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001529 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001530 return FALSE;
1531 }
1532 }
1533 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1534 wcsncmp(new_path, L"//", 2) == 0)
1535 /* UNC path, nothing to do. */
1536 return TRUE;
1537 env[1] = new_path[0];
1538 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001539 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001540 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001541 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001542}
1543#endif
1544
Martin v. Löwis14694662006-02-03 12:54:16 +00001545#ifdef MS_WINDOWS
1546/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1547 - time stamps are restricted to second resolution
1548 - file modification times suffer from forth-and-back conversions between
1549 UTC and local time
1550 Therefore, we implement our own stat, based on the Win32 API directly.
1551*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001552#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001553#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001554
Victor Stinner6036e442015-03-08 01:58:04 +01001555static void
Steve Dowercc16be82016-09-08 10:35:16 -07001556find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1557 BY_HANDLE_FILE_INFORMATION *info,
1558 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001559{
1560 memset(info, 0, sizeof(*info));
1561 info->dwFileAttributes = pFileData->dwFileAttributes;
1562 info->ftCreationTime = pFileData->ftCreationTime;
1563 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1564 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1565 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1566 info->nFileSizeLow = pFileData->nFileSizeLow;
1567/* info->nNumberOfLinks = 1; */
1568 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1569 *reparse_tag = pFileData->dwReserved0;
1570 else
1571 *reparse_tag = 0;
1572}
1573
Guido van Rossumd8faa362007-04-27 19:54:29 +00001574static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001575attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001576{
Victor Stinner8c62be82010-05-06 00:08:46 +00001577 HANDLE hFindFile;
1578 WIN32_FIND_DATAW FileData;
1579 hFindFile = FindFirstFileW(pszFile, &FileData);
1580 if (hFindFile == INVALID_HANDLE_VALUE)
1581 return FALSE;
1582 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001583 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001584 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001585}
1586
Brian Curtind25aef52011-06-13 15:16:04 -05001587static BOOL
1588get_target_path(HANDLE hdl, wchar_t **target_path)
1589{
1590 int buf_size, result_length;
1591 wchar_t *buf;
1592
1593 /* We have a good handle to the target, use it to determine
1594 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001595 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1596 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001597 if(!buf_size)
1598 return FALSE;
1599
Victor Stinnerc36674a2016-03-16 14:30:16 +01001600 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001601 if (!buf) {
1602 SetLastError(ERROR_OUTOFMEMORY);
1603 return FALSE;
1604 }
1605
Steve Dower2ea51c92015-03-20 21:49:12 -07001606 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001607 buf, buf_size, VOLUME_NAME_DOS);
1608
1609 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001610 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001611 return FALSE;
1612 }
1613
1614 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001615 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001616 return FALSE;
1617 }
1618
1619 buf[result_length] = 0;
1620
1621 *target_path = buf;
1622 return TRUE;
1623}
1624
1625static int
Steve Dowercc16be82016-09-08 10:35:16 -07001626win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001627 BOOL traverse)
1628{
Victor Stinner26de69d2011-06-17 15:15:38 +02001629 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001630 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001631 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001632 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001633 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001634 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001635
Steve Dowercc16be82016-09-08 10:35:16 -07001636 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001637 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001638 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001639 0, /* share mode */
1640 NULL, /* security attributes */
1641 OPEN_EXISTING,
1642 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001643 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1644 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001645 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001646 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1647 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001648 NULL);
1649
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001650 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001651 /* Either the target doesn't exist, or we don't have access to
1652 get a handle to it. If the former, we need to return an error.
1653 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001654 DWORD lastError = GetLastError();
1655 if (lastError != ERROR_ACCESS_DENIED &&
1656 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001657 return -1;
1658 /* Could not get attributes on open file. Fall back to
1659 reading the directory. */
1660 if (!attributes_from_dir(path, &info, &reparse_tag))
1661 /* Very strange. This should not fail now */
1662 return -1;
1663 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1664 if (traverse) {
1665 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001666 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001667 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001668 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001669 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001670 } else {
1671 if (!GetFileInformationByHandle(hFile, &info)) {
1672 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001673 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001674 }
1675 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001676 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1677 return -1;
1678
1679 /* Close the outer open file handle now that we're about to
1680 reopen it with different flags. */
1681 if (!CloseHandle(hFile))
1682 return -1;
1683
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001684 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001685 /* In order to call GetFinalPathNameByHandle we need to open
1686 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001687 hFile2 = CreateFileW(
1688 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1689 NULL, OPEN_EXISTING,
1690 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1691 NULL);
1692 if (hFile2 == INVALID_HANDLE_VALUE)
1693 return -1;
1694
1695 if (!get_target_path(hFile2, &target_path))
1696 return -1;
1697
Steve Dowercc16be82016-09-08 10:35:16 -07001698 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001699 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001700 return code;
1701 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001702 } else
1703 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001704 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001705 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001706
1707 /* Set S_IEXEC if it is an .exe, .bat, ... */
1708 dot = wcsrchr(path, '.');
1709 if (dot) {
1710 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1711 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1712 result->st_mode |= 0111;
1713 }
1714 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001715}
1716
1717static int
Steve Dowercc16be82016-09-08 10:35:16 -07001718win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001719{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001720 /* Protocol violation: we explicitly clear errno, instead of
1721 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001722 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001723 errno = 0;
1724 return code;
1725}
Brian Curtind25aef52011-06-13 15:16:04 -05001726/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001727
1728 In Posix, stat automatically traverses symlinks and returns the stat
1729 structure for the target. In Windows, the equivalent GetFileAttributes by
1730 default does not traverse symlinks and instead returns attributes for
1731 the symlink.
1732
1733 Therefore, win32_lstat will get the attributes traditionally, and
1734 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001735 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001736
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001737static int
Steve Dowercc16be82016-09-08 10:35:16 -07001738win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001739{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001740 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001741}
1742
Victor Stinner8c62be82010-05-06 00:08:46 +00001743static int
Steve Dowercc16be82016-09-08 10:35:16 -07001744win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001745{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001746 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001747}
1748
Martin v. Löwis14694662006-02-03 12:54:16 +00001749#endif /* MS_WINDOWS */
1750
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001751PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001752"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001753This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001754 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001755or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1756\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001757Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1758or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001759\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001760See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001761
1762static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001763 {"st_mode", "protection bits"},
1764 {"st_ino", "inode"},
1765 {"st_dev", "device"},
1766 {"st_nlink", "number of hard links"},
1767 {"st_uid", "user ID of owner"},
1768 {"st_gid", "group ID of owner"},
1769 {"st_size", "total size, in bytes"},
1770 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1771 {NULL, "integer time of last access"},
1772 {NULL, "integer time of last modification"},
1773 {NULL, "integer time of last change"},
1774 {"st_atime", "time of last access"},
1775 {"st_mtime", "time of last modification"},
1776 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001777 {"st_atime_ns", "time of last access in nanoseconds"},
1778 {"st_mtime_ns", "time of last modification in nanoseconds"},
1779 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001780#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001781 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001782#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001783#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001784 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001785#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001786#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001787 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001788#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001789#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001790 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001791#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001792#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001793 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001794#endif
1795#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001796 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001797#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001798#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1799 {"st_file_attributes", "Windows file attribute bits"},
1800#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001801 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001802};
1803
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001804#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001805#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001806#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001807#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001808#endif
1809
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001810#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001811#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1812#else
1813#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1814#endif
1815
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001816#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001817#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1818#else
1819#define ST_RDEV_IDX ST_BLOCKS_IDX
1820#endif
1821
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001822#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1823#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1824#else
1825#define ST_FLAGS_IDX ST_RDEV_IDX
1826#endif
1827
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001828#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001829#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001830#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001831#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001832#endif
1833
1834#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1835#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1836#else
1837#define ST_BIRTHTIME_IDX ST_GEN_IDX
1838#endif
1839
Zachary Ware63f277b2014-06-19 09:46:37 -05001840#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1841#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1842#else
1843#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1844#endif
1845
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001846static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001847 "stat_result", /* name */
1848 stat_result__doc__, /* doc */
1849 stat_result_fields,
1850 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001851};
1852
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001853PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001854"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1855This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001856 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001857or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001858\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001859See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001860
1861static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001862 {"f_bsize", },
1863 {"f_frsize", },
1864 {"f_blocks", },
1865 {"f_bfree", },
1866 {"f_bavail", },
1867 {"f_files", },
1868 {"f_ffree", },
1869 {"f_favail", },
1870 {"f_flag", },
1871 {"f_namemax",},
1872 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001873};
1874
1875static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001876 "statvfs_result", /* name */
1877 statvfs_result__doc__, /* doc */
1878 statvfs_result_fields,
1879 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001880};
1881
Ross Lagerwall7807c352011-03-17 20:20:30 +02001882#if defined(HAVE_WAITID) && !defined(__APPLE__)
1883PyDoc_STRVAR(waitid_result__doc__,
1884"waitid_result: Result from waitid.\n\n\
1885This object may be accessed either as a tuple of\n\
1886 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1887or via the attributes si_pid, si_uid, and so on.\n\
1888\n\
1889See os.waitid for more information.");
1890
1891static PyStructSequence_Field waitid_result_fields[] = {
1892 {"si_pid", },
1893 {"si_uid", },
1894 {"si_signo", },
1895 {"si_status", },
1896 {"si_code", },
1897 {0}
1898};
1899
1900static PyStructSequence_Desc waitid_result_desc = {
1901 "waitid_result", /* name */
1902 waitid_result__doc__, /* doc */
1903 waitid_result_fields,
1904 5
1905};
1906static PyTypeObject WaitidResultType;
1907#endif
1908
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001909static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001910static PyTypeObject StatResultType;
1911static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001912#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001913static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001914#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001915static newfunc structseq_new;
1916
1917static PyObject *
1918statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1919{
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 PyStructSequence *result;
1921 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001922
Victor Stinner8c62be82010-05-06 00:08:46 +00001923 result = (PyStructSequence*)structseq_new(type, args, kwds);
1924 if (!result)
1925 return NULL;
1926 /* If we have been initialized from a tuple,
1927 st_?time might be set to None. Initialize it
1928 from the int slots. */
1929 for (i = 7; i <= 9; i++) {
1930 if (result->ob_item[i+3] == Py_None) {
1931 Py_DECREF(Py_None);
1932 Py_INCREF(result->ob_item[i]);
1933 result->ob_item[i+3] = result->ob_item[i];
1934 }
1935 }
1936 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001937}
1938
1939
1940
1941/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001942static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001943
1944PyDoc_STRVAR(stat_float_times__doc__,
1945"stat_float_times([newval]) -> oldval\n\n\
1946Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001947\n\
1948If value is True, future calls to stat() return floats; if it is False,\n\
1949future calls return ints.\n\
1950If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001951
Larry Hastings2f936352014-08-05 14:04:04 +10001952/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001953static PyObject*
1954stat_float_times(PyObject* self, PyObject *args)
1955{
Victor Stinner8c62be82010-05-06 00:08:46 +00001956 int newval = -1;
1957 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1958 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001959 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1960 "stat_float_times() is deprecated",
1961 1))
1962 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001963 if (newval == -1)
1964 /* Return old value */
1965 return PyBool_FromLong(_stat_float_times);
1966 _stat_float_times = newval;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001967 Py_RETURN_NONE;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001968}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001969
Larry Hastings6fe20b32012-04-19 15:07:49 -07001970static PyObject *billion = NULL;
1971
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001972static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001973fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001974{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001975 PyObject *s = _PyLong_FromTime_t(sec);
1976 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1977 PyObject *s_in_ns = NULL;
1978 PyObject *ns_total = NULL;
1979 PyObject *float_s = NULL;
1980
1981 if (!(s && ns_fractional))
1982 goto exit;
1983
1984 s_in_ns = PyNumber_Multiply(s, billion);
1985 if (!s_in_ns)
1986 goto exit;
1987
1988 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1989 if (!ns_total)
1990 goto exit;
1991
Victor Stinner4195b5c2012-02-08 23:03:19 +01001992 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001993 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1994 if (!float_s)
1995 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001996 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001997 else {
1998 float_s = s;
1999 Py_INCREF(float_s);
2000 }
2001
2002 PyStructSequence_SET_ITEM(v, index, s);
2003 PyStructSequence_SET_ITEM(v, index+3, float_s);
2004 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2005 s = NULL;
2006 float_s = NULL;
2007 ns_total = NULL;
2008exit:
2009 Py_XDECREF(s);
2010 Py_XDECREF(ns_fractional);
2011 Py_XDECREF(s_in_ns);
2012 Py_XDECREF(ns_total);
2013 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002014}
2015
Tim Peters5aa91602002-01-30 05:46:57 +00002016/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002017 (used by posix_stat() and posix_fstat()) */
2018static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002019_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002020{
Victor Stinner8c62be82010-05-06 00:08:46 +00002021 unsigned long ansec, mnsec, cnsec;
2022 PyObject *v = PyStructSequence_New(&StatResultType);
2023 if (v == NULL)
2024 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002025
Victor Stinner8c62be82010-05-06 00:08:46 +00002026 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002027 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002028 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002029#ifdef MS_WINDOWS
2030 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002031#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002032 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002033#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002035#if defined(MS_WINDOWS)
2036 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2037 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2038#else
2039 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2040 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2041#endif
xdegaye50e86032017-05-22 11:15:08 +02002042 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2043 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002044
Martin v. Löwis14694662006-02-03 12:54:16 +00002045#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002046 ansec = st->st_atim.tv_nsec;
2047 mnsec = st->st_mtim.tv_nsec;
2048 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002049#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 ansec = st->st_atimespec.tv_nsec;
2051 mnsec = st->st_mtimespec.tv_nsec;
2052 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002053#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002054 ansec = st->st_atime_nsec;
2055 mnsec = st->st_mtime_nsec;
2056 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002057#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002058 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002059#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002060 fill_time(v, 7, st->st_atime, ansec);
2061 fill_time(v, 8, st->st_mtime, mnsec);
2062 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002063
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002064#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002065 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2066 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002067#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002068#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2070 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002071#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002072#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002073 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2074 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002075#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002076#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2078 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002079#endif
2080#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002081 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002082 PyObject *val;
2083 unsigned long bsec,bnsec;
2084 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002085#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002086 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002087#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002088 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002089#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002090 if (_stat_float_times) {
2091 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2092 } else {
2093 val = PyLong_FromLong((long)bsec);
2094 }
2095 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2096 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002097 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002098#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002099#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2101 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002102#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002103#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2104 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2105 PyLong_FromUnsignedLong(st->st_file_attributes));
2106#endif
Fred Drake699f3522000-06-29 21:12:41 +00002107
Victor Stinner8c62be82010-05-06 00:08:46 +00002108 if (PyErr_Occurred()) {
2109 Py_DECREF(v);
2110 return NULL;
2111 }
Fred Drake699f3522000-06-29 21:12:41 +00002112
Victor Stinner8c62be82010-05-06 00:08:46 +00002113 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002114}
2115
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002116/* POSIX methods */
2117
Guido van Rossum94f6f721999-01-06 18:42:14 +00002118
2119static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002120posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002121 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002122{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002123 STRUCT_STAT st;
2124 int result;
2125
2126#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2127 if (follow_symlinks_specified(function_name, follow_symlinks))
2128 return NULL;
2129#endif
2130
2131 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2132 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2133 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2134 return NULL;
2135
2136 Py_BEGIN_ALLOW_THREADS
2137 if (path->fd != -1)
2138 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002139#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002140 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002141 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002142 else
Steve Dowercc16be82016-09-08 10:35:16 -07002143 result = win32_lstat(path->wide, &st);
2144#else
2145 else
2146#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002147 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2148 result = LSTAT(path->narrow, &st);
2149 else
Steve Dowercc16be82016-09-08 10:35:16 -07002150#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002151#ifdef HAVE_FSTATAT
2152 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2153 result = fstatat(dir_fd, path->narrow, &st,
2154 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2155 else
Steve Dowercc16be82016-09-08 10:35:16 -07002156#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002157 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002158#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002159 Py_END_ALLOW_THREADS
2160
Victor Stinner292c8352012-10-30 02:17:38 +01002161 if (result != 0) {
2162 return path_error(path);
2163 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002164
2165 return _pystat_fromstructstat(&st);
2166}
2167
Larry Hastings2f936352014-08-05 14:04:04 +10002168/*[python input]
2169
2170for s in """
2171
2172FACCESSAT
2173FCHMODAT
2174FCHOWNAT
2175FSTATAT
2176LINKAT
2177MKDIRAT
2178MKFIFOAT
2179MKNODAT
2180OPENAT
2181READLINKAT
2182SYMLINKAT
2183UNLINKAT
2184
2185""".strip().split():
2186 s = s.strip()
2187 print("""
2188#ifdef HAVE_{s}
2189 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002190#else
Larry Hastings2f936352014-08-05 14:04:04 +10002191 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002192#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002193""".rstrip().format(s=s))
2194
2195for s in """
2196
2197FCHDIR
2198FCHMOD
2199FCHOWN
2200FDOPENDIR
2201FEXECVE
2202FPATHCONF
2203FSTATVFS
2204FTRUNCATE
2205
2206""".strip().split():
2207 s = s.strip()
2208 print("""
2209#ifdef HAVE_{s}
2210 #define PATH_HAVE_{s} 1
2211#else
2212 #define PATH_HAVE_{s} 0
2213#endif
2214
2215""".rstrip().format(s=s))
2216[python start generated code]*/
2217
2218#ifdef HAVE_FACCESSAT
2219 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2220#else
2221 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2222#endif
2223
2224#ifdef HAVE_FCHMODAT
2225 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2226#else
2227 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2228#endif
2229
2230#ifdef HAVE_FCHOWNAT
2231 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2232#else
2233 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2234#endif
2235
2236#ifdef HAVE_FSTATAT
2237 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2238#else
2239 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2240#endif
2241
2242#ifdef HAVE_LINKAT
2243 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2244#else
2245 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2246#endif
2247
2248#ifdef HAVE_MKDIRAT
2249 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2250#else
2251 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2252#endif
2253
2254#ifdef HAVE_MKFIFOAT
2255 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2256#else
2257 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2258#endif
2259
2260#ifdef HAVE_MKNODAT
2261 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2262#else
2263 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2264#endif
2265
2266#ifdef HAVE_OPENAT
2267 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2268#else
2269 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2270#endif
2271
2272#ifdef HAVE_READLINKAT
2273 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2274#else
2275 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2276#endif
2277
2278#ifdef HAVE_SYMLINKAT
2279 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2280#else
2281 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2282#endif
2283
2284#ifdef HAVE_UNLINKAT
2285 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2286#else
2287 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2288#endif
2289
2290#ifdef HAVE_FCHDIR
2291 #define PATH_HAVE_FCHDIR 1
2292#else
2293 #define PATH_HAVE_FCHDIR 0
2294#endif
2295
2296#ifdef HAVE_FCHMOD
2297 #define PATH_HAVE_FCHMOD 1
2298#else
2299 #define PATH_HAVE_FCHMOD 0
2300#endif
2301
2302#ifdef HAVE_FCHOWN
2303 #define PATH_HAVE_FCHOWN 1
2304#else
2305 #define PATH_HAVE_FCHOWN 0
2306#endif
2307
2308#ifdef HAVE_FDOPENDIR
2309 #define PATH_HAVE_FDOPENDIR 1
2310#else
2311 #define PATH_HAVE_FDOPENDIR 0
2312#endif
2313
2314#ifdef HAVE_FEXECVE
2315 #define PATH_HAVE_FEXECVE 1
2316#else
2317 #define PATH_HAVE_FEXECVE 0
2318#endif
2319
2320#ifdef HAVE_FPATHCONF
2321 #define PATH_HAVE_FPATHCONF 1
2322#else
2323 #define PATH_HAVE_FPATHCONF 0
2324#endif
2325
2326#ifdef HAVE_FSTATVFS
2327 #define PATH_HAVE_FSTATVFS 1
2328#else
2329 #define PATH_HAVE_FSTATVFS 0
2330#endif
2331
2332#ifdef HAVE_FTRUNCATE
2333 #define PATH_HAVE_FTRUNCATE 1
2334#else
2335 #define PATH_HAVE_FTRUNCATE 0
2336#endif
2337/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002338
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002339#ifdef MS_WINDOWS
2340 #undef PATH_HAVE_FTRUNCATE
2341 #define PATH_HAVE_FTRUNCATE 1
2342#endif
Larry Hastings31826802013-10-19 00:09:25 -07002343
Larry Hastings61272b72014-01-07 12:41:53 -08002344/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002345
2346class path_t_converter(CConverter):
2347
2348 type = "path_t"
2349 impl_by_reference = True
2350 parse_by_reference = True
2351
2352 converter = 'path_converter'
2353
2354 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002355 # right now path_t doesn't support default values.
2356 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002357 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002358 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002359
Larry Hastings2f936352014-08-05 14:04:04 +10002360 if self.c_default not in (None, 'Py_None'):
2361 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002362
2363 self.nullable = nullable
2364 self.allow_fd = allow_fd
2365
Larry Hastings7726ac92014-01-31 22:03:12 -08002366 def pre_render(self):
2367 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002368 if isinstance(value, str):
2369 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002370 return str(int(bool(value)))
2371
2372 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002373 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002374 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002375 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002376 strify(self.nullable),
2377 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002378 )
2379
2380 def cleanup(self):
2381 return "path_cleanup(&" + self.name + ");\n"
2382
2383
2384class dir_fd_converter(CConverter):
2385 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002386
Larry Hastings2f936352014-08-05 14:04:04 +10002387 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002388 if self.default in (unspecified, None):
2389 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002390 if isinstance(requires, str):
2391 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2392 else:
2393 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002394
Larry Hastings2f936352014-08-05 14:04:04 +10002395class fildes_converter(CConverter):
2396 type = 'int'
2397 converter = 'fildes_converter'
2398
2399class uid_t_converter(CConverter):
2400 type = "uid_t"
2401 converter = '_Py_Uid_Converter'
2402
2403class gid_t_converter(CConverter):
2404 type = "gid_t"
2405 converter = '_Py_Gid_Converter'
2406
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002407class dev_t_converter(CConverter):
2408 type = 'dev_t'
2409 converter = '_Py_Dev_Converter'
2410
2411class dev_t_return_converter(unsigned_long_return_converter):
2412 type = 'dev_t'
2413 conversion_fn = '_PyLong_FromDev'
2414 unsigned_cast = '(dev_t)'
2415
Larry Hastings2f936352014-08-05 14:04:04 +10002416class FSConverter_converter(CConverter):
2417 type = 'PyObject *'
2418 converter = 'PyUnicode_FSConverter'
2419 def converter_init(self):
2420 if self.default is not unspecified:
2421 fail("FSConverter_converter does not support default values")
2422 self.c_default = 'NULL'
2423
2424 def cleanup(self):
2425 return "Py_XDECREF(" + self.name + ");\n"
2426
2427class pid_t_converter(CConverter):
2428 type = 'pid_t'
2429 format_unit = '" _Py_PARSE_PID "'
2430
2431class idtype_t_converter(int_converter):
2432 type = 'idtype_t'
2433
2434class id_t_converter(CConverter):
2435 type = 'id_t'
2436 format_unit = '" _Py_PARSE_PID "'
2437
Benjamin Petersonca470632016-09-06 13:47:26 -07002438class intptr_t_converter(CConverter):
2439 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002440 format_unit = '" _Py_PARSE_INTPTR "'
2441
2442class Py_off_t_converter(CConverter):
2443 type = 'Py_off_t'
2444 converter = 'Py_off_t_converter'
2445
2446class Py_off_t_return_converter(long_return_converter):
2447 type = 'Py_off_t'
2448 conversion_fn = 'PyLong_FromPy_off_t'
2449
2450class path_confname_converter(CConverter):
2451 type="int"
2452 converter="conv_path_confname"
2453
2454class confstr_confname_converter(path_confname_converter):
2455 converter='conv_confstr_confname'
2456
2457class sysconf_confname_converter(path_confname_converter):
2458 converter="conv_sysconf_confname"
2459
2460class sched_param_converter(CConverter):
2461 type = 'struct sched_param'
2462 converter = 'convert_sched_param'
2463 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002464
Larry Hastings61272b72014-01-07 12:41:53 -08002465[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002466/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002467
Larry Hastings61272b72014-01-07 12:41:53 -08002468/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002469
Larry Hastings2a727912014-01-16 11:32:01 -08002470os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002471
2472 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002473 Path to be examined; can be string, bytes, path-like object or
2474 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002475
2476 *
2477
Larry Hastings2f936352014-08-05 14:04:04 +10002478 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002479 If not None, it should be a file descriptor open to a directory,
2480 and path should be a relative string; path will then be relative to
2481 that directory.
2482
2483 follow_symlinks: bool = True
2484 If False, and the last element of the path is a symbolic link,
2485 stat will examine the symbolic link itself instead of the file
2486 the link points to.
2487
2488Perform a stat system call on the given path.
2489
2490dir_fd and follow_symlinks may not be implemented
2491 on your platform. If they are unavailable, using them will raise a
2492 NotImplementedError.
2493
2494It's an error to use dir_fd or follow_symlinks when specifying path as
2495 an open file descriptor.
2496
Larry Hastings61272b72014-01-07 12:41:53 -08002497[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002498
Larry Hastings31826802013-10-19 00:09:25 -07002499static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002500os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002501/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002502{
2503 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2504}
2505
Larry Hastings2f936352014-08-05 14:04:04 +10002506
2507/*[clinic input]
2508os.lstat
2509
2510 path : path_t
2511
2512 *
2513
2514 dir_fd : dir_fd(requires='fstatat') = None
2515
2516Perform a stat system call on the given path, without following symbolic links.
2517
2518Like stat(), but do not follow symbolic links.
2519Equivalent to stat(path, follow_symlinks=False).
2520[clinic start generated code]*/
2521
Larry Hastings2f936352014-08-05 14:04:04 +10002522static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002523os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2524/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002525{
2526 int follow_symlinks = 0;
2527 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2528}
Larry Hastings31826802013-10-19 00:09:25 -07002529
Larry Hastings2f936352014-08-05 14:04:04 +10002530
Larry Hastings61272b72014-01-07 12:41:53 -08002531/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002532os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002533
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002534 path: path_t
2535 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002536
2537 mode: int
2538 Operating-system mode bitfield. Can be F_OK to test existence,
2539 or the inclusive-OR of R_OK, W_OK, and X_OK.
2540
2541 *
2542
Larry Hastings2f936352014-08-05 14:04:04 +10002543 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002544 If not None, it should be a file descriptor open to a directory,
2545 and path should be relative; path will then be relative to that
2546 directory.
2547
2548 effective_ids: bool = False
2549 If True, access will use the effective uid/gid instead of
2550 the real uid/gid.
2551
2552 follow_symlinks: bool = True
2553 If False, and the last element of the path is a symbolic link,
2554 access will examine the symbolic link itself instead of the file
2555 the link points to.
2556
2557Use the real uid/gid to test for access to a path.
2558
2559{parameters}
2560dir_fd, effective_ids, and follow_symlinks may not be implemented
2561 on your platform. If they are unavailable, using them will raise a
2562 NotImplementedError.
2563
2564Note that most operations will use the effective uid/gid, therefore this
2565 routine can be used in a suid/sgid environment to test if the invoking user
2566 has the specified access to the path.
2567
Larry Hastings61272b72014-01-07 12:41:53 -08002568[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002569
Larry Hastings2f936352014-08-05 14:04:04 +10002570static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002571os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002572 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002573/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002574{
Larry Hastings2f936352014-08-05 14:04:04 +10002575 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002576
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002577#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002578 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002579#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002580 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002581#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002582
Larry Hastings9cf065c2012-06-22 16:30:09 -07002583#ifndef HAVE_FACCESSAT
2584 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002585 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002586
2587 if (effective_ids) {
2588 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002589 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002590 }
2591#endif
2592
2593#ifdef MS_WINDOWS
2594 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002595 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002596 Py_END_ALLOW_THREADS
2597
2598 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002599 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002600 * * we didn't get a -1, and
2601 * * write access wasn't requested,
2602 * * or the file isn't read-only,
2603 * * or it's a directory.
2604 * (Directories cannot be read-only on Windows.)
2605 */
Larry Hastings2f936352014-08-05 14:04:04 +10002606 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002607 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002608 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002609 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002610#else
2611
2612 Py_BEGIN_ALLOW_THREADS
2613#ifdef HAVE_FACCESSAT
2614 if ((dir_fd != DEFAULT_DIR_FD) ||
2615 effective_ids ||
2616 !follow_symlinks) {
2617 int flags = 0;
2618 if (!follow_symlinks)
2619 flags |= AT_SYMLINK_NOFOLLOW;
2620 if (effective_ids)
2621 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002622 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002623 }
2624 else
2625#endif
Larry Hastings31826802013-10-19 00:09:25 -07002626 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002627 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002628 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002629#endif
2630
Larry Hastings9cf065c2012-06-22 16:30:09 -07002631 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002632}
2633
Guido van Rossumd371ff11999-01-25 16:12:23 +00002634#ifndef F_OK
2635#define F_OK 0
2636#endif
2637#ifndef R_OK
2638#define R_OK 4
2639#endif
2640#ifndef W_OK
2641#define W_OK 2
2642#endif
2643#ifndef X_OK
2644#define X_OK 1
2645#endif
2646
Larry Hastings31826802013-10-19 00:09:25 -07002647
Guido van Rossumd371ff11999-01-25 16:12:23 +00002648#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002649/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002650os.ttyname -> DecodeFSDefault
2651
2652 fd: int
2653 Integer file descriptor handle.
2654
2655 /
2656
2657Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002658[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002659
Larry Hastings31826802013-10-19 00:09:25 -07002660static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002661os_ttyname_impl(PyObject *module, int fd)
2662/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002663{
2664 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002665
Larry Hastings31826802013-10-19 00:09:25 -07002666 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002667 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002668 posix_error();
2669 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002670}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002671#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002672
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002673#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002674/*[clinic input]
2675os.ctermid
2676
2677Return the name of the controlling terminal for this process.
2678[clinic start generated code]*/
2679
Larry Hastings2f936352014-08-05 14:04:04 +10002680static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002681os_ctermid_impl(PyObject *module)
2682/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002683{
Victor Stinner8c62be82010-05-06 00:08:46 +00002684 char *ret;
2685 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002686
Greg Wardb48bc172000-03-01 21:51:56 +00002687#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002688 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002689#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002690 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002691#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002692 if (ret == NULL)
2693 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002694 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002695}
Larry Hastings2f936352014-08-05 14:04:04 +10002696#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002697
Larry Hastings2f936352014-08-05 14:04:04 +10002698
2699/*[clinic input]
2700os.chdir
2701
2702 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2703
2704Change the current working directory to the specified path.
2705
2706path may always be specified as a string.
2707On some platforms, path may also be specified as an open file descriptor.
2708 If this functionality is unavailable, using it raises an exception.
2709[clinic start generated code]*/
2710
Larry Hastings2f936352014-08-05 14:04:04 +10002711static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002712os_chdir_impl(PyObject *module, path_t *path)
2713/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002714{
2715 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002716
2717 Py_BEGIN_ALLOW_THREADS
2718#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002719 /* on unix, success = 0, on windows, success = !0 */
2720 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002721#else
2722#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002723 if (path->fd != -1)
2724 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002725 else
2726#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002727 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002728#endif
2729 Py_END_ALLOW_THREADS
2730
2731 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002732 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002733 }
2734
Larry Hastings2f936352014-08-05 14:04:04 +10002735 Py_RETURN_NONE;
2736}
2737
2738
2739#ifdef HAVE_FCHDIR
2740/*[clinic input]
2741os.fchdir
2742
2743 fd: fildes
2744
2745Change to the directory of the given file descriptor.
2746
2747fd must be opened on a directory, not a file.
2748Equivalent to os.chdir(fd).
2749
2750[clinic start generated code]*/
2751
Fred Drake4d1e64b2002-04-15 19:40:07 +00002752static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002753os_fchdir_impl(PyObject *module, int fd)
2754/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002755{
Larry Hastings2f936352014-08-05 14:04:04 +10002756 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002757}
2758#endif /* HAVE_FCHDIR */
2759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002760
Larry Hastings2f936352014-08-05 14:04:04 +10002761/*[clinic input]
2762os.chmod
2763
2764 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2765 Path to be modified. May always be specified as a str or bytes.
2766 On some platforms, path may also be specified as an open file descriptor.
2767 If this functionality is unavailable, using it raises an exception.
2768
2769 mode: int
2770 Operating-system mode bitfield.
2771
2772 *
2773
2774 dir_fd : dir_fd(requires='fchmodat') = None
2775 If not None, it should be a file descriptor open to a directory,
2776 and path should be relative; path will then be relative to that
2777 directory.
2778
2779 follow_symlinks: bool = True
2780 If False, and the last element of the path is a symbolic link,
2781 chmod will modify the symbolic link itself instead of the file
2782 the link points to.
2783
2784Change the access permissions of a file.
2785
2786It is an error to use dir_fd or follow_symlinks when specifying path as
2787 an open file descriptor.
2788dir_fd and follow_symlinks may not be implemented on your platform.
2789 If they are unavailable, using them will raise a NotImplementedError.
2790
2791[clinic start generated code]*/
2792
Larry Hastings2f936352014-08-05 14:04:04 +10002793static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002794os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002795 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002796/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002797{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002800#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002801 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002802#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002803
Larry Hastings9cf065c2012-06-22 16:30:09 -07002804#ifdef HAVE_FCHMODAT
2805 int fchmodat_nofollow_unsupported = 0;
2806#endif
2807
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2809 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002810 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811#endif
2812
2813#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002814 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002815 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002816 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002817 result = 0;
2818 else {
2819 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002820 attr &= ~FILE_ATTRIBUTE_READONLY;
2821 else
2822 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002823 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 }
2825 Py_END_ALLOW_THREADS
2826
2827 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002828 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829 }
2830#else /* MS_WINDOWS */
2831 Py_BEGIN_ALLOW_THREADS
2832#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002833 if (path->fd != -1)
2834 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835 else
2836#endif
2837#ifdef HAVE_LCHMOD
2838 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002839 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002840 else
2841#endif
2842#ifdef HAVE_FCHMODAT
2843 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2844 /*
2845 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2846 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002847 * and then says it isn't implemented yet.
2848 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002849 *
2850 * Once it is supported, os.chmod will automatically
2851 * support dir_fd and follow_symlinks=False. (Hopefully.)
2852 * Until then, we need to be careful what exception we raise.
2853 */
Larry Hastings2f936352014-08-05 14:04:04 +10002854 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2856 /*
2857 * But wait! We can't throw the exception without allowing threads,
2858 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2859 */
2860 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002861 result &&
2862 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2863 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002864 }
2865 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002866#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002867 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002868 Py_END_ALLOW_THREADS
2869
2870 if (result) {
2871#ifdef HAVE_FCHMODAT
2872 if (fchmodat_nofollow_unsupported) {
2873 if (dir_fd != DEFAULT_DIR_FD)
2874 dir_fd_and_follow_symlinks_invalid("chmod",
2875 dir_fd, follow_symlinks);
2876 else
2877 follow_symlinks_specified("chmod", follow_symlinks);
2878 }
2879 else
2880#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002881 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002882 }
2883#endif
2884
Larry Hastings2f936352014-08-05 14:04:04 +10002885 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002886}
2887
Larry Hastings9cf065c2012-06-22 16:30:09 -07002888
Christian Heimes4e30a842007-11-30 22:12:06 +00002889#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002890/*[clinic input]
2891os.fchmod
2892
2893 fd: int
2894 mode: int
2895
2896Change the access permissions of the file given by file descriptor fd.
2897
2898Equivalent to os.chmod(fd, mode).
2899[clinic start generated code]*/
2900
Larry Hastings2f936352014-08-05 14:04:04 +10002901static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002902os_fchmod_impl(PyObject *module, int fd, int mode)
2903/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002904{
2905 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002906 int async_err = 0;
2907
2908 do {
2909 Py_BEGIN_ALLOW_THREADS
2910 res = fchmod(fd, mode);
2911 Py_END_ALLOW_THREADS
2912 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2913 if (res != 0)
2914 return (!async_err) ? posix_error() : NULL;
2915
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002917}
2918#endif /* HAVE_FCHMOD */
2919
Larry Hastings2f936352014-08-05 14:04:04 +10002920
Christian Heimes4e30a842007-11-30 22:12:06 +00002921#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002922/*[clinic input]
2923os.lchmod
2924
2925 path: path_t
2926 mode: int
2927
2928Change the access permissions of a file, without following symbolic links.
2929
2930If path is a symlink, this affects the link itself rather than the target.
2931Equivalent to chmod(path, mode, follow_symlinks=False)."
2932[clinic start generated code]*/
2933
Larry Hastings2f936352014-08-05 14:04:04 +10002934static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002935os_lchmod_impl(PyObject *module, path_t *path, int mode)
2936/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002937{
Victor Stinner8c62be82010-05-06 00:08:46 +00002938 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002939 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002940 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002941 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002942 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002943 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002944 return NULL;
2945 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002946 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002947}
2948#endif /* HAVE_LCHMOD */
2949
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002950
Thomas Wouterscf297e42007-02-23 15:07:44 +00002951#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002952/*[clinic input]
2953os.chflags
2954
2955 path: path_t
2956 flags: unsigned_long(bitwise=True)
2957 follow_symlinks: bool=True
2958
2959Set file flags.
2960
2961If follow_symlinks is False, and the last element of the path is a symbolic
2962 link, chflags will change flags on the symbolic link itself instead of the
2963 file the link points to.
2964follow_symlinks may not be implemented on your platform. If it is
2965unavailable, using it will raise a NotImplementedError.
2966
2967[clinic start generated code]*/
2968
Larry Hastings2f936352014-08-05 14:04:04 +10002969static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002970os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002971 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002972/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002973{
2974 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002975
2976#ifndef HAVE_LCHFLAGS
2977 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002978 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002979#endif
2980
Victor Stinner8c62be82010-05-06 00:08:46 +00002981 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002982#ifdef HAVE_LCHFLAGS
2983 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002984 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002985 else
2986#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002987 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002988 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002989
Larry Hastings2f936352014-08-05 14:04:04 +10002990 if (result)
2991 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002992
Larry Hastings2f936352014-08-05 14:04:04 +10002993 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002994}
2995#endif /* HAVE_CHFLAGS */
2996
Larry Hastings2f936352014-08-05 14:04:04 +10002997
Thomas Wouterscf297e42007-02-23 15:07:44 +00002998#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002999/*[clinic input]
3000os.lchflags
3001
3002 path: path_t
3003 flags: unsigned_long(bitwise=True)
3004
3005Set file flags.
3006
3007This function will not follow symbolic links.
3008Equivalent to chflags(path, flags, follow_symlinks=False).
3009[clinic start generated code]*/
3010
Larry Hastings2f936352014-08-05 14:04:04 +10003011static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003012os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3013/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003014{
Victor Stinner8c62be82010-05-06 00:08:46 +00003015 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003016 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003017 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003018 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003019 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003020 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003021 }
Victor Stinner292c8352012-10-30 02:17:38 +01003022 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003023}
3024#endif /* HAVE_LCHFLAGS */
3025
Larry Hastings2f936352014-08-05 14:04:04 +10003026
Martin v. Löwis244edc82001-10-04 22:44:26 +00003027#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003028/*[clinic input]
3029os.chroot
3030 path: path_t
3031
3032Change root directory to path.
3033
3034[clinic start generated code]*/
3035
Larry Hastings2f936352014-08-05 14:04:04 +10003036static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003037os_chroot_impl(PyObject *module, path_t *path)
3038/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003039{
3040 int res;
3041 Py_BEGIN_ALLOW_THREADS
3042 res = chroot(path->narrow);
3043 Py_END_ALLOW_THREADS
3044 if (res < 0)
3045 return path_error(path);
3046 Py_RETURN_NONE;
3047}
3048#endif /* HAVE_CHROOT */
3049
Martin v. Löwis244edc82001-10-04 22:44:26 +00003050
Guido van Rossum21142a01999-01-08 21:05:37 +00003051#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003052/*[clinic input]
3053os.fsync
3054
3055 fd: fildes
3056
3057Force write of fd to disk.
3058[clinic start generated code]*/
3059
Larry Hastings2f936352014-08-05 14:04:04 +10003060static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003061os_fsync_impl(PyObject *module, int fd)
3062/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003063{
3064 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003065}
3066#endif /* HAVE_FSYNC */
3067
Larry Hastings2f936352014-08-05 14:04:04 +10003068
Ross Lagerwall7807c352011-03-17 20:20:30 +02003069#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003070/*[clinic input]
3071os.sync
3072
3073Force write of everything to disk.
3074[clinic start generated code]*/
3075
Larry Hastings2f936352014-08-05 14:04:04 +10003076static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003077os_sync_impl(PyObject *module)
3078/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003079{
3080 Py_BEGIN_ALLOW_THREADS
3081 sync();
3082 Py_END_ALLOW_THREADS
3083 Py_RETURN_NONE;
3084}
Larry Hastings2f936352014-08-05 14:04:04 +10003085#endif /* HAVE_SYNC */
3086
Ross Lagerwall7807c352011-03-17 20:20:30 +02003087
Guido van Rossum21142a01999-01-08 21:05:37 +00003088#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003089#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003090extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3091#endif
3092
Larry Hastings2f936352014-08-05 14:04:04 +10003093/*[clinic input]
3094os.fdatasync
3095
3096 fd: fildes
3097
3098Force write of fd to disk without forcing update of metadata.
3099[clinic start generated code]*/
3100
Larry Hastings2f936352014-08-05 14:04:04 +10003101static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003102os_fdatasync_impl(PyObject *module, int fd)
3103/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003104{
3105 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003106}
3107#endif /* HAVE_FDATASYNC */
3108
3109
Fredrik Lundh10723342000-07-10 16:38:09 +00003110#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003111/*[clinic input]
3112os.chown
3113
3114 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3115 Path to be examined; can be string, bytes, or open-file-descriptor int.
3116
3117 uid: uid_t
3118
3119 gid: gid_t
3120
3121 *
3122
3123 dir_fd : dir_fd(requires='fchownat') = None
3124 If not None, it should be a file descriptor open to a directory,
3125 and path should be relative; path will then be relative to that
3126 directory.
3127
3128 follow_symlinks: bool = True
3129 If False, and the last element of the path is a symbolic link,
3130 stat will examine the symbolic link itself instead of the file
3131 the link points to.
3132
3133Change the owner and group id of path to the numeric uid and gid.\
3134
3135path may always be specified as a string.
3136On some platforms, path may also be specified as an open file descriptor.
3137 If this functionality is unavailable, using it raises an exception.
3138If dir_fd is not None, it should be a file descriptor open to a directory,
3139 and path should be relative; path will then be relative to that directory.
3140If follow_symlinks is False, and the last element of the path is a symbolic
3141 link, chown will modify the symbolic link itself instead of the file the
3142 link points to.
3143It is an error to use dir_fd or follow_symlinks when specifying path as
3144 an open file descriptor.
3145dir_fd and follow_symlinks may not be implemented on your platform.
3146 If they are unavailable, using them will raise a NotImplementedError.
3147
3148[clinic start generated code]*/
3149
Larry Hastings2f936352014-08-05 14:04:04 +10003150static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003151os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003152 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003153/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003154{
3155 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003156
3157#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3158 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003159 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003160#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003161 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3162 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3163 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003164
3165#ifdef __APPLE__
3166 /*
3167 * This is for Mac OS X 10.3, which doesn't have lchown.
3168 * (But we still have an lchown symbol because of weak-linking.)
3169 * It doesn't have fchownat either. So there's no possibility
3170 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003171 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003172 if ((!follow_symlinks) && (lchown == NULL)) {
3173 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003174 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003175 }
3176#endif
3177
Victor Stinner8c62be82010-05-06 00:08:46 +00003178 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003179#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003180 if (path->fd != -1)
3181 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003182 else
3183#endif
3184#ifdef HAVE_LCHOWN
3185 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003186 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003187 else
3188#endif
3189#ifdef HAVE_FCHOWNAT
3190 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003191 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3193 else
3194#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003195 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003196 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003197
Larry Hastings2f936352014-08-05 14:04:04 +10003198 if (result)
3199 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003200
Larry Hastings2f936352014-08-05 14:04:04 +10003201 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003202}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003203#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003204
Larry Hastings2f936352014-08-05 14:04:04 +10003205
Christian Heimes4e30a842007-11-30 22:12:06 +00003206#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003207/*[clinic input]
3208os.fchown
3209
3210 fd: int
3211 uid: uid_t
3212 gid: gid_t
3213
3214Change the owner and group id of the file specified by file descriptor.
3215
3216Equivalent to os.chown(fd, uid, gid).
3217
3218[clinic start generated code]*/
3219
Larry Hastings2f936352014-08-05 14:04:04 +10003220static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003221os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3222/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003223{
Victor Stinner8c62be82010-05-06 00:08:46 +00003224 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003225 int async_err = 0;
3226
3227 do {
3228 Py_BEGIN_ALLOW_THREADS
3229 res = fchown(fd, uid, gid);
3230 Py_END_ALLOW_THREADS
3231 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3232 if (res != 0)
3233 return (!async_err) ? posix_error() : NULL;
3234
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003236}
3237#endif /* HAVE_FCHOWN */
3238
Larry Hastings2f936352014-08-05 14:04:04 +10003239
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003240#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003241/*[clinic input]
3242os.lchown
3243
3244 path : path_t
3245 uid: uid_t
3246 gid: gid_t
3247
3248Change the owner and group id of path to the numeric uid and gid.
3249
3250This function will not follow symbolic links.
3251Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3252[clinic start generated code]*/
3253
Larry Hastings2f936352014-08-05 14:04:04 +10003254static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003255os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3256/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003257{
Victor Stinner8c62be82010-05-06 00:08:46 +00003258 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003259 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003260 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003261 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003262 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003263 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003264 }
Larry Hastings2f936352014-08-05 14:04:04 +10003265 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003266}
3267#endif /* HAVE_LCHOWN */
3268
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003269
Barry Warsaw53699e91996-12-10 23:23:01 +00003270static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003271posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003272{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003273 char *buf, *tmpbuf;
3274 char *cwd;
3275 const size_t chunk = 1024;
3276 size_t buflen = 0;
3277 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003278
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003279#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003280 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003281 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003282 wchar_t *wbuf2 = wbuf;
3283 PyObject *resobj;
3284 DWORD len;
3285 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003286 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 /* If the buffer is large enough, len does not include the
3288 terminating \0. If the buffer is too small, len includes
3289 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003290 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003291 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003292 if (wbuf2)
3293 len = GetCurrentDirectoryW(len, wbuf2);
3294 }
3295 Py_END_ALLOW_THREADS
3296 if (!wbuf2) {
3297 PyErr_NoMemory();
3298 return NULL;
3299 }
3300 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003301 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003302 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003303 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003304 }
3305 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003306 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003307 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003308 return resobj;
3309 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003310
3311 if (win32_warn_bytes_api())
3312 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003313#endif
3314
Victor Stinner4403d7d2015-04-25 00:16:10 +02003315 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003316 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003317 do {
3318 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003319#ifdef MS_WINDOWS
3320 if (buflen > INT_MAX) {
3321 PyErr_NoMemory();
3322 break;
3323 }
3324#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003325 tmpbuf = PyMem_RawRealloc(buf, buflen);
3326 if (tmpbuf == NULL)
3327 break;
3328
3329 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003330#ifdef MS_WINDOWS
3331 cwd = getcwd(buf, (int)buflen);
3332#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003333 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003334#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003335 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003336 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003337
3338 if (cwd == NULL) {
3339 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003341 }
3342
Victor Stinner8c62be82010-05-06 00:08:46 +00003343 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003344 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3345 else
3346 obj = PyUnicode_DecodeFSDefault(buf);
3347 PyMem_RawFree(buf);
3348
3349 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003350}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003351
Larry Hastings2f936352014-08-05 14:04:04 +10003352
3353/*[clinic input]
3354os.getcwd
3355
3356Return a unicode string representing the current working directory.
3357[clinic start generated code]*/
3358
Larry Hastings2f936352014-08-05 14:04:04 +10003359static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003360os_getcwd_impl(PyObject *module)
3361/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003362{
3363 return posix_getcwd(0);
3364}
3365
Larry Hastings2f936352014-08-05 14:04:04 +10003366
3367/*[clinic input]
3368os.getcwdb
3369
3370Return a bytes string representing the current working directory.
3371[clinic start generated code]*/
3372
Larry Hastings2f936352014-08-05 14:04:04 +10003373static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003374os_getcwdb_impl(PyObject *module)
3375/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003376{
3377 return posix_getcwd(1);
3378}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003379
Larry Hastings2f936352014-08-05 14:04:04 +10003380
Larry Hastings9cf065c2012-06-22 16:30:09 -07003381#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3382#define HAVE_LINK 1
3383#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003384
Guido van Rossumb6775db1994-08-01 11:34:53 +00003385#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003386/*[clinic input]
3387
3388os.link
3389
3390 src : path_t
3391 dst : path_t
3392 *
3393 src_dir_fd : dir_fd = None
3394 dst_dir_fd : dir_fd = None
3395 follow_symlinks: bool = True
3396
3397Create a hard link to a file.
3398
3399If either src_dir_fd or dst_dir_fd is not None, it should be a file
3400 descriptor open to a directory, and the respective path string (src or dst)
3401 should be relative; the path will then be relative to that directory.
3402If follow_symlinks is False, and the last element of src is a symbolic
3403 link, link will create a link to the symbolic link itself instead of the
3404 file the link points to.
3405src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3406 platform. If they are unavailable, using them will raise a
3407 NotImplementedError.
3408[clinic start generated code]*/
3409
Larry Hastings2f936352014-08-05 14:04:04 +10003410static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003411os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003412 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003413/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003414{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003415#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003416 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003417#else
3418 int result;
3419#endif
3420
Larry Hastings9cf065c2012-06-22 16:30:09 -07003421#ifndef HAVE_LINKAT
3422 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3423 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003424 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425 }
3426#endif
3427
Steve Dowercc16be82016-09-08 10:35:16 -07003428#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003429 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003430 PyErr_SetString(PyExc_NotImplementedError,
3431 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003432 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003433 }
Steve Dowercc16be82016-09-08 10:35:16 -07003434#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003435
Brian Curtin1b9df392010-11-24 20:24:31 +00003436#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003437 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003438 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003439 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003440
Larry Hastings2f936352014-08-05 14:04:04 +10003441 if (!result)
3442 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443#else
3444 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003445#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3447 (dst_dir_fd != DEFAULT_DIR_FD) ||
3448 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003449 result = linkat(src_dir_fd, src->narrow,
3450 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003451 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3452 else
Steve Dowercc16be82016-09-08 10:35:16 -07003453#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003454 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003455 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003456
Larry Hastings2f936352014-08-05 14:04:04 +10003457 if (result)
3458 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003459#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003460
Larry Hastings2f936352014-08-05 14:04:04 +10003461 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003462}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463#endif
3464
Brian Curtin1b9df392010-11-24 20:24:31 +00003465
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003466#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003467static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003468_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003469{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003470 PyObject *v;
3471 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3472 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003473 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003474 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003475 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003476 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003477
Steve Dowercc16be82016-09-08 10:35:16 -07003478 WIN32_FIND_DATAW wFileData;
3479 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003480
Steve Dowercc16be82016-09-08 10:35:16 -07003481 if (!path->wide) { /* Default arg: "." */
3482 po_wchars = L".";
3483 len = 1;
3484 } else {
3485 po_wchars = path->wide;
3486 len = wcslen(path->wide);
3487 }
3488 /* The +5 is so we can append "\\*.*\0" */
3489 wnamebuf = PyMem_New(wchar_t, len + 5);
3490 if (!wnamebuf) {
3491 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003492 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003493 }
Steve Dowercc16be82016-09-08 10:35:16 -07003494 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003495 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003496 wchar_t wch = wnamebuf[len-1];
3497 if (wch != SEP && wch != ALTSEP && wch != L':')
3498 wnamebuf[len++] = SEP;
3499 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003500 }
Steve Dowercc16be82016-09-08 10:35:16 -07003501 if ((list = PyList_New(0)) == NULL) {
3502 goto exit;
3503 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003504 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003505 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003506 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003507 if (hFindFile == INVALID_HANDLE_VALUE) {
3508 int error = GetLastError();
3509 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510 goto exit;
3511 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003512 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003513 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003514 }
3515 do {
3516 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003517 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3518 wcscmp(wFileData.cFileName, L"..") != 0) {
3519 v = PyUnicode_FromWideChar(wFileData.cFileName,
3520 wcslen(wFileData.cFileName));
3521 if (path->narrow && v) {
3522 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3523 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003524 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003525 Py_DECREF(list);
3526 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003527 break;
3528 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003529 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003530 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003531 Py_DECREF(list);
3532 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003533 break;
3534 }
3535 Py_DECREF(v);
3536 }
3537 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003538 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 Py_END_ALLOW_THREADS
3540 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3541 it got to the end of the directory. */
3542 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003544 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003545 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 }
3547 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003548
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549exit:
3550 if (hFindFile != INVALID_HANDLE_VALUE) {
3551 if (FindClose(hFindFile) == FALSE) {
3552 if (list != NULL) {
3553 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003554 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003555 }
3556 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003558 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003559
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003561} /* end of _listdir_windows_no_opendir */
3562
3563#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3564
3565static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003566_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003567{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003568 PyObject *v;
3569 DIR *dirp = NULL;
3570 struct dirent *ep;
3571 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003572#ifdef HAVE_FDOPENDIR
3573 int fd = -1;
3574#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003575
Victor Stinner8c62be82010-05-06 00:08:46 +00003576 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003577#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003578 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003580 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003581 if (fd == -1)
3582 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003583
Larry Hastingsfdaea062012-06-25 04:42:23 -07003584 return_str = 1;
3585
Larry Hastings9cf065c2012-06-22 16:30:09 -07003586 Py_BEGIN_ALLOW_THREADS
3587 dirp = fdopendir(fd);
3588 Py_END_ALLOW_THREADS
3589 }
3590 else
3591#endif
3592 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003593 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003594 if (path->narrow) {
3595 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003596 /* only return bytes if they specified a bytes-like object */
3597 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003598 }
3599 else {
3600 name = ".";
3601 return_str = 1;
3602 }
3603
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 Py_BEGIN_ALLOW_THREADS
3605 dirp = opendir(name);
3606 Py_END_ALLOW_THREADS
3607 }
3608
3609 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003610 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003611#ifdef HAVE_FDOPENDIR
3612 if (fd != -1) {
3613 Py_BEGIN_ALLOW_THREADS
3614 close(fd);
3615 Py_END_ALLOW_THREADS
3616 }
3617#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003618 goto exit;
3619 }
3620 if ((list = PyList_New(0)) == NULL) {
3621 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003622 }
3623 for (;;) {
3624 errno = 0;
3625 Py_BEGIN_ALLOW_THREADS
3626 ep = readdir(dirp);
3627 Py_END_ALLOW_THREADS
3628 if (ep == NULL) {
3629 if (errno == 0) {
3630 break;
3631 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003633 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 }
3636 }
3637 if (ep->d_name[0] == '.' &&
3638 (NAMLEN(ep) == 1 ||
3639 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3640 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003641 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003642 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3643 else
3644 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003646 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003647 break;
3648 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003649 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003650 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003651 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003652 break;
3653 }
3654 Py_DECREF(v);
3655 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003656
Larry Hastings9cf065c2012-06-22 16:30:09 -07003657exit:
3658 if (dirp != NULL) {
3659 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003660#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003661 if (fd > -1)
3662 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003663#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003664 closedir(dirp);
3665 Py_END_ALLOW_THREADS
3666 }
3667
Larry Hastings9cf065c2012-06-22 16:30:09 -07003668 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003669} /* end of _posix_listdir */
3670#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003671
Larry Hastings2f936352014-08-05 14:04:04 +10003672
3673/*[clinic input]
3674os.listdir
3675
3676 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3677
3678Return a list containing the names of the files in the directory.
3679
3680path can be specified as either str or bytes. If path is bytes,
3681 the filenames returned will also be bytes; in all other circumstances
3682 the filenames returned will be str.
3683If path is None, uses the path='.'.
3684On some platforms, path may also be specified as an open file descriptor;\
3685 the file descriptor must refer to a directory.
3686 If this functionality is unavailable, using it raises NotImplementedError.
3687
3688The list is in arbitrary order. It does not include the special
3689entries '.' and '..' even if they are present in the directory.
3690
3691
3692[clinic start generated code]*/
3693
Larry Hastings2f936352014-08-05 14:04:04 +10003694static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003695os_listdir_impl(PyObject *module, path_t *path)
3696/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003697{
3698#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3699 return _listdir_windows_no_opendir(path, NULL);
3700#else
3701 return _posix_listdir(path, NULL);
3702#endif
3703}
3704
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003705#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003706/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003707/*[clinic input]
3708os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003709
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003710 path: path_t
3711 /
3712
3713[clinic start generated code]*/
3714
3715static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003716os__getfullpathname_impl(PyObject *module, path_t *path)
3717/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003718{
Steve Dowercc16be82016-09-08 10:35:16 -07003719 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3720 wchar_t *wtemp;
3721 DWORD result;
3722 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003723
Steve Dowercc16be82016-09-08 10:35:16 -07003724 result = GetFullPathNameW(path->wide,
3725 Py_ARRAY_LENGTH(woutbuf),
3726 woutbuf, &wtemp);
3727 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3728 woutbufp = PyMem_New(wchar_t, result);
3729 if (!woutbufp)
3730 return PyErr_NoMemory();
3731 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003732 }
Steve Dowercc16be82016-09-08 10:35:16 -07003733 if (result) {
3734 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3735 if (path->narrow)
3736 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3737 } else
3738 v = win32_error_object("GetFullPathNameW", path->object);
3739 if (woutbufp != woutbuf)
3740 PyMem_Free(woutbufp);
3741 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003742}
Brian Curtind40e6f72010-07-08 21:39:08 +00003743
Brian Curtind25aef52011-06-13 15:16:04 -05003744
Larry Hastings2f936352014-08-05 14:04:04 +10003745/*[clinic input]
3746os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003747
Larry Hastings2f936352014-08-05 14:04:04 +10003748 path: unicode
3749 /
3750
3751A helper function for samepath on windows.
3752[clinic start generated code]*/
3753
Larry Hastings2f936352014-08-05 14:04:04 +10003754static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003755os__getfinalpathname_impl(PyObject *module, PyObject *path)
3756/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003757{
3758 HANDLE hFile;
3759 int buf_size;
3760 wchar_t *target_path;
3761 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003762 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003763 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003764
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03003765 path_wchar = _PyUnicode_AsUnicode(path);
Larry Hastings2f936352014-08-05 14:04:04 +10003766 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003767 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003768
Brian Curtind40e6f72010-07-08 21:39:08 +00003769 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003770 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003771 0, /* desired access */
3772 0, /* share mode */
3773 NULL, /* security attributes */
3774 OPEN_EXISTING,
3775 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3776 FILE_FLAG_BACKUP_SEMANTICS,
3777 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003778
Victor Stinnereb5657a2011-09-30 01:44:27 +02003779 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003780 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003781
3782 /* We have a good handle to the target, use it to determine the
3783 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003784 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003785
3786 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003787 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003788
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003789 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003790 if(!target_path)
3791 return PyErr_NoMemory();
3792
Steve Dower2ea51c92015-03-20 21:49:12 -07003793 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3794 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003795 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003796 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003797
3798 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003799 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003800
3801 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003802 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003803 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003804 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003805}
Brian Curtin62857742010-09-06 17:07:27 +00003806
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003807/*[clinic input]
3808os._isdir
3809
3810 path: path_t
3811 /
3812
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003813Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003814[clinic start generated code]*/
3815
Brian Curtin9c669cc2011-06-08 18:17:18 -05003816static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003817os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003818/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003819{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003820 DWORD attributes;
3821
Steve Dowerb22a6772016-07-17 20:49:38 -07003822 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003823 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003824 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003825
Brian Curtin9c669cc2011-06-08 18:17:18 -05003826 if (attributes == INVALID_FILE_ATTRIBUTES)
3827 Py_RETURN_FALSE;
3828
Brian Curtin9c669cc2011-06-08 18:17:18 -05003829 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3830 Py_RETURN_TRUE;
3831 else
3832 Py_RETURN_FALSE;
3833}
Tim Golden6b528062013-08-01 12:44:00 +01003834
Tim Golden6b528062013-08-01 12:44:00 +01003835
Larry Hastings2f936352014-08-05 14:04:04 +10003836/*[clinic input]
3837os._getvolumepathname
3838
3839 path: unicode
3840
3841A helper function for ismount on Win32.
3842[clinic start generated code]*/
3843
Larry Hastings2f936352014-08-05 14:04:04 +10003844static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003845os__getvolumepathname_impl(PyObject *module, PyObject *path)
3846/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003847{
3848 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003849 const wchar_t *path_wchar;
3850 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003851 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003852 BOOL ret;
3853
Larry Hastings2f936352014-08-05 14:04:04 +10003854 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3855 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003856 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003857 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003858
3859 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003860 buflen = Py_MAX(buflen, MAX_PATH);
3861
3862 if (buflen > DWORD_MAX) {
3863 PyErr_SetString(PyExc_OverflowError, "path too long");
3864 return NULL;
3865 }
3866
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003867 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003868 if (mountpath == NULL)
3869 return PyErr_NoMemory();
3870
3871 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003872 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003873 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003874 Py_END_ALLOW_THREADS
3875
3876 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003877 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003878 goto exit;
3879 }
3880 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3881
3882exit:
3883 PyMem_Free(mountpath);
3884 return result;
3885}
Tim Golden6b528062013-08-01 12:44:00 +01003886
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003887#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003888
Larry Hastings2f936352014-08-05 14:04:04 +10003889
3890/*[clinic input]
3891os.mkdir
3892
3893 path : path_t
3894
3895 mode: int = 0o777
3896
3897 *
3898
3899 dir_fd : dir_fd(requires='mkdirat') = None
3900
3901# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3902
3903Create a directory.
3904
3905If dir_fd is not None, it should be a file descriptor open to a directory,
3906 and path should be relative; path will then be relative to that directory.
3907dir_fd may not be implemented on your platform.
3908 If it is unavailable, using it will raise a NotImplementedError.
3909
3910The mode argument is ignored on Windows.
3911[clinic start generated code]*/
3912
Larry Hastings2f936352014-08-05 14:04:04 +10003913static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003914os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3915/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003916{
3917 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003918
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003919#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003920 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003921 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003923
Larry Hastings2f936352014-08-05 14:04:04 +10003924 if (!result)
3925 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003926#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003927 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003928#if HAVE_MKDIRAT
3929 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003930 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003931 else
3932#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003933#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003934 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003935#else
Larry Hastings2f936352014-08-05 14:04:04 +10003936 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003937#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003938 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003939 if (result < 0)
3940 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003941#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003942 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003943}
3944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003945
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003946/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3947#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003948#include <sys/resource.h>
3949#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003950
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003951
3952#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003953/*[clinic input]
3954os.nice
3955
3956 increment: int
3957 /
3958
3959Add increment to the priority of process and return the new priority.
3960[clinic start generated code]*/
3961
Larry Hastings2f936352014-08-05 14:04:04 +10003962static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003963os_nice_impl(PyObject *module, int increment)
3964/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003965{
3966 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003967
Victor Stinner8c62be82010-05-06 00:08:46 +00003968 /* There are two flavours of 'nice': one that returns the new
3969 priority (as required by almost all standards out there) and the
3970 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3971 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003972
Victor Stinner8c62be82010-05-06 00:08:46 +00003973 If we are of the nice family that returns the new priority, we
3974 need to clear errno before the call, and check if errno is filled
3975 before calling posix_error() on a returnvalue of -1, because the
3976 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003977
Victor Stinner8c62be82010-05-06 00:08:46 +00003978 errno = 0;
3979 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003980#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003981 if (value == 0)
3982 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003983#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003984 if (value == -1 && errno != 0)
3985 /* either nice() or getpriority() returned an error */
3986 return posix_error();
3987 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003988}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003989#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003990
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003991
3992#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003993/*[clinic input]
3994os.getpriority
3995
3996 which: int
3997 who: int
3998
3999Return program scheduling priority.
4000[clinic start generated code]*/
4001
Larry Hastings2f936352014-08-05 14:04:04 +10004002static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004003os_getpriority_impl(PyObject *module, int which, int who)
4004/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004005{
4006 int retval;
4007
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004008 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004009 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004010 if (errno != 0)
4011 return posix_error();
4012 return PyLong_FromLong((long)retval);
4013}
4014#endif /* HAVE_GETPRIORITY */
4015
4016
4017#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004018/*[clinic input]
4019os.setpriority
4020
4021 which: int
4022 who: int
4023 priority: int
4024
4025Set program scheduling priority.
4026[clinic start generated code]*/
4027
Larry Hastings2f936352014-08-05 14:04:04 +10004028static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004029os_setpriority_impl(PyObject *module, int which, int who, int priority)
4030/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004031{
4032 int retval;
4033
4034 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004035 if (retval == -1)
4036 return posix_error();
4037 Py_RETURN_NONE;
4038}
4039#endif /* HAVE_SETPRIORITY */
4040
4041
Barry Warsaw53699e91996-12-10 23:23:01 +00004042static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004043internal_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 +00004044{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004045 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004046 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004047
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004048#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004049 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004050 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004051#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004052 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004053#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004054
Larry Hastings9cf065c2012-06-22 16:30:09 -07004055 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4056 (dst_dir_fd != DEFAULT_DIR_FD);
4057#ifndef HAVE_RENAMEAT
4058 if (dir_fd_specified) {
4059 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004060 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004061 }
4062#endif
4063
Larry Hastings9cf065c2012-06-22 16:30:09 -07004064#ifdef MS_WINDOWS
4065 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004066 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004067 Py_END_ALLOW_THREADS
4068
Larry Hastings2f936352014-08-05 14:04:04 +10004069 if (!result)
4070 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004071
4072#else
Steve Dowercc16be82016-09-08 10:35:16 -07004073 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4074 PyErr_Format(PyExc_ValueError,
4075 "%s: src and dst must be the same type", function_name);
4076 return NULL;
4077 }
4078
Larry Hastings9cf065c2012-06-22 16:30:09 -07004079 Py_BEGIN_ALLOW_THREADS
4080#ifdef HAVE_RENAMEAT
4081 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004082 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004083 else
4084#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004085 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004086 Py_END_ALLOW_THREADS
4087
Larry Hastings2f936352014-08-05 14:04:04 +10004088 if (result)
4089 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004090#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004091 Py_RETURN_NONE;
4092}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004093
Larry Hastings2f936352014-08-05 14:04:04 +10004094
4095/*[clinic input]
4096os.rename
4097
4098 src : path_t
4099 dst : path_t
4100 *
4101 src_dir_fd : dir_fd = None
4102 dst_dir_fd : dir_fd = None
4103
4104Rename a file or directory.
4105
4106If either src_dir_fd or dst_dir_fd is not None, it should be a file
4107 descriptor open to a directory, and the respective path string (src or dst)
4108 should be relative; the path will then be relative to that directory.
4109src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4110 If they are unavailable, using them will raise a NotImplementedError.
4111[clinic start generated code]*/
4112
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004113static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004114os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004115 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004116/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004117{
Larry Hastings2f936352014-08-05 14:04:04 +10004118 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004119}
4120
Larry Hastings2f936352014-08-05 14:04:04 +10004121
4122/*[clinic input]
4123os.replace = os.rename
4124
4125Rename a file or directory, overwriting the destination.
4126
4127If either src_dir_fd or dst_dir_fd is not None, it should be a file
4128 descriptor open to a directory, and the respective path string (src or dst)
4129 should be relative; the path will then be relative to that directory.
4130src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4131 If they are unavailable, using them will raise a NotImplementedError."
4132[clinic start generated code]*/
4133
Larry Hastings2f936352014-08-05 14:04:04 +10004134static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004135os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4136 int dst_dir_fd)
4137/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004138{
4139 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4140}
4141
4142
4143/*[clinic input]
4144os.rmdir
4145
4146 path: path_t
4147 *
4148 dir_fd: dir_fd(requires='unlinkat') = None
4149
4150Remove a directory.
4151
4152If dir_fd is not None, it should be a file descriptor open to a directory,
4153 and path should be relative; path will then be relative to that directory.
4154dir_fd may not be implemented on your platform.
4155 If it is unavailable, using it will raise a NotImplementedError.
4156[clinic start generated code]*/
4157
Larry Hastings2f936352014-08-05 14:04:04 +10004158static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004159os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4160/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004161{
4162 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004163
4164 Py_BEGIN_ALLOW_THREADS
4165#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004166 /* Windows, success=1, UNIX, success=0 */
4167 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004168#else
4169#ifdef HAVE_UNLINKAT
4170 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004171 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004172 else
4173#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004174 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004175#endif
4176 Py_END_ALLOW_THREADS
4177
Larry Hastings2f936352014-08-05 14:04:04 +10004178 if (result)
4179 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004180
Larry Hastings2f936352014-08-05 14:04:04 +10004181 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004182}
4183
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004184
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004185#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004186#ifdef MS_WINDOWS
4187/*[clinic input]
4188os.system -> long
4189
4190 command: Py_UNICODE
4191
4192Execute the command in a subshell.
4193[clinic start generated code]*/
4194
Larry Hastings2f936352014-08-05 14:04:04 +10004195static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004196os_system_impl(PyObject *module, Py_UNICODE *command)
4197/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004198{
4199 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004200 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004201 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004202 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004203 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004204 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004205 return result;
4206}
4207#else /* MS_WINDOWS */
4208/*[clinic input]
4209os.system -> long
4210
4211 command: FSConverter
4212
4213Execute the command in a subshell.
4214[clinic start generated code]*/
4215
Larry Hastings2f936352014-08-05 14:04:04 +10004216static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004217os_system_impl(PyObject *module, PyObject *command)
4218/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004219{
4220 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004221 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004222 Py_BEGIN_ALLOW_THREADS
4223 result = system(bytes);
4224 Py_END_ALLOW_THREADS
4225 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004226}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004227#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004228#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004229
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004230
Larry Hastings2f936352014-08-05 14:04:04 +10004231/*[clinic input]
4232os.umask
4233
4234 mask: int
4235 /
4236
4237Set the current numeric umask and return the previous umask.
4238[clinic start generated code]*/
4239
Larry Hastings2f936352014-08-05 14:04:04 +10004240static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004241os_umask_impl(PyObject *module, int mask)
4242/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004243{
4244 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004245 if (i < 0)
4246 return posix_error();
4247 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004248}
4249
Brian Curtind40e6f72010-07-08 21:39:08 +00004250#ifdef MS_WINDOWS
4251
4252/* override the default DeleteFileW behavior so that directory
4253symlinks can be removed with this function, the same as with
4254Unix symlinks */
4255BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4256{
4257 WIN32_FILE_ATTRIBUTE_DATA info;
4258 WIN32_FIND_DATAW find_data;
4259 HANDLE find_data_handle;
4260 int is_directory = 0;
4261 int is_link = 0;
4262
4263 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4264 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004265
Brian Curtind40e6f72010-07-08 21:39:08 +00004266 /* Get WIN32_FIND_DATA structure for the path to determine if
4267 it is a symlink */
4268 if(is_directory &&
4269 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4270 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4271
4272 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004273 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4274 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4275 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4276 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004277 FindClose(find_data_handle);
4278 }
4279 }
4280 }
4281
4282 if (is_directory && is_link)
4283 return RemoveDirectoryW(lpFileName);
4284
4285 return DeleteFileW(lpFileName);
4286}
4287#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004288
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004289
Larry Hastings2f936352014-08-05 14:04:04 +10004290/*[clinic input]
4291os.unlink
4292
4293 path: path_t
4294 *
4295 dir_fd: dir_fd(requires='unlinkat')=None
4296
4297Remove a file (same as remove()).
4298
4299If dir_fd is not None, it should be a file descriptor open to a directory,
4300 and path should be relative; path will then be relative to that directory.
4301dir_fd may not be implemented on your platform.
4302 If it is unavailable, using it will raise a NotImplementedError.
4303
4304[clinic start generated code]*/
4305
Larry Hastings2f936352014-08-05 14:04:04 +10004306static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004307os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4308/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004309{
4310 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004311
4312 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004313 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004314#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004315 /* Windows, success=1, UNIX, success=0 */
4316 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004317#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004318#ifdef HAVE_UNLINKAT
4319 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004320 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004321 else
4322#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004323 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004324#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004325 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004326 Py_END_ALLOW_THREADS
4327
Larry Hastings2f936352014-08-05 14:04:04 +10004328 if (result)
4329 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004330
Larry Hastings2f936352014-08-05 14:04:04 +10004331 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004332}
4333
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004334
Larry Hastings2f936352014-08-05 14:04:04 +10004335/*[clinic input]
4336os.remove = os.unlink
4337
4338Remove a file (same as unlink()).
4339
4340If dir_fd is not None, it should be a file descriptor open to a directory,
4341 and path should be relative; path will then be relative to that directory.
4342dir_fd may not be implemented on your platform.
4343 If it is unavailable, using it will raise a NotImplementedError.
4344[clinic start generated code]*/
4345
Larry Hastings2f936352014-08-05 14:04:04 +10004346static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004347os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4348/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004349{
4350 return os_unlink_impl(module, path, dir_fd);
4351}
4352
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004353
Larry Hastings605a62d2012-06-24 04:33:36 -07004354static PyStructSequence_Field uname_result_fields[] = {
4355 {"sysname", "operating system name"},
4356 {"nodename", "name of machine on network (implementation-defined)"},
4357 {"release", "operating system release"},
4358 {"version", "operating system version"},
4359 {"machine", "hardware identifier"},
4360 {NULL}
4361};
4362
4363PyDoc_STRVAR(uname_result__doc__,
4364"uname_result: Result from os.uname().\n\n\
4365This object may be accessed either as a tuple of\n\
4366 (sysname, nodename, release, version, machine),\n\
4367or via the attributes sysname, nodename, release, version, and machine.\n\
4368\n\
4369See os.uname for more information.");
4370
4371static PyStructSequence_Desc uname_result_desc = {
4372 "uname_result", /* name */
4373 uname_result__doc__, /* doc */
4374 uname_result_fields,
4375 5
4376};
4377
4378static PyTypeObject UnameResultType;
4379
4380
4381#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004382/*[clinic input]
4383os.uname
4384
4385Return an object identifying the current operating system.
4386
4387The object behaves like a named tuple with the following fields:
4388 (sysname, nodename, release, version, machine)
4389
4390[clinic start generated code]*/
4391
Larry Hastings2f936352014-08-05 14:04:04 +10004392static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004393os_uname_impl(PyObject *module)
4394/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004395{
Victor Stinner8c62be82010-05-06 00:08:46 +00004396 struct utsname u;
4397 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004398 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004399
Victor Stinner8c62be82010-05-06 00:08:46 +00004400 Py_BEGIN_ALLOW_THREADS
4401 res = uname(&u);
4402 Py_END_ALLOW_THREADS
4403 if (res < 0)
4404 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004405
4406 value = PyStructSequence_New(&UnameResultType);
4407 if (value == NULL)
4408 return NULL;
4409
4410#define SET(i, field) \
4411 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004412 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004413 if (!o) { \
4414 Py_DECREF(value); \
4415 return NULL; \
4416 } \
4417 PyStructSequence_SET_ITEM(value, i, o); \
4418 } \
4419
4420 SET(0, u.sysname);
4421 SET(1, u.nodename);
4422 SET(2, u.release);
4423 SET(3, u.version);
4424 SET(4, u.machine);
4425
4426#undef SET
4427
4428 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004429}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004430#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004431
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004432
Larry Hastings9cf065c2012-06-22 16:30:09 -07004433
4434typedef struct {
4435 int now;
4436 time_t atime_s;
4437 long atime_ns;
4438 time_t mtime_s;
4439 long mtime_ns;
4440} utime_t;
4441
4442/*
Victor Stinner484df002014-10-09 13:52:31 +02004443 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444 * they also intentionally leak the declaration of a pointer named "time"
4445 */
4446#define UTIME_TO_TIMESPEC \
4447 struct timespec ts[2]; \
4448 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004449 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004450 time = NULL; \
4451 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004452 ts[0].tv_sec = ut->atime_s; \
4453 ts[0].tv_nsec = ut->atime_ns; \
4454 ts[1].tv_sec = ut->mtime_s; \
4455 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004456 time = ts; \
4457 } \
4458
4459#define UTIME_TO_TIMEVAL \
4460 struct timeval tv[2]; \
4461 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004462 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004463 time = NULL; \
4464 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004465 tv[0].tv_sec = ut->atime_s; \
4466 tv[0].tv_usec = ut->atime_ns / 1000; \
4467 tv[1].tv_sec = ut->mtime_s; \
4468 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004469 time = tv; \
4470 } \
4471
4472#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004473 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004474 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004475 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004476 time = NULL; \
4477 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004478 u.actime = ut->atime_s; \
4479 u.modtime = ut->mtime_s; \
4480 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004481 }
4482
4483#define UTIME_TO_TIME_T \
4484 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004485 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004486 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004487 time = NULL; \
4488 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004489 timet[0] = ut->atime_s; \
4490 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004491 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004492 } \
4493
4494
Victor Stinner528a9ab2015-09-03 21:30:26 +02004495#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004496
4497static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004498utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004499{
4500#ifdef HAVE_UTIMENSAT
4501 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4502 UTIME_TO_TIMESPEC;
4503 return utimensat(dir_fd, path, time, flags);
4504#elif defined(HAVE_FUTIMESAT)
4505 UTIME_TO_TIMEVAL;
4506 /*
4507 * follow_symlinks will never be false here;
4508 * we only allow !follow_symlinks and dir_fd together
4509 * if we have utimensat()
4510 */
4511 assert(follow_symlinks);
4512 return futimesat(dir_fd, path, time);
4513#endif
4514}
4515
Larry Hastings2f936352014-08-05 14:04:04 +10004516 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4517#else
4518 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004519#endif
4520
Victor Stinner528a9ab2015-09-03 21:30:26 +02004521#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004522
4523static int
Victor Stinner484df002014-10-09 13:52:31 +02004524utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004525{
4526#ifdef HAVE_FUTIMENS
4527 UTIME_TO_TIMESPEC;
4528 return futimens(fd, time);
4529#else
4530 UTIME_TO_TIMEVAL;
4531 return futimes(fd, time);
4532#endif
4533}
4534
Larry Hastings2f936352014-08-05 14:04:04 +10004535 #define PATH_UTIME_HAVE_FD 1
4536#else
4537 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538#endif
4539
Victor Stinner5ebae872015-09-22 01:29:33 +02004540#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4541# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4542#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004543
Victor Stinner4552ced2015-09-21 22:37:15 +02004544#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004545
4546static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004547utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004548{
4549#ifdef HAVE_UTIMENSAT
4550 UTIME_TO_TIMESPEC;
4551 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4552#else
4553 UTIME_TO_TIMEVAL;
4554 return lutimes(path, time);
4555#endif
4556}
4557
4558#endif
4559
4560#ifndef MS_WINDOWS
4561
4562static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004563utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004564{
4565#ifdef HAVE_UTIMENSAT
4566 UTIME_TO_TIMESPEC;
4567 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4568#elif defined(HAVE_UTIMES)
4569 UTIME_TO_TIMEVAL;
4570 return utimes(path, time);
4571#elif defined(HAVE_UTIME_H)
4572 UTIME_TO_UTIMBUF;
4573 return utime(path, time);
4574#else
4575 UTIME_TO_TIME_T;
4576 return utime(path, time);
4577#endif
4578}
4579
4580#endif
4581
Larry Hastings76ad59b2012-05-03 00:30:07 -07004582static int
4583split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4584{
4585 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004586 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004587 divmod = PyNumber_Divmod(py_long, billion);
4588 if (!divmod)
4589 goto exit;
4590 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4591 if ((*s == -1) && PyErr_Occurred())
4592 goto exit;
4593 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004594 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004595 goto exit;
4596
4597 result = 1;
4598exit:
4599 Py_XDECREF(divmod);
4600 return result;
4601}
4602
Larry Hastings2f936352014-08-05 14:04:04 +10004603
4604/*[clinic input]
4605os.utime
4606
4607 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4608 times: object = NULL
4609 *
4610 ns: object = NULL
4611 dir_fd: dir_fd(requires='futimensat') = None
4612 follow_symlinks: bool=True
4613
Martin Panter0ff89092015-09-09 01:56:53 +00004614# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004615
4616Set the access and modified time of path.
4617
4618path may always be specified as a string.
4619On some platforms, path may also be specified as an open file descriptor.
4620 If this functionality is unavailable, using it raises an exception.
4621
4622If times is not None, it must be a tuple (atime, mtime);
4623 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004624If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004625 atime_ns and mtime_ns should be expressed as integer nanoseconds
4626 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004627If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004628Specifying tuples for both times and ns is an error.
4629
4630If dir_fd is not None, it should be a file descriptor open to a directory,
4631 and path should be relative; path will then be relative to that directory.
4632If follow_symlinks is False, and the last element of the path is a symbolic
4633 link, utime will modify the symbolic link itself instead of the file the
4634 link points to.
4635It is an error to use dir_fd or follow_symlinks when specifying path
4636 as an open file descriptor.
4637dir_fd and follow_symlinks may not be available on your platform.
4638 If they are unavailable, using them will raise a NotImplementedError.
4639
4640[clinic start generated code]*/
4641
Larry Hastings2f936352014-08-05 14:04:04 +10004642static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004643os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4644 int dir_fd, int follow_symlinks)
4645/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004646{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004647#ifdef MS_WINDOWS
4648 HANDLE hFile;
4649 FILETIME atime, mtime;
4650#else
4651 int result;
4652#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004653
Larry Hastings9cf065c2012-06-22 16:30:09 -07004654 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004655 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004656
Christian Heimesb3c87242013-08-01 00:08:16 +02004657 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004658
Larry Hastings9cf065c2012-06-22 16:30:09 -07004659 if (times && (times != Py_None) && ns) {
4660 PyErr_SetString(PyExc_ValueError,
4661 "utime: you may specify either 'times'"
4662 " or 'ns' but not both");
4663 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004664 }
4665
4666 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004667 time_t a_sec, m_sec;
4668 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004669 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004670 PyErr_SetString(PyExc_TypeError,
4671 "utime: 'times' must be either"
4672 " a tuple of two ints or None");
4673 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004674 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004676 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004677 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004678 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004679 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004680 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004681 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004682 utime.atime_s = a_sec;
4683 utime.atime_ns = a_nsec;
4684 utime.mtime_s = m_sec;
4685 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004686 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004687 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004688 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004689 PyErr_SetString(PyExc_TypeError,
4690 "utime: 'ns' must be a tuple of two ints");
4691 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004692 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004693 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004694 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004695 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004696 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004697 &utime.mtime_s, &utime.mtime_ns)) {
4698 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004699 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004700 }
4701 else {
4702 /* times and ns are both None/unspecified. use "now". */
4703 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004704 }
4705
Victor Stinner4552ced2015-09-21 22:37:15 +02004706#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004707 if (follow_symlinks_specified("utime", follow_symlinks))
4708 goto exit;
4709#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004710
Larry Hastings2f936352014-08-05 14:04:04 +10004711 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4712 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4713 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004714 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004715
Larry Hastings9cf065c2012-06-22 16:30:09 -07004716#if !defined(HAVE_UTIMENSAT)
4717 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004718 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004719 "utime: cannot use dir_fd and follow_symlinks "
4720 "together on this platform");
4721 goto exit;
4722 }
4723#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004724
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004725#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004726 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004727 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4728 NULL, OPEN_EXISTING,
4729 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004730 Py_END_ALLOW_THREADS
4731 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004732 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004733 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004734 }
4735
Larry Hastings9cf065c2012-06-22 16:30:09 -07004736 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004737 GetSystemTimeAsFileTime(&mtime);
4738 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004739 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004740 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004741 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4742 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004743 }
4744 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4745 /* Avoid putting the file name into the error here,
4746 as that may confuse the user into believing that
4747 something is wrong with the file, when it also
4748 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004749 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004750 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004751 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004752#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004754
Victor Stinner4552ced2015-09-21 22:37:15 +02004755#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004756 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004757 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004759#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004760
Victor Stinner528a9ab2015-09-03 21:30:26 +02004761#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004762 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004763 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004764 else
4765#endif
4766
Victor Stinner528a9ab2015-09-03 21:30:26 +02004767#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004768 if (path->fd != -1)
4769 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770 else
4771#endif
4772
Larry Hastings2f936352014-08-05 14:04:04 +10004773 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004774
4775 Py_END_ALLOW_THREADS
4776
4777 if (result < 0) {
4778 /* see previous comment about not putting filename in error here */
4779 return_value = posix_error();
4780 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004781 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004782
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004783#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004784
4785 Py_INCREF(Py_None);
4786 return_value = Py_None;
4787
4788exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004789#ifdef MS_WINDOWS
4790 if (hFile != INVALID_HANDLE_VALUE)
4791 CloseHandle(hFile);
4792#endif
4793 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004794}
4795
Guido van Rossum3b066191991-06-04 19:40:25 +00004796/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004797
Larry Hastings2f936352014-08-05 14:04:04 +10004798
4799/*[clinic input]
4800os._exit
4801
4802 status: int
4803
4804Exit to the system with specified status, without normal exit processing.
4805[clinic start generated code]*/
4806
Larry Hastings2f936352014-08-05 14:04:04 +10004807static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004808os__exit_impl(PyObject *module, int status)
4809/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004810{
4811 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004812 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004813}
4814
Steve Dowercc16be82016-09-08 10:35:16 -07004815#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4816#define EXECV_CHAR wchar_t
4817#else
4818#define EXECV_CHAR char
4819#endif
4820
Martin v. Löwis114619e2002-10-07 06:44:21 +00004821#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4822static void
Steve Dowercc16be82016-09-08 10:35:16 -07004823free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004824{
Victor Stinner8c62be82010-05-06 00:08:46 +00004825 Py_ssize_t i;
4826 for (i = 0; i < count; i++)
4827 PyMem_Free(array[i]);
4828 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004829}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004830
Berker Peksag81816462016-09-15 20:19:47 +03004831static int
4832fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004833{
Victor Stinner8c62be82010-05-06 00:08:46 +00004834 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004835 PyObject *ub;
4836 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004837#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004838 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004839 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004840 *out = PyUnicode_AsWideCharString(ub, &size);
4841 if (*out)
4842 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004843#else
Berker Peksag81816462016-09-15 20:19:47 +03004844 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004845 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004846 size = PyBytes_GET_SIZE(ub);
4847 *out = PyMem_Malloc(size + 1);
4848 if (*out) {
4849 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4850 result = 1;
4851 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004852 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004853#endif
Berker Peksag81816462016-09-15 20:19:47 +03004854 Py_DECREF(ub);
4855 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004856}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004857#endif
4858
Ross Lagerwall7807c352011-03-17 20:20:30 +02004859#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004860static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004861parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4862{
Victor Stinner8c62be82010-05-06 00:08:46 +00004863 Py_ssize_t i, pos, envc;
4864 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004865 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004866 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004867
Victor Stinner8c62be82010-05-06 00:08:46 +00004868 i = PyMapping_Size(env);
4869 if (i < 0)
4870 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004871 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004872 if (envlist == NULL) {
4873 PyErr_NoMemory();
4874 return NULL;
4875 }
4876 envc = 0;
4877 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004878 if (!keys)
4879 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004880 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004881 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004882 goto error;
4883 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4884 PyErr_Format(PyExc_TypeError,
4885 "env.keys() or env.values() is not a list");
4886 goto error;
4887 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004888
Victor Stinner8c62be82010-05-06 00:08:46 +00004889 for (pos = 0; pos < i; pos++) {
4890 key = PyList_GetItem(keys, pos);
4891 val = PyList_GetItem(vals, pos);
4892 if (!key || !val)
4893 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004894
Berker Peksag81816462016-09-15 20:19:47 +03004895#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4896 if (!PyUnicode_FSDecoder(key, &key2))
4897 goto error;
4898 if (!PyUnicode_FSDecoder(val, &val2)) {
4899 Py_DECREF(key2);
4900 goto error;
4901 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004902 /* Search from index 1 because on Windows starting '=' is allowed for
4903 defining hidden environment variables. */
4904 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4905 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4906 {
4907 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004908 Py_DECREF(key2);
4909 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004910 goto error;
4911 }
Berker Peksag81816462016-09-15 20:19:47 +03004912 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4913#else
4914 if (!PyUnicode_FSConverter(key, &key2))
4915 goto error;
4916 if (!PyUnicode_FSConverter(val, &val2)) {
4917 Py_DECREF(key2);
4918 goto error;
4919 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004920 if (PyBytes_GET_SIZE(key2) == 0 ||
4921 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4922 {
4923 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004924 Py_DECREF(key2);
4925 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004926 goto error;
4927 }
Berker Peksag81816462016-09-15 20:19:47 +03004928 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4929 PyBytes_AS_STRING(val2));
4930#endif
4931 Py_DECREF(key2);
4932 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004933 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004934 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004935
4936 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4937 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004938 goto error;
4939 }
Berker Peksag81816462016-09-15 20:19:47 +03004940
Steve Dowercc16be82016-09-08 10:35:16 -07004941 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 }
4943 Py_DECREF(vals);
4944 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004945
Victor Stinner8c62be82010-05-06 00:08:46 +00004946 envlist[envc] = 0;
4947 *envc_ptr = envc;
4948 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004949
4950error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004951 Py_XDECREF(keys);
4952 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004953 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004954 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004955}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004956
Steve Dowercc16be82016-09-08 10:35:16 -07004957static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004958parse_arglist(PyObject* argv, Py_ssize_t *argc)
4959{
4960 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004961 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004962 if (argvlist == NULL) {
4963 PyErr_NoMemory();
4964 return NULL;
4965 }
4966 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004967 PyObject* item = PySequence_ITEM(argv, i);
4968 if (item == NULL)
4969 goto fail;
4970 if (!fsconvert_strdup(item, &argvlist[i])) {
4971 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004972 goto fail;
4973 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004974 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004975 }
4976 argvlist[*argc] = NULL;
4977 return argvlist;
4978fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004979 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004980 free_string_array(argvlist, *argc);
4981 return NULL;
4982}
Steve Dowercc16be82016-09-08 10:35:16 -07004983
Ross Lagerwall7807c352011-03-17 20:20:30 +02004984#endif
4985
Larry Hastings2f936352014-08-05 14:04:04 +10004986
Ross Lagerwall7807c352011-03-17 20:20:30 +02004987#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004988/*[clinic input]
4989os.execv
4990
Steve Dowercc16be82016-09-08 10:35:16 -07004991 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004992 Path of executable file.
4993 argv: object
4994 Tuple or list of strings.
4995 /
4996
4997Execute an executable path with arguments, replacing current process.
4998[clinic start generated code]*/
4999
Larry Hastings2f936352014-08-05 14:04:04 +10005000static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005001os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5002/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005003{
Steve Dowercc16be82016-09-08 10:35:16 -07005004 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005005 Py_ssize_t argc;
5006
5007 /* execv has two arguments: (path, argv), where
5008 argv is a list or tuple of strings. */
5009
Ross Lagerwall7807c352011-03-17 20:20:30 +02005010 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5011 PyErr_SetString(PyExc_TypeError,
5012 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005013 return NULL;
5014 }
5015 argc = PySequence_Size(argv);
5016 if (argc < 1) {
5017 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005018 return NULL;
5019 }
5020
5021 argvlist = parse_arglist(argv, &argc);
5022 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005023 return NULL;
5024 }
Steve Dowerbce26262016-11-19 19:17:26 -08005025 if (!argvlist[0][0]) {
5026 PyErr_SetString(PyExc_ValueError,
5027 "execv() arg 2 first element cannot be empty");
5028 free_string_array(argvlist, argc);
5029 return NULL;
5030 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005031
Steve Dowerbce26262016-11-19 19:17:26 -08005032 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005033#ifdef HAVE_WEXECV
5034 _wexecv(path->wide, argvlist);
5035#else
5036 execv(path->narrow, argvlist);
5037#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005038 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005039
5040 /* If we get here it's definitely an error */
5041
5042 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005043 return posix_error();
5044}
5045
Larry Hastings2f936352014-08-05 14:04:04 +10005046
5047/*[clinic input]
5048os.execve
5049
5050 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5051 Path of executable file.
5052 argv: object
5053 Tuple or list of strings.
5054 env: object
5055 Dictionary of strings mapping to strings.
5056
5057Execute an executable path with arguments, replacing current process.
5058[clinic start generated code]*/
5059
Larry Hastings2f936352014-08-05 14:04:04 +10005060static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005061os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5062/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005063{
Steve Dowercc16be82016-09-08 10:35:16 -07005064 EXECV_CHAR **argvlist = NULL;
5065 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005066 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005067
Victor Stinner8c62be82010-05-06 00:08:46 +00005068 /* execve has three arguments: (path, argv, env), where
5069 argv is a list or tuple of strings and env is a dictionary
5070 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005071
Ross Lagerwall7807c352011-03-17 20:20:30 +02005072 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005073 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005074 "execve: argv must be a tuple or list");
5075 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005076 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005077 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005078 if (argc < 1) {
5079 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5080 return NULL;
5081 }
5082
Victor Stinner8c62be82010-05-06 00:08:46 +00005083 if (!PyMapping_Check(env)) {
5084 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005085 "execve: environment must be a mapping object");
5086 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005087 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005088
Ross Lagerwall7807c352011-03-17 20:20:30 +02005089 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005090 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005091 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005092 }
Steve Dowerbce26262016-11-19 19:17:26 -08005093 if (!argvlist[0][0]) {
5094 PyErr_SetString(PyExc_ValueError,
5095 "execve: argv first element cannot be empty");
5096 goto fail;
5097 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005098
Victor Stinner8c62be82010-05-06 00:08:46 +00005099 envlist = parse_envlist(env, &envc);
5100 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005101 goto fail;
5102
Steve Dowerbce26262016-11-19 19:17:26 -08005103 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005104#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005105 if (path->fd > -1)
5106 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005107 else
5108#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005109#ifdef HAVE_WEXECV
5110 _wexecve(path->wide, argvlist, envlist);
5111#else
Larry Hastings2f936352014-08-05 14:04:04 +10005112 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005113#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005114 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005115
5116 /* If we get here it's definitely an error */
5117
Larry Hastings2f936352014-08-05 14:04:04 +10005118 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005119
Steve Dowercc16be82016-09-08 10:35:16 -07005120 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005121 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005122 if (argvlist)
5123 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005124 return NULL;
5125}
Steve Dowercc16be82016-09-08 10:35:16 -07005126
Larry Hastings9cf065c2012-06-22 16:30:09 -07005127#endif /* HAVE_EXECV */
5128
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005129
Steve Dowercc16be82016-09-08 10:35:16 -07005130#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005131/*[clinic input]
5132os.spawnv
5133
5134 mode: int
5135 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005136 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005137 Path of executable file.
5138 argv: object
5139 Tuple or list of strings.
5140 /
5141
5142Execute the program specified by path in a new process.
5143[clinic start generated code]*/
5144
Larry Hastings2f936352014-08-05 14:04:04 +10005145static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005146os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5147/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005148{
Steve Dowercc16be82016-09-08 10:35:16 -07005149 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005150 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005151 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005152 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005154
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 /* spawnv has three arguments: (mode, path, argv), where
5156 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005157
Victor Stinner8c62be82010-05-06 00:08:46 +00005158 if (PyList_Check(argv)) {
5159 argc = PyList_Size(argv);
5160 getitem = PyList_GetItem;
5161 }
5162 else if (PyTuple_Check(argv)) {
5163 argc = PyTuple_Size(argv);
5164 getitem = PyTuple_GetItem;
5165 }
5166 else {
5167 PyErr_SetString(PyExc_TypeError,
5168 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005169 return NULL;
5170 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005171 if (argc == 0) {
5172 PyErr_SetString(PyExc_ValueError,
5173 "spawnv() arg 2 cannot be empty");
5174 return NULL;
5175 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005176
Steve Dowercc16be82016-09-08 10:35:16 -07005177 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005178 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005179 return PyErr_NoMemory();
5180 }
5181 for (i = 0; i < argc; i++) {
5182 if (!fsconvert_strdup((*getitem)(argv, i),
5183 &argvlist[i])) {
5184 free_string_array(argvlist, i);
5185 PyErr_SetString(
5186 PyExc_TypeError,
5187 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005188 return NULL;
5189 }
Steve Dower93ff8722016-11-19 19:03:54 -08005190 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005191 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005192 PyErr_SetString(
5193 PyExc_ValueError,
5194 "spawnv() arg 2 first element cannot be empty");
5195 return NULL;
5196 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005197 }
5198 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005199
Victor Stinner8c62be82010-05-06 00:08:46 +00005200 if (mode == _OLD_P_OVERLAY)
5201 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005202
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005204 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005205#ifdef HAVE_WSPAWNV
5206 spawnval = _wspawnv(mode, path->wide, argvlist);
5207#else
5208 spawnval = _spawnv(mode, path->narrow, argvlist);
5209#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005210 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005211 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005212
Victor Stinner8c62be82010-05-06 00:08:46 +00005213 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005214
Victor Stinner8c62be82010-05-06 00:08:46 +00005215 if (spawnval == -1)
5216 return posix_error();
5217 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005218 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005219}
5220
5221
Larry Hastings2f936352014-08-05 14:04:04 +10005222/*[clinic input]
5223os.spawnve
5224
5225 mode: int
5226 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005227 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005228 Path of executable file.
5229 argv: object
5230 Tuple or list of strings.
5231 env: object
5232 Dictionary of strings mapping to strings.
5233 /
5234
5235Execute the program specified by path in a new process.
5236[clinic start generated code]*/
5237
Larry Hastings2f936352014-08-05 14:04:04 +10005238static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005239os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005240 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005241/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005242{
Steve Dowercc16be82016-09-08 10:35:16 -07005243 EXECV_CHAR **argvlist;
5244 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005245 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005246 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005247 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005248 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005249 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005250
Victor Stinner8c62be82010-05-06 00:08:46 +00005251 /* spawnve has four arguments: (mode, path, argv, env), where
5252 argv is a list or tuple of strings and env is a dictionary
5253 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005254
Victor Stinner8c62be82010-05-06 00:08:46 +00005255 if (PyList_Check(argv)) {
5256 argc = PyList_Size(argv);
5257 getitem = PyList_GetItem;
5258 }
5259 else if (PyTuple_Check(argv)) {
5260 argc = PyTuple_Size(argv);
5261 getitem = PyTuple_GetItem;
5262 }
5263 else {
5264 PyErr_SetString(PyExc_TypeError,
5265 "spawnve() arg 2 must be a tuple or list");
5266 goto fail_0;
5267 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005268 if (argc == 0) {
5269 PyErr_SetString(PyExc_ValueError,
5270 "spawnve() arg 2 cannot be empty");
5271 goto fail_0;
5272 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005273 if (!PyMapping_Check(env)) {
5274 PyErr_SetString(PyExc_TypeError,
5275 "spawnve() arg 3 must be a mapping object");
5276 goto fail_0;
5277 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005278
Steve Dowercc16be82016-09-08 10:35:16 -07005279 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005280 if (argvlist == NULL) {
5281 PyErr_NoMemory();
5282 goto fail_0;
5283 }
5284 for (i = 0; i < argc; i++) {
5285 if (!fsconvert_strdup((*getitem)(argv, i),
5286 &argvlist[i]))
5287 {
5288 lastarg = i;
5289 goto fail_1;
5290 }
Steve Dowerbce26262016-11-19 19:17:26 -08005291 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005292 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005293 PyErr_SetString(
5294 PyExc_ValueError,
5295 "spawnv() arg 2 first element cannot be empty");
5296 goto fail_1;
5297 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005298 }
5299 lastarg = argc;
5300 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005301
Victor Stinner8c62be82010-05-06 00:08:46 +00005302 envlist = parse_envlist(env, &envc);
5303 if (envlist == NULL)
5304 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005305
Victor Stinner8c62be82010-05-06 00:08:46 +00005306 if (mode == _OLD_P_OVERLAY)
5307 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005308
Victor Stinner8c62be82010-05-06 00:08:46 +00005309 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005310 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005311#ifdef HAVE_WSPAWNV
5312 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5313#else
5314 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5315#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005316 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005317 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005318
Victor Stinner8c62be82010-05-06 00:08:46 +00005319 if (spawnval == -1)
5320 (void) posix_error();
5321 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005322 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005323
Victor Stinner8c62be82010-05-06 00:08:46 +00005324 while (--envc >= 0)
5325 PyMem_DEL(envlist[envc]);
5326 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005327 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005328 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005329 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005330 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005331}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005332
Guido van Rossuma1065681999-01-25 23:20:23 +00005333#endif /* HAVE_SPAWNV */
5334
5335
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005336#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005337
5338/* Helper function to validate arguments.
5339 Returns 0 on success. non-zero on failure with a TypeError raised.
5340 If obj is non-NULL it must be callable. */
5341static int
5342check_null_or_callable(PyObject *obj, const char* obj_name)
5343{
5344 if (obj && !PyCallable_Check(obj)) {
5345 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5346 obj_name, Py_TYPE(obj)->tp_name);
5347 return -1;
5348 }
5349 return 0;
5350}
5351
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005352/*[clinic input]
5353os.register_at_fork
5354
Gregory P. Smith163468a2017-05-29 10:03:41 -07005355 *
5356 before: object=NULL
5357 A callable to be called in the parent before the fork() syscall.
5358 after_in_child: object=NULL
5359 A callable to be called in the child after fork().
5360 after_in_parent: object=NULL
5361 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005362
Gregory P. Smith163468a2017-05-29 10:03:41 -07005363Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005364
Gregory P. Smith163468a2017-05-29 10:03:41 -07005365'before' callbacks are called in reverse order.
5366'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005367
5368[clinic start generated code]*/
5369
5370static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005371os_register_at_fork_impl(PyObject *module, PyObject *before,
5372 PyObject *after_in_child, PyObject *after_in_parent)
5373/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005374{
5375 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005376
Gregory P. Smith163468a2017-05-29 10:03:41 -07005377 if (!before && !after_in_child && !after_in_parent) {
5378 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5379 return NULL;
5380 }
5381 if (check_null_or_callable(before, "before") ||
5382 check_null_or_callable(after_in_child, "after_in_child") ||
5383 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005384 return NULL;
5385 }
5386 interp = PyThreadState_Get()->interp;
5387
Gregory P. Smith163468a2017-05-29 10:03:41 -07005388 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005389 return NULL;
5390 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005391 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005392 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005393 }
5394 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5395 return NULL;
5396 }
5397 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005398}
5399#endif /* HAVE_FORK */
5400
5401
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005402#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005403/*[clinic input]
5404os.fork1
5405
5406Fork a child process with a single multiplexed (i.e., not bound) thread.
5407
5408Return 0 to child process and PID of child to parent process.
5409[clinic start generated code]*/
5410
Larry Hastings2f936352014-08-05 14:04:04 +10005411static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005412os_fork1_impl(PyObject *module)
5413/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005414{
Victor Stinner8c62be82010-05-06 00:08:46 +00005415 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005416
5417 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005418 pid = fork1();
5419 if (pid == 0) {
5420 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005421 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005422 } else {
5423 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005424 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005425 }
5426 if (pid == -1)
5427 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005428 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005429}
Larry Hastings2f936352014-08-05 14:04:04 +10005430#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005431
5432
Guido van Rossumad0ee831995-03-01 10:34:45 +00005433#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005434/*[clinic input]
5435os.fork
5436
5437Fork a child process.
5438
5439Return 0 to child process and PID of child to parent process.
5440[clinic start generated code]*/
5441
Larry Hastings2f936352014-08-05 14:04:04 +10005442static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005443os_fork_impl(PyObject *module)
5444/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005445{
Victor Stinner8c62be82010-05-06 00:08:46 +00005446 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005447
5448 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005449 pid = fork();
5450 if (pid == 0) {
5451 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005452 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005453 } else {
5454 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005455 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005456 }
5457 if (pid == -1)
5458 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005459 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005460}
Larry Hastings2f936352014-08-05 14:04:04 +10005461#endif /* HAVE_FORK */
5462
Guido van Rossum85e3b011991-06-03 12:42:10 +00005463
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005464#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005465#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005466/*[clinic input]
5467os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005468
Larry Hastings2f936352014-08-05 14:04:04 +10005469 policy: int
5470
5471Get the maximum scheduling priority for policy.
5472[clinic start generated code]*/
5473
Larry Hastings2f936352014-08-05 14:04:04 +10005474static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005475os_sched_get_priority_max_impl(PyObject *module, int policy)
5476/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005477{
5478 int max;
5479
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005480 max = sched_get_priority_max(policy);
5481 if (max < 0)
5482 return posix_error();
5483 return PyLong_FromLong(max);
5484}
5485
Larry Hastings2f936352014-08-05 14:04:04 +10005486
5487/*[clinic input]
5488os.sched_get_priority_min
5489
5490 policy: int
5491
5492Get the minimum scheduling priority for policy.
5493[clinic start generated code]*/
5494
Larry Hastings2f936352014-08-05 14:04:04 +10005495static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005496os_sched_get_priority_min_impl(PyObject *module, int policy)
5497/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005498{
5499 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005500 if (min < 0)
5501 return posix_error();
5502 return PyLong_FromLong(min);
5503}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005504#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5505
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005506
Larry Hastings2f936352014-08-05 14:04:04 +10005507#ifdef HAVE_SCHED_SETSCHEDULER
5508/*[clinic input]
5509os.sched_getscheduler
5510 pid: pid_t
5511 /
5512
5513Get the scheduling policy for the process identifiedy by pid.
5514
5515Passing 0 for pid returns the scheduling policy for the calling process.
5516[clinic start generated code]*/
5517
Larry Hastings2f936352014-08-05 14:04:04 +10005518static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005519os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5520/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005521{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005522 int policy;
5523
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005524 policy = sched_getscheduler(pid);
5525 if (policy < 0)
5526 return posix_error();
5527 return PyLong_FromLong(policy);
5528}
Larry Hastings2f936352014-08-05 14:04:04 +10005529#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005530
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005531
5532#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005533/*[clinic input]
5534class os.sched_param "PyObject *" "&SchedParamType"
5535
5536@classmethod
5537os.sched_param.__new__
5538
5539 sched_priority: object
5540 A scheduling parameter.
5541
5542Current has only one field: sched_priority");
5543[clinic start generated code]*/
5544
Larry Hastings2f936352014-08-05 14:04:04 +10005545static PyObject *
5546os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005547/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005548{
5549 PyObject *res;
5550
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005551 res = PyStructSequence_New(type);
5552 if (!res)
5553 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005554 Py_INCREF(sched_priority);
5555 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005556 return res;
5557}
5558
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005559
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005560PyDoc_VAR(os_sched_param__doc__);
5561
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005562static PyStructSequence_Field sched_param_fields[] = {
5563 {"sched_priority", "the scheduling priority"},
5564 {0}
5565};
5566
5567static PyStructSequence_Desc sched_param_desc = {
5568 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005569 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005570 sched_param_fields,
5571 1
5572};
5573
5574static int
5575convert_sched_param(PyObject *param, struct sched_param *res)
5576{
5577 long priority;
5578
5579 if (Py_TYPE(param) != &SchedParamType) {
5580 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5581 return 0;
5582 }
5583 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5584 if (priority == -1 && PyErr_Occurred())
5585 return 0;
5586 if (priority > INT_MAX || priority < INT_MIN) {
5587 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5588 return 0;
5589 }
5590 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5591 return 1;
5592}
Larry Hastings2f936352014-08-05 14:04:04 +10005593#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005594
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005595
5596#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005597/*[clinic input]
5598os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005599
Larry Hastings2f936352014-08-05 14:04:04 +10005600 pid: pid_t
5601 policy: int
5602 param: sched_param
5603 /
5604
5605Set the scheduling policy for the process identified by pid.
5606
5607If pid is 0, the calling process is changed.
5608param is an instance of sched_param.
5609[clinic start generated code]*/
5610
Larry Hastings2f936352014-08-05 14:04:04 +10005611static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005612os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005613 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005614/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005615{
Jesus Cea9c822272011-09-10 01:40:52 +02005616 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005617 ** sched_setscheduler() returns 0 in Linux, but the previous
5618 ** scheduling policy under Solaris/Illumos, and others.
5619 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005620 */
Larry Hastings2f936352014-08-05 14:04:04 +10005621 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005622 return posix_error();
5623 Py_RETURN_NONE;
5624}
Larry Hastings2f936352014-08-05 14:04:04 +10005625#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005626
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005627
5628#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005629/*[clinic input]
5630os.sched_getparam
5631 pid: pid_t
5632 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005633
Larry Hastings2f936352014-08-05 14:04:04 +10005634Returns scheduling parameters for the process identified by pid.
5635
5636If pid is 0, returns parameters for the calling process.
5637Return value is an instance of sched_param.
5638[clinic start generated code]*/
5639
Larry Hastings2f936352014-08-05 14:04:04 +10005640static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005641os_sched_getparam_impl(PyObject *module, pid_t pid)
5642/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005643{
5644 struct sched_param param;
5645 PyObject *result;
5646 PyObject *priority;
5647
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005648 if (sched_getparam(pid, &param))
5649 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005650 result = PyStructSequence_New(&SchedParamType);
5651 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005652 return NULL;
5653 priority = PyLong_FromLong(param.sched_priority);
5654 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005655 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005656 return NULL;
5657 }
Larry Hastings2f936352014-08-05 14:04:04 +10005658 PyStructSequence_SET_ITEM(result, 0, priority);
5659 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005660}
5661
Larry Hastings2f936352014-08-05 14:04:04 +10005662
5663/*[clinic input]
5664os.sched_setparam
5665 pid: pid_t
5666 param: sched_param
5667 /
5668
5669Set scheduling parameters for the process identified by pid.
5670
5671If pid is 0, sets parameters for the calling process.
5672param should be an instance of sched_param.
5673[clinic start generated code]*/
5674
Larry Hastings2f936352014-08-05 14:04:04 +10005675static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005676os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005677 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005678/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005679{
5680 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005681 return posix_error();
5682 Py_RETURN_NONE;
5683}
Larry Hastings2f936352014-08-05 14:04:04 +10005684#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005685
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005686
5687#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005688/*[clinic input]
5689os.sched_rr_get_interval -> double
5690 pid: pid_t
5691 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005692
Larry Hastings2f936352014-08-05 14:04:04 +10005693Return the round-robin quantum for the process identified by pid, in seconds.
5694
5695Value returned is a float.
5696[clinic start generated code]*/
5697
Larry Hastings2f936352014-08-05 14:04:04 +10005698static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005699os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5700/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005701{
5702 struct timespec interval;
5703 if (sched_rr_get_interval(pid, &interval)) {
5704 posix_error();
5705 return -1.0;
5706 }
5707 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5708}
5709#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005710
Larry Hastings2f936352014-08-05 14:04:04 +10005711
5712/*[clinic input]
5713os.sched_yield
5714
5715Voluntarily relinquish the CPU.
5716[clinic start generated code]*/
5717
Larry Hastings2f936352014-08-05 14:04:04 +10005718static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005719os_sched_yield_impl(PyObject *module)
5720/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005721{
5722 if (sched_yield())
5723 return posix_error();
5724 Py_RETURN_NONE;
5725}
5726
Benjamin Peterson2740af82011-08-02 17:41:34 -05005727#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005728/* The minimum number of CPUs allocated in a cpu_set_t */
5729static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005730
Larry Hastings2f936352014-08-05 14:04:04 +10005731/*[clinic input]
5732os.sched_setaffinity
5733 pid: pid_t
5734 mask : object
5735 /
5736
5737Set the CPU affinity of the process identified by pid to mask.
5738
5739mask should be an iterable of integers identifying CPUs.
5740[clinic start generated code]*/
5741
Larry Hastings2f936352014-08-05 14:04:04 +10005742static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005743os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5744/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005745{
Antoine Pitrou84869872012-08-04 16:16:35 +02005746 int ncpus;
5747 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005748 cpu_set_t *cpu_set = NULL;
5749 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005750
Larry Hastings2f936352014-08-05 14:04:04 +10005751 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005752 if (iterator == NULL)
5753 return NULL;
5754
5755 ncpus = NCPUS_START;
5756 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005757 cpu_set = CPU_ALLOC(ncpus);
5758 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005759 PyErr_NoMemory();
5760 goto error;
5761 }
Larry Hastings2f936352014-08-05 14:04:04 +10005762 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005763
5764 while ((item = PyIter_Next(iterator))) {
5765 long cpu;
5766 if (!PyLong_Check(item)) {
5767 PyErr_Format(PyExc_TypeError,
5768 "expected an iterator of ints, "
5769 "but iterator yielded %R",
5770 Py_TYPE(item));
5771 Py_DECREF(item);
5772 goto error;
5773 }
5774 cpu = PyLong_AsLong(item);
5775 Py_DECREF(item);
5776 if (cpu < 0) {
5777 if (!PyErr_Occurred())
5778 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5779 goto error;
5780 }
5781 if (cpu > INT_MAX - 1) {
5782 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5783 goto error;
5784 }
5785 if (cpu >= ncpus) {
5786 /* Grow CPU mask to fit the CPU number */
5787 int newncpus = ncpus;
5788 cpu_set_t *newmask;
5789 size_t newsetsize;
5790 while (newncpus <= cpu) {
5791 if (newncpus > INT_MAX / 2)
5792 newncpus = cpu + 1;
5793 else
5794 newncpus = newncpus * 2;
5795 }
5796 newmask = CPU_ALLOC(newncpus);
5797 if (newmask == NULL) {
5798 PyErr_NoMemory();
5799 goto error;
5800 }
5801 newsetsize = CPU_ALLOC_SIZE(newncpus);
5802 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005803 memcpy(newmask, cpu_set, setsize);
5804 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005805 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005806 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005807 ncpus = newncpus;
5808 }
Larry Hastings2f936352014-08-05 14:04:04 +10005809 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005810 }
5811 Py_CLEAR(iterator);
5812
Larry Hastings2f936352014-08-05 14:04:04 +10005813 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005814 posix_error();
5815 goto error;
5816 }
Larry Hastings2f936352014-08-05 14:04:04 +10005817 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005818 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005819
5820error:
Larry Hastings2f936352014-08-05 14:04:04 +10005821 if (cpu_set)
5822 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005823 Py_XDECREF(iterator);
5824 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005825}
5826
Larry Hastings2f936352014-08-05 14:04:04 +10005827
5828/*[clinic input]
5829os.sched_getaffinity
5830 pid: pid_t
5831 /
5832
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005833Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005834
5835The affinity is returned as a set of CPU identifiers.
5836[clinic start generated code]*/
5837
Larry Hastings2f936352014-08-05 14:04:04 +10005838static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005839os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005840/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005841{
Antoine Pitrou84869872012-08-04 16:16:35 +02005842 int cpu, ncpus, count;
5843 size_t setsize;
5844 cpu_set_t *mask = NULL;
5845 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005846
Antoine Pitrou84869872012-08-04 16:16:35 +02005847 ncpus = NCPUS_START;
5848 while (1) {
5849 setsize = CPU_ALLOC_SIZE(ncpus);
5850 mask = CPU_ALLOC(ncpus);
5851 if (mask == NULL)
5852 return PyErr_NoMemory();
5853 if (sched_getaffinity(pid, setsize, mask) == 0)
5854 break;
5855 CPU_FREE(mask);
5856 if (errno != EINVAL)
5857 return posix_error();
5858 if (ncpus > INT_MAX / 2) {
5859 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5860 "a large enough CPU set");
5861 return NULL;
5862 }
5863 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005864 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005865
5866 res = PySet_New(NULL);
5867 if (res == NULL)
5868 goto error;
5869 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5870 if (CPU_ISSET_S(cpu, setsize, mask)) {
5871 PyObject *cpu_num = PyLong_FromLong(cpu);
5872 --count;
5873 if (cpu_num == NULL)
5874 goto error;
5875 if (PySet_Add(res, cpu_num)) {
5876 Py_DECREF(cpu_num);
5877 goto error;
5878 }
5879 Py_DECREF(cpu_num);
5880 }
5881 }
5882 CPU_FREE(mask);
5883 return res;
5884
5885error:
5886 if (mask)
5887 CPU_FREE(mask);
5888 Py_XDECREF(res);
5889 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005890}
5891
Benjamin Peterson2740af82011-08-02 17:41:34 -05005892#endif /* HAVE_SCHED_SETAFFINITY */
5893
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005894#endif /* HAVE_SCHED_H */
5895
Larry Hastings2f936352014-08-05 14:04:04 +10005896
Neal Norwitzb59798b2003-03-21 01:43:31 +00005897/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005898/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5899#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005900#define DEV_PTY_FILE "/dev/ptc"
5901#define HAVE_DEV_PTMX
5902#else
5903#define DEV_PTY_FILE "/dev/ptmx"
5904#endif
5905
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005906#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005907#ifdef HAVE_PTY_H
5908#include <pty.h>
5909#else
5910#ifdef HAVE_LIBUTIL_H
5911#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005912#else
5913#ifdef HAVE_UTIL_H
5914#include <util.h>
5915#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005916#endif /* HAVE_LIBUTIL_H */
5917#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005918#ifdef HAVE_STROPTS_H
5919#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005920#endif
5921#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005922
Larry Hastings2f936352014-08-05 14:04:04 +10005923
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005924#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005925/*[clinic input]
5926os.openpty
5927
5928Open a pseudo-terminal.
5929
5930Return a tuple of (master_fd, slave_fd) containing open file descriptors
5931for both the master and slave ends.
5932[clinic start generated code]*/
5933
Larry Hastings2f936352014-08-05 14:04:04 +10005934static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005935os_openpty_impl(PyObject *module)
5936/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005937{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005938 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005939#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005940 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005941#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005942#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005944#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005945 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005946#endif
5947#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005948
Thomas Wouters70c21a12000-07-14 14:28:33 +00005949#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005950 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005951 goto posix_error;
5952
5953 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5954 goto error;
5955 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5956 goto error;
5957
Neal Norwitzb59798b2003-03-21 01:43:31 +00005958#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005959 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5960 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005961 goto posix_error;
5962 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5963 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005964
Victor Stinnerdaf45552013-08-28 00:53:59 +02005965 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005966 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005967 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005968
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005969#else
Victor Stinner000de532013-11-25 23:19:58 +01005970 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005971 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005972 goto posix_error;
5973
Victor Stinner8c62be82010-05-06 00:08:46 +00005974 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005975
Victor Stinner8c62be82010-05-06 00:08:46 +00005976 /* change permission of slave */
5977 if (grantpt(master_fd) < 0) {
5978 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005979 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005980 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005981
Victor Stinner8c62be82010-05-06 00:08:46 +00005982 /* unlock slave */
5983 if (unlockpt(master_fd) < 0) {
5984 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005985 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005986 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005987
Victor Stinner8c62be82010-05-06 00:08:46 +00005988 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005989
Victor Stinner8c62be82010-05-06 00:08:46 +00005990 slave_name = ptsname(master_fd); /* get name of slave */
5991 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005992 goto posix_error;
5993
5994 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005995 if (slave_fd == -1)
5996 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005997
5998 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5999 goto posix_error;
6000
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006001#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006002 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6003 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006004#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006005 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006006#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006007#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006008#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006009
Victor Stinner8c62be82010-05-06 00:08:46 +00006010 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006011
Victor Stinnerdaf45552013-08-28 00:53:59 +02006012posix_error:
6013 posix_error();
6014error:
6015 if (master_fd != -1)
6016 close(master_fd);
6017 if (slave_fd != -1)
6018 close(slave_fd);
6019 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006020}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006021#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006022
Larry Hastings2f936352014-08-05 14:04:04 +10006023
Fred Drake8cef4cf2000-06-28 16:40:38 +00006024#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006025/*[clinic input]
6026os.forkpty
6027
6028Fork a new process with a new pseudo-terminal as controlling tty.
6029
6030Returns a tuple of (pid, master_fd).
6031Like fork(), return pid of 0 to the child process,
6032and pid of child to the parent process.
6033To both, return fd of newly opened pseudo-terminal.
6034[clinic start generated code]*/
6035
Larry Hastings2f936352014-08-05 14:04:04 +10006036static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006037os_forkpty_impl(PyObject *module)
6038/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006039{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006040 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006041 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006042
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006043 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006044 pid = forkpty(&master_fd, NULL, NULL, NULL);
6045 if (pid == 0) {
6046 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006047 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006048 } else {
6049 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006050 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006051 }
6052 if (pid == -1)
6053 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006054 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006055}
Larry Hastings2f936352014-08-05 14:04:04 +10006056#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006057
Ross Lagerwall7807c352011-03-17 20:20:30 +02006058
Guido van Rossumad0ee831995-03-01 10:34:45 +00006059#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006060/*[clinic input]
6061os.getegid
6062
6063Return the current process's effective group id.
6064[clinic start generated code]*/
6065
Larry Hastings2f936352014-08-05 14:04:04 +10006066static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006067os_getegid_impl(PyObject *module)
6068/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006069{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006070 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006071}
Larry Hastings2f936352014-08-05 14:04:04 +10006072#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006073
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006074
Guido van Rossumad0ee831995-03-01 10:34:45 +00006075#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006076/*[clinic input]
6077os.geteuid
6078
6079Return the current process's effective user id.
6080[clinic start generated code]*/
6081
Larry Hastings2f936352014-08-05 14:04:04 +10006082static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006083os_geteuid_impl(PyObject *module)
6084/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006085{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006086 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006087}
Larry Hastings2f936352014-08-05 14:04:04 +10006088#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006089
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006090
Guido van Rossumad0ee831995-03-01 10:34:45 +00006091#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006092/*[clinic input]
6093os.getgid
6094
6095Return the current process's group id.
6096[clinic start generated code]*/
6097
Larry Hastings2f936352014-08-05 14:04:04 +10006098static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006099os_getgid_impl(PyObject *module)
6100/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006101{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006102 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006103}
Larry Hastings2f936352014-08-05 14:04:04 +10006104#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006105
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006106
Berker Peksag39404992016-09-15 20:45:16 +03006107#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006108/*[clinic input]
6109os.getpid
6110
6111Return the current process id.
6112[clinic start generated code]*/
6113
Larry Hastings2f936352014-08-05 14:04:04 +10006114static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006115os_getpid_impl(PyObject *module)
6116/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006117{
Victor Stinner8c62be82010-05-06 00:08:46 +00006118 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006119}
Berker Peksag39404992016-09-15 20:45:16 +03006120#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006121
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006122#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006123
6124/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006125PyDoc_STRVAR(posix_getgrouplist__doc__,
6126"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6127Returns a list of groups to which a user belongs.\n\n\
6128 user: username to lookup\n\
6129 group: base group id of the user");
6130
6131static PyObject *
6132posix_getgrouplist(PyObject *self, PyObject *args)
6133{
6134#ifdef NGROUPS_MAX
6135#define MAX_GROUPS NGROUPS_MAX
6136#else
6137 /* defined to be 16 on Solaris7, so this should be a small number */
6138#define MAX_GROUPS 64
6139#endif
6140
6141 const char *user;
6142 int i, ngroups;
6143 PyObject *list;
6144#ifdef __APPLE__
6145 int *groups, basegid;
6146#else
6147 gid_t *groups, basegid;
6148#endif
6149 ngroups = MAX_GROUPS;
6150
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006151#ifdef __APPLE__
6152 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006153 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006154#else
6155 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6156 _Py_Gid_Converter, &basegid))
6157 return NULL;
6158#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006159
6160#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006161 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006162#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006163 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006164#endif
6165 if (groups == NULL)
6166 return PyErr_NoMemory();
6167
6168 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6169 PyMem_Del(groups);
6170 return posix_error();
6171 }
6172
6173 list = PyList_New(ngroups);
6174 if (list == NULL) {
6175 PyMem_Del(groups);
6176 return NULL;
6177 }
6178
6179 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006180#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006181 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006182#else
6183 PyObject *o = _PyLong_FromGid(groups[i]);
6184#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006185 if (o == NULL) {
6186 Py_DECREF(list);
6187 PyMem_Del(groups);
6188 return NULL;
6189 }
6190 PyList_SET_ITEM(list, i, o);
6191 }
6192
6193 PyMem_Del(groups);
6194
6195 return list;
6196}
Larry Hastings2f936352014-08-05 14:04:04 +10006197#endif /* HAVE_GETGROUPLIST */
6198
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006199
Fred Drakec9680921999-12-13 16:37:25 +00006200#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006201/*[clinic input]
6202os.getgroups
6203
6204Return list of supplemental group IDs for the process.
6205[clinic start generated code]*/
6206
Larry Hastings2f936352014-08-05 14:04:04 +10006207static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006208os_getgroups_impl(PyObject *module)
6209/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006210{
6211 PyObject *result = NULL;
6212
Fred Drakec9680921999-12-13 16:37:25 +00006213#ifdef NGROUPS_MAX
6214#define MAX_GROUPS NGROUPS_MAX
6215#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006216 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006217#define MAX_GROUPS 64
6218#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006219 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006220
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006221 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006222 * This is a helper variable to store the intermediate result when
6223 * that happens.
6224 *
6225 * To keep the code readable the OSX behaviour is unconditional,
6226 * according to the POSIX spec this should be safe on all unix-y
6227 * systems.
6228 */
6229 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006230 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006231
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006232#ifdef __APPLE__
6233 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6234 * there are more groups than can fit in grouplist. Therefore, on OS X
6235 * always first call getgroups with length 0 to get the actual number
6236 * of groups.
6237 */
6238 n = getgroups(0, NULL);
6239 if (n < 0) {
6240 return posix_error();
6241 } else if (n <= MAX_GROUPS) {
6242 /* groups will fit in existing array */
6243 alt_grouplist = grouplist;
6244 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006245 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006246 if (alt_grouplist == NULL) {
6247 errno = EINVAL;
6248 return posix_error();
6249 }
6250 }
6251
6252 n = getgroups(n, alt_grouplist);
6253 if (n == -1) {
6254 if (alt_grouplist != grouplist) {
6255 PyMem_Free(alt_grouplist);
6256 }
6257 return posix_error();
6258 }
6259#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006260 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006261 if (n < 0) {
6262 if (errno == EINVAL) {
6263 n = getgroups(0, NULL);
6264 if (n == -1) {
6265 return posix_error();
6266 }
6267 if (n == 0) {
6268 /* Avoid malloc(0) */
6269 alt_grouplist = grouplist;
6270 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006271 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006272 if (alt_grouplist == NULL) {
6273 errno = EINVAL;
6274 return posix_error();
6275 }
6276 n = getgroups(n, alt_grouplist);
6277 if (n == -1) {
6278 PyMem_Free(alt_grouplist);
6279 return posix_error();
6280 }
6281 }
6282 } else {
6283 return posix_error();
6284 }
6285 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006286#endif
6287
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006288 result = PyList_New(n);
6289 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006290 int i;
6291 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006292 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006294 Py_DECREF(result);
6295 result = NULL;
6296 break;
Fred Drakec9680921999-12-13 16:37:25 +00006297 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006298 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006299 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006300 }
6301
6302 if (alt_grouplist != grouplist) {
6303 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006304 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006305
Fred Drakec9680921999-12-13 16:37:25 +00006306 return result;
6307}
Larry Hastings2f936352014-08-05 14:04:04 +10006308#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006309
Antoine Pitroub7572f02009-12-02 20:46:48 +00006310#ifdef HAVE_INITGROUPS
6311PyDoc_STRVAR(posix_initgroups__doc__,
6312"initgroups(username, gid) -> None\n\n\
6313Call the system initgroups() to initialize the group access list with all of\n\
6314the groups of which the specified username is a member, plus the specified\n\
6315group id.");
6316
Larry Hastings2f936352014-08-05 14:04:04 +10006317/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006318static PyObject *
6319posix_initgroups(PyObject *self, PyObject *args)
6320{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006321 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006322 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006323 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006324#ifdef __APPLE__
6325 int gid;
6326#else
6327 gid_t gid;
6328#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006329
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006330#ifdef __APPLE__
6331 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6332 PyUnicode_FSConverter, &oname,
6333 &gid))
6334#else
6335 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6336 PyUnicode_FSConverter, &oname,
6337 _Py_Gid_Converter, &gid))
6338#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006339 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006340 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006341
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006342 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006343 Py_DECREF(oname);
6344 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006345 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006346
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006347 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006348}
Larry Hastings2f936352014-08-05 14:04:04 +10006349#endif /* HAVE_INITGROUPS */
6350
Antoine Pitroub7572f02009-12-02 20:46:48 +00006351
Martin v. Löwis606edc12002-06-13 21:09:11 +00006352#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006353/*[clinic input]
6354os.getpgid
6355
6356 pid: pid_t
6357
6358Call the system call getpgid(), and return the result.
6359[clinic start generated code]*/
6360
Larry Hastings2f936352014-08-05 14:04:04 +10006361static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006362os_getpgid_impl(PyObject *module, pid_t pid)
6363/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006364{
6365 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006366 if (pgid < 0)
6367 return posix_error();
6368 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006369}
6370#endif /* HAVE_GETPGID */
6371
6372
Guido van Rossumb6775db1994-08-01 11:34:53 +00006373#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006374/*[clinic input]
6375os.getpgrp
6376
6377Return the current process group id.
6378[clinic start generated code]*/
6379
Larry Hastings2f936352014-08-05 14:04:04 +10006380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006381os_getpgrp_impl(PyObject *module)
6382/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006383{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006384#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006385 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006386#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006387 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006388#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006389}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006390#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006391
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006392
Guido van Rossumb6775db1994-08-01 11:34:53 +00006393#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006394/*[clinic input]
6395os.setpgrp
6396
6397Make the current process the leader of its process group.
6398[clinic start generated code]*/
6399
Larry Hastings2f936352014-08-05 14:04:04 +10006400static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006401os_setpgrp_impl(PyObject *module)
6402/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006403{
Guido van Rossum64933891994-10-20 21:56:42 +00006404#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006406#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006408#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006409 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006410 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006411}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006412#endif /* HAVE_SETPGRP */
6413
Guido van Rossumad0ee831995-03-01 10:34:45 +00006414#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006415
6416#ifdef MS_WINDOWS
6417#include <tlhelp32.h>
6418
6419static PyObject*
6420win32_getppid()
6421{
6422 HANDLE snapshot;
6423 pid_t mypid;
6424 PyObject* result = NULL;
6425 BOOL have_record;
6426 PROCESSENTRY32 pe;
6427
6428 mypid = getpid(); /* This function never fails */
6429
6430 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6431 if (snapshot == INVALID_HANDLE_VALUE)
6432 return PyErr_SetFromWindowsErr(GetLastError());
6433
6434 pe.dwSize = sizeof(pe);
6435 have_record = Process32First(snapshot, &pe);
6436 while (have_record) {
6437 if (mypid == (pid_t)pe.th32ProcessID) {
6438 /* We could cache the ulong value in a static variable. */
6439 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6440 break;
6441 }
6442
6443 have_record = Process32Next(snapshot, &pe);
6444 }
6445
6446 /* If our loop exits and our pid was not found (result will be NULL)
6447 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6448 * error anyway, so let's raise it. */
6449 if (!result)
6450 result = PyErr_SetFromWindowsErr(GetLastError());
6451
6452 CloseHandle(snapshot);
6453
6454 return result;
6455}
6456#endif /*MS_WINDOWS*/
6457
Larry Hastings2f936352014-08-05 14:04:04 +10006458
6459/*[clinic input]
6460os.getppid
6461
6462Return the parent's process id.
6463
6464If the parent process has already exited, Windows machines will still
6465return its id; others systems will return the id of the 'init' process (1).
6466[clinic start generated code]*/
6467
Larry Hastings2f936352014-08-05 14:04:04 +10006468static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006469os_getppid_impl(PyObject *module)
6470/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006471{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006472#ifdef MS_WINDOWS
6473 return win32_getppid();
6474#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006475 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006476#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006477}
6478#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006479
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006480
Fred Drake12c6e2d1999-12-14 21:25:03 +00006481#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006482/*[clinic input]
6483os.getlogin
6484
6485Return the actual login name.
6486[clinic start generated code]*/
6487
Larry Hastings2f936352014-08-05 14:04:04 +10006488static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006489os_getlogin_impl(PyObject *module)
6490/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006491{
Victor Stinner8c62be82010-05-06 00:08:46 +00006492 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006493#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006494 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006495 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006496
6497 if (GetUserNameW(user_name, &num_chars)) {
6498 /* num_chars is the number of unicode chars plus null terminator */
6499 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006500 }
6501 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006502 result = PyErr_SetFromWindowsErr(GetLastError());
6503#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006504 char *name;
6505 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006506
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 errno = 0;
6508 name = getlogin();
6509 if (name == NULL) {
6510 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006511 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006512 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006513 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006514 }
6515 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006516 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006517 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006518#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006519 return result;
6520}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006521#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006522
Larry Hastings2f936352014-08-05 14:04:04 +10006523
Guido van Rossumad0ee831995-03-01 10:34:45 +00006524#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006525/*[clinic input]
6526os.getuid
6527
6528Return the current process's user id.
6529[clinic start generated code]*/
6530
Larry Hastings2f936352014-08-05 14:04:04 +10006531static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006532os_getuid_impl(PyObject *module)
6533/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006534{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006535 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006536}
Larry Hastings2f936352014-08-05 14:04:04 +10006537#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006538
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006539
Brian Curtineb24d742010-04-12 17:16:38 +00006540#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006541#define HAVE_KILL
6542#endif /* MS_WINDOWS */
6543
6544#ifdef HAVE_KILL
6545/*[clinic input]
6546os.kill
6547
6548 pid: pid_t
6549 signal: Py_ssize_t
6550 /
6551
6552Kill a process with a signal.
6553[clinic start generated code]*/
6554
Larry Hastings2f936352014-08-05 14:04:04 +10006555static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006556os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6557/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006558#ifndef MS_WINDOWS
6559{
6560 if (kill(pid, (int)signal) == -1)
6561 return posix_error();
6562 Py_RETURN_NONE;
6563}
6564#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006565{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006566 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006567 DWORD sig = (DWORD)signal;
6568 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006569 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006570
Victor Stinner8c62be82010-05-06 00:08:46 +00006571 /* Console processes which share a common console can be sent CTRL+C or
6572 CTRL+BREAK events, provided they handle said events. */
6573 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006574 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 err = GetLastError();
6576 PyErr_SetFromWindowsErr(err);
6577 }
6578 else
6579 Py_RETURN_NONE;
6580 }
Brian Curtineb24d742010-04-12 17:16:38 +00006581
Victor Stinner8c62be82010-05-06 00:08:46 +00006582 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6583 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006584 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 if (handle == NULL) {
6586 err = GetLastError();
6587 return PyErr_SetFromWindowsErr(err);
6588 }
Brian Curtineb24d742010-04-12 17:16:38 +00006589
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 if (TerminateProcess(handle, sig) == 0) {
6591 err = GetLastError();
6592 result = PyErr_SetFromWindowsErr(err);
6593 } else {
6594 Py_INCREF(Py_None);
6595 result = Py_None;
6596 }
Brian Curtineb24d742010-04-12 17:16:38 +00006597
Victor Stinner8c62be82010-05-06 00:08:46 +00006598 CloseHandle(handle);
6599 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006600}
Larry Hastings2f936352014-08-05 14:04:04 +10006601#endif /* !MS_WINDOWS */
6602#endif /* HAVE_KILL */
6603
6604
6605#ifdef HAVE_KILLPG
6606/*[clinic input]
6607os.killpg
6608
6609 pgid: pid_t
6610 signal: int
6611 /
6612
6613Kill a process group with a signal.
6614[clinic start generated code]*/
6615
Larry Hastings2f936352014-08-05 14:04:04 +10006616static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006617os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6618/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006619{
6620 /* XXX some man pages make the `pgid` parameter an int, others
6621 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6622 take the same type. Moreover, pid_t is always at least as wide as
6623 int (else compilation of this module fails), which is safe. */
6624 if (killpg(pgid, signal) == -1)
6625 return posix_error();
6626 Py_RETURN_NONE;
6627}
6628#endif /* HAVE_KILLPG */
6629
Brian Curtineb24d742010-04-12 17:16:38 +00006630
Guido van Rossumc0125471996-06-28 18:55:32 +00006631#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006632#ifdef HAVE_SYS_LOCK_H
6633#include <sys/lock.h>
6634#endif
6635
Larry Hastings2f936352014-08-05 14:04:04 +10006636/*[clinic input]
6637os.plock
6638 op: int
6639 /
6640
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006641Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006642[clinic start generated code]*/
6643
Larry Hastings2f936352014-08-05 14:04:04 +10006644static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006645os_plock_impl(PyObject *module, int op)
6646/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006647{
Victor Stinner8c62be82010-05-06 00:08:46 +00006648 if (plock(op) == -1)
6649 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006650 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006651}
Larry Hastings2f936352014-08-05 14:04:04 +10006652#endif /* HAVE_PLOCK */
6653
Guido van Rossumc0125471996-06-28 18:55:32 +00006654
Guido van Rossumb6775db1994-08-01 11:34:53 +00006655#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006656/*[clinic input]
6657os.setuid
6658
6659 uid: uid_t
6660 /
6661
6662Set the current process's user id.
6663[clinic start generated code]*/
6664
Larry Hastings2f936352014-08-05 14:04:04 +10006665static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006666os_setuid_impl(PyObject *module, uid_t uid)
6667/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006668{
Victor Stinner8c62be82010-05-06 00:08:46 +00006669 if (setuid(uid) < 0)
6670 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006671 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006672}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006673#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006674
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006675
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006676#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006677/*[clinic input]
6678os.seteuid
6679
6680 euid: uid_t
6681 /
6682
6683Set the current process's effective user id.
6684[clinic start generated code]*/
6685
Larry Hastings2f936352014-08-05 14:04:04 +10006686static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006687os_seteuid_impl(PyObject *module, uid_t euid)
6688/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006689{
6690 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006692 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006693}
6694#endif /* HAVE_SETEUID */
6695
Larry Hastings2f936352014-08-05 14:04:04 +10006696
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006697#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006698/*[clinic input]
6699os.setegid
6700
6701 egid: gid_t
6702 /
6703
6704Set the current process's effective group id.
6705[clinic start generated code]*/
6706
Larry Hastings2f936352014-08-05 14:04:04 +10006707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006708os_setegid_impl(PyObject *module, gid_t egid)
6709/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006710{
6711 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006713 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006714}
6715#endif /* HAVE_SETEGID */
6716
Larry Hastings2f936352014-08-05 14:04:04 +10006717
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006718#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006719/*[clinic input]
6720os.setreuid
6721
6722 ruid: uid_t
6723 euid: uid_t
6724 /
6725
6726Set the current process's real and effective user ids.
6727[clinic start generated code]*/
6728
Larry Hastings2f936352014-08-05 14:04:04 +10006729static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006730os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6731/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006732{
Victor Stinner8c62be82010-05-06 00:08:46 +00006733 if (setreuid(ruid, euid) < 0) {
6734 return posix_error();
6735 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006736 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006738}
6739#endif /* HAVE_SETREUID */
6740
Larry Hastings2f936352014-08-05 14:04:04 +10006741
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006742#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006743/*[clinic input]
6744os.setregid
6745
6746 rgid: gid_t
6747 egid: gid_t
6748 /
6749
6750Set the current process's real and effective group ids.
6751[clinic start generated code]*/
6752
Larry Hastings2f936352014-08-05 14:04:04 +10006753static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006754os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6755/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006756{
6757 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006758 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006759 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006760}
6761#endif /* HAVE_SETREGID */
6762
Larry Hastings2f936352014-08-05 14:04:04 +10006763
Guido van Rossumb6775db1994-08-01 11:34:53 +00006764#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006765/*[clinic input]
6766os.setgid
6767 gid: gid_t
6768 /
6769
6770Set the current process's group id.
6771[clinic start generated code]*/
6772
Larry Hastings2f936352014-08-05 14:04:04 +10006773static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006774os_setgid_impl(PyObject *module, gid_t gid)
6775/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006776{
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 if (setgid(gid) < 0)
6778 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006779 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006780}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006781#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006782
Larry Hastings2f936352014-08-05 14:04:04 +10006783
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006784#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006785/*[clinic input]
6786os.setgroups
6787
6788 groups: object
6789 /
6790
6791Set the groups of the current process to list.
6792[clinic start generated code]*/
6793
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006794static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006795os_setgroups(PyObject *module, PyObject *groups)
6796/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006797{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006798 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006800
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 if (!PySequence_Check(groups)) {
6802 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6803 return NULL;
6804 }
6805 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006806 if (len < 0) {
6807 return NULL;
6808 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 if (len > MAX_GROUPS) {
6810 PyErr_SetString(PyExc_ValueError, "too many groups");
6811 return NULL;
6812 }
6813 for(i = 0; i < len; i++) {
6814 PyObject *elem;
6815 elem = PySequence_GetItem(groups, i);
6816 if (!elem)
6817 return NULL;
6818 if (!PyLong_Check(elem)) {
6819 PyErr_SetString(PyExc_TypeError,
6820 "groups must be integers");
6821 Py_DECREF(elem);
6822 return NULL;
6823 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006824 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006825 Py_DECREF(elem);
6826 return NULL;
6827 }
6828 }
6829 Py_DECREF(elem);
6830 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006831
Victor Stinner8c62be82010-05-06 00:08:46 +00006832 if (setgroups(len, grouplist) < 0)
6833 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006834 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006835}
6836#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006837
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006838#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6839static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006840wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006841{
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 PyObject *result;
6843 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006844 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006845
Victor Stinner8c62be82010-05-06 00:08:46 +00006846 if (pid == -1)
6847 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006848
Victor Stinner8c62be82010-05-06 00:08:46 +00006849 if (struct_rusage == NULL) {
6850 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6851 if (m == NULL)
6852 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006853 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006854 Py_DECREF(m);
6855 if (struct_rusage == NULL)
6856 return NULL;
6857 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006858
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6860 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6861 if (!result)
6862 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006863
6864#ifndef doubletime
6865#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6866#endif
6867
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006869 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006871 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006872#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6874 SET_INT(result, 2, ru->ru_maxrss);
6875 SET_INT(result, 3, ru->ru_ixrss);
6876 SET_INT(result, 4, ru->ru_idrss);
6877 SET_INT(result, 5, ru->ru_isrss);
6878 SET_INT(result, 6, ru->ru_minflt);
6879 SET_INT(result, 7, ru->ru_majflt);
6880 SET_INT(result, 8, ru->ru_nswap);
6881 SET_INT(result, 9, ru->ru_inblock);
6882 SET_INT(result, 10, ru->ru_oublock);
6883 SET_INT(result, 11, ru->ru_msgsnd);
6884 SET_INT(result, 12, ru->ru_msgrcv);
6885 SET_INT(result, 13, ru->ru_nsignals);
6886 SET_INT(result, 14, ru->ru_nvcsw);
6887 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006888#undef SET_INT
6889
Victor Stinner8c62be82010-05-06 00:08:46 +00006890 if (PyErr_Occurred()) {
6891 Py_DECREF(result);
6892 return NULL;
6893 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006894
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006896}
6897#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6898
Larry Hastings2f936352014-08-05 14:04:04 +10006899
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006900#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006901/*[clinic input]
6902os.wait3
6903
6904 options: int
6905Wait for completion of a child process.
6906
6907Returns a tuple of information about the child process:
6908 (pid, status, rusage)
6909[clinic start generated code]*/
6910
Larry Hastings2f936352014-08-05 14:04:04 +10006911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006912os_wait3_impl(PyObject *module, int options)
6913/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006914{
Victor Stinner8c62be82010-05-06 00:08:46 +00006915 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006917 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006918 WAIT_TYPE status;
6919 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006920
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006921 do {
6922 Py_BEGIN_ALLOW_THREADS
6923 pid = wait3(&status, options, &ru);
6924 Py_END_ALLOW_THREADS
6925 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6926 if (pid < 0)
6927 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006928
Victor Stinner4195b5c2012-02-08 23:03:19 +01006929 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006930}
6931#endif /* HAVE_WAIT3 */
6932
Larry Hastings2f936352014-08-05 14:04:04 +10006933
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006934#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006935/*[clinic input]
6936
6937os.wait4
6938
6939 pid: pid_t
6940 options: int
6941
6942Wait for completion of a specific child process.
6943
6944Returns a tuple of information about the child process:
6945 (pid, status, rusage)
6946[clinic start generated code]*/
6947
Larry Hastings2f936352014-08-05 14:04:04 +10006948static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006949os_wait4_impl(PyObject *module, pid_t pid, int options)
6950/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006951{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006952 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006954 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 WAIT_TYPE status;
6956 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006957
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006958 do {
6959 Py_BEGIN_ALLOW_THREADS
6960 res = wait4(pid, &status, options, &ru);
6961 Py_END_ALLOW_THREADS
6962 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6963 if (res < 0)
6964 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006965
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006966 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006967}
6968#endif /* HAVE_WAIT4 */
6969
Larry Hastings2f936352014-08-05 14:04:04 +10006970
Ross Lagerwall7807c352011-03-17 20:20:30 +02006971#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006972/*[clinic input]
6973os.waitid
6974
6975 idtype: idtype_t
6976 Must be one of be P_PID, P_PGID or P_ALL.
6977 id: id_t
6978 The id to wait on.
6979 options: int
6980 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6981 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6982 /
6983
6984Returns the result of waiting for a process or processes.
6985
6986Returns either waitid_result or None if WNOHANG is specified and there are
6987no children in a waitable state.
6988[clinic start generated code]*/
6989
Larry Hastings2f936352014-08-05 14:04:04 +10006990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006991os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6992/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006993{
6994 PyObject *result;
6995 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006996 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006997 siginfo_t si;
6998 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006999
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007000 do {
7001 Py_BEGIN_ALLOW_THREADS
7002 res = waitid(idtype, id, &si, options);
7003 Py_END_ALLOW_THREADS
7004 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7005 if (res < 0)
7006 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007007
7008 if (si.si_pid == 0)
7009 Py_RETURN_NONE;
7010
7011 result = PyStructSequence_New(&WaitidResultType);
7012 if (!result)
7013 return NULL;
7014
7015 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007016 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007017 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7018 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7019 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7020 if (PyErr_Occurred()) {
7021 Py_DECREF(result);
7022 return NULL;
7023 }
7024
7025 return result;
7026}
Larry Hastings2f936352014-08-05 14:04:04 +10007027#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007028
Larry Hastings2f936352014-08-05 14:04:04 +10007029
7030#if defined(HAVE_WAITPID)
7031/*[clinic input]
7032os.waitpid
7033 pid: pid_t
7034 options: int
7035 /
7036
7037Wait for completion of a given child process.
7038
7039Returns a tuple of information regarding the child process:
7040 (pid, status)
7041
7042The options argument is ignored on Windows.
7043[clinic start generated code]*/
7044
Larry Hastings2f936352014-08-05 14:04:04 +10007045static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007046os_waitpid_impl(PyObject *module, pid_t pid, int options)
7047/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007048{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007049 pid_t res;
7050 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 WAIT_TYPE status;
7052 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007053
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007054 do {
7055 Py_BEGIN_ALLOW_THREADS
7056 res = waitpid(pid, &status, options);
7057 Py_END_ALLOW_THREADS
7058 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7059 if (res < 0)
7060 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007061
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007062 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007063}
Tim Petersab034fa2002-02-01 11:27:43 +00007064#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007065/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007066/*[clinic input]
7067os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007068 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007069 options: int
7070 /
7071
7072Wait for completion of a given process.
7073
7074Returns a tuple of information regarding the process:
7075 (pid, status << 8)
7076
7077The options argument is ignored on Windows.
7078[clinic start generated code]*/
7079
Larry Hastings2f936352014-08-05 14:04:04 +10007080static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007081os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007082/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007083{
7084 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007085 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007086 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007087
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007088 do {
7089 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007090 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007091 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007092 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007093 Py_END_ALLOW_THREADS
7094 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007095 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007096 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007097
Victor Stinner8c62be82010-05-06 00:08:46 +00007098 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007099 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007100}
Larry Hastings2f936352014-08-05 14:04:04 +10007101#endif
7102
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007103
Guido van Rossumad0ee831995-03-01 10:34:45 +00007104#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007105/*[clinic input]
7106os.wait
7107
7108Wait for completion of a child process.
7109
7110Returns a tuple of information about the child process:
7111 (pid, status)
7112[clinic start generated code]*/
7113
Larry Hastings2f936352014-08-05 14:04:04 +10007114static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007115os_wait_impl(PyObject *module)
7116/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007117{
Victor Stinner8c62be82010-05-06 00:08:46 +00007118 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007119 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 WAIT_TYPE status;
7121 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007122
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007123 do {
7124 Py_BEGIN_ALLOW_THREADS
7125 pid = wait(&status);
7126 Py_END_ALLOW_THREADS
7127 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7128 if (pid < 0)
7129 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007130
Victor Stinner8c62be82010-05-06 00:08:46 +00007131 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007132}
Larry Hastings2f936352014-08-05 14:04:04 +10007133#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007134
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007135
Larry Hastings9cf065c2012-06-22 16:30:09 -07007136#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7137PyDoc_STRVAR(readlink__doc__,
7138"readlink(path, *, dir_fd=None) -> path\n\n\
7139Return a string representing the path to which the symbolic link points.\n\
7140\n\
7141If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7142 and path should be relative; path will then be relative to that directory.\n\
7143dir_fd may not be implemented on your platform.\n\
7144 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007145#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007146
Guido van Rossumb6775db1994-08-01 11:34:53 +00007147#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007148
Larry Hastings2f936352014-08-05 14:04:04 +10007149/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007150static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007151posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007152{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007153 path_t path;
7154 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007155 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007156 ssize_t length;
7157 PyObject *return_value = NULL;
7158 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007159
Larry Hastings9cf065c2012-06-22 16:30:09 -07007160 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007161 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007162 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7163 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007164 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007166
Victor Stinner8c62be82010-05-06 00:08:46 +00007167 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007168#ifdef HAVE_READLINKAT
7169 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007170 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007171 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007172#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007173 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007174 Py_END_ALLOW_THREADS
7175
7176 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007177 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007178 goto exit;
7179 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007180 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007181
7182 if (PyUnicode_Check(path.object))
7183 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7184 else
7185 return_value = PyBytes_FromStringAndSize(buffer, length);
7186exit:
7187 path_cleanup(&path);
7188 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007189}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007190
Guido van Rossumb6775db1994-08-01 11:34:53 +00007191#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007192
Larry Hastings2f936352014-08-05 14:04:04 +10007193#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7194
7195static PyObject *
7196win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7197{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007198 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007199 DWORD n_bytes_returned;
7200 DWORD io_result;
7201 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007202 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007203 HANDLE reparse_point_handle;
7204
Martin Panter70214ad2016-08-04 02:38:59 +00007205 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7206 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007207 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007208
7209 static char *keywords[] = {"path", "dir_fd", NULL};
7210
7211 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7212 &po,
7213 dir_fd_unavailable, &dir_fd
7214 ))
7215 return NULL;
7216
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007217 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007218 if (path == NULL)
7219 return NULL;
7220
7221 /* First get a handle to the reparse point */
7222 Py_BEGIN_ALLOW_THREADS
7223 reparse_point_handle = CreateFileW(
7224 path,
7225 0,
7226 0,
7227 0,
7228 OPEN_EXISTING,
7229 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7230 0);
7231 Py_END_ALLOW_THREADS
7232
7233 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7234 return win32_error_object("readlink", po);
7235
7236 Py_BEGIN_ALLOW_THREADS
7237 /* New call DeviceIoControl to read the reparse point */
7238 io_result = DeviceIoControl(
7239 reparse_point_handle,
7240 FSCTL_GET_REPARSE_POINT,
7241 0, 0, /* in buffer */
7242 target_buffer, sizeof(target_buffer),
7243 &n_bytes_returned,
7244 0 /* we're not using OVERLAPPED_IO */
7245 );
7246 CloseHandle(reparse_point_handle);
7247 Py_END_ALLOW_THREADS
7248
7249 if (io_result==0)
7250 return win32_error_object("readlink", po);
7251
7252 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7253 {
7254 PyErr_SetString(PyExc_ValueError,
7255 "not a symbolic link");
7256 return NULL;
7257 }
7258 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7259 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7260
7261 result = PyUnicode_FromWideChar(print_name,
7262 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7263 return result;
7264}
7265
7266#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7267
7268
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007269
Larry Hastings9cf065c2012-06-22 16:30:09 -07007270#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007271
7272#if defined(MS_WINDOWS)
7273
7274/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007275static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007276
Larry Hastings9cf065c2012-06-22 16:30:09 -07007277static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007278check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007279{
7280 HINSTANCE hKernel32;
7281 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007282 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007283 return 1;
7284 hKernel32 = GetModuleHandleW(L"KERNEL32");
7285 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7286 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007287 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007288}
7289
Victor Stinner31b3b922013-06-05 01:49:17 +02007290/* Remove the last portion of the path */
7291static void
7292_dirnameW(WCHAR *path)
7293{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007294 WCHAR *ptr;
7295
7296 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007297 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007298 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007299 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007300 }
7301 *ptr = 0;
7302}
7303
Victor Stinner31b3b922013-06-05 01:49:17 +02007304/* Is this path absolute? */
7305static int
7306_is_absW(const WCHAR *path)
7307{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007308 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7309
7310}
7311
Victor Stinner31b3b922013-06-05 01:49:17 +02007312/* join root and rest with a backslash */
7313static void
7314_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7315{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007316 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007317
Victor Stinner31b3b922013-06-05 01:49:17 +02007318 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007319 wcscpy(dest_path, rest);
7320 return;
7321 }
7322
7323 root_len = wcslen(root);
7324
7325 wcscpy(dest_path, root);
7326 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007327 dest_path[root_len] = L'\\';
7328 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007329 }
7330 wcscpy(dest_path+root_len, rest);
7331}
7332
Victor Stinner31b3b922013-06-05 01:49:17 +02007333/* Return True if the path at src relative to dest is a directory */
7334static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007335_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007336{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007337 WIN32_FILE_ATTRIBUTE_DATA src_info;
7338 WCHAR dest_parent[MAX_PATH];
7339 WCHAR src_resolved[MAX_PATH] = L"";
7340
7341 /* dest_parent = os.path.dirname(dest) */
7342 wcscpy(dest_parent, dest);
7343 _dirnameW(dest_parent);
7344 /* src_resolved = os.path.join(dest_parent, src) */
7345 _joinW(src_resolved, dest_parent, src);
7346 return (
7347 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7348 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7349 );
7350}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007351#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007352
Larry Hastings2f936352014-08-05 14:04:04 +10007353
7354/*[clinic input]
7355os.symlink
7356 src: path_t
7357 dst: path_t
7358 target_is_directory: bool = False
7359 *
7360 dir_fd: dir_fd(requires='symlinkat')=None
7361
7362# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7363
7364Create a symbolic link pointing to src named dst.
7365
7366target_is_directory is required on Windows if the target is to be
7367 interpreted as a directory. (On Windows, symlink requires
7368 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7369 target_is_directory is ignored on non-Windows platforms.
7370
7371If dir_fd is not None, it should be a file descriptor open to a directory,
7372 and path should be relative; path will then be relative to that directory.
7373dir_fd may not be implemented on your platform.
7374 If it is unavailable, using it will raise a NotImplementedError.
7375
7376[clinic start generated code]*/
7377
Larry Hastings2f936352014-08-05 14:04:04 +10007378static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007379os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007380 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007381/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007382{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007383#ifdef MS_WINDOWS
7384 DWORD result;
7385#else
7386 int result;
7387#endif
7388
Larry Hastings9cf065c2012-06-22 16:30:09 -07007389#ifdef MS_WINDOWS
7390 if (!check_CreateSymbolicLink()) {
7391 PyErr_SetString(PyExc_NotImplementedError,
7392 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007393 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007394 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007395 if (!win32_can_symlink) {
7396 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007397 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007398 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007399#endif
7400
Larry Hastings2f936352014-08-05 14:04:04 +10007401 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007402 PyErr_SetString(PyExc_ValueError,
7403 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007404 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007405 }
7406
7407#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007408
Larry Hastings9cf065c2012-06-22 16:30:09 -07007409 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007410 /* if src is a directory, ensure target_is_directory==1 */
7411 target_is_directory |= _check_dirW(src->wide, dst->wide);
7412 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7413 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007414 Py_END_ALLOW_THREADS
7415
Larry Hastings2f936352014-08-05 14:04:04 +10007416 if (!result)
7417 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007418
7419#else
7420
7421 Py_BEGIN_ALLOW_THREADS
7422#if HAVE_SYMLINKAT
7423 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007424 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007425 else
7426#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007427 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007428 Py_END_ALLOW_THREADS
7429
Larry Hastings2f936352014-08-05 14:04:04 +10007430 if (result)
7431 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007432#endif
7433
Larry Hastings2f936352014-08-05 14:04:04 +10007434 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007435}
7436#endif /* HAVE_SYMLINK */
7437
Larry Hastings9cf065c2012-06-22 16:30:09 -07007438
Brian Curtind40e6f72010-07-08 21:39:08 +00007439
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007440
Larry Hastings605a62d2012-06-24 04:33:36 -07007441static PyStructSequence_Field times_result_fields[] = {
7442 {"user", "user time"},
7443 {"system", "system time"},
7444 {"children_user", "user time of children"},
7445 {"children_system", "system time of children"},
7446 {"elapsed", "elapsed time since an arbitrary point in the past"},
7447 {NULL}
7448};
7449
7450PyDoc_STRVAR(times_result__doc__,
7451"times_result: Result from os.times().\n\n\
7452This object may be accessed either as a tuple of\n\
7453 (user, system, children_user, children_system, elapsed),\n\
7454or via the attributes user, system, children_user, children_system,\n\
7455and elapsed.\n\
7456\n\
7457See os.times for more information.");
7458
7459static PyStructSequence_Desc times_result_desc = {
7460 "times_result", /* name */
7461 times_result__doc__, /* doc */
7462 times_result_fields,
7463 5
7464};
7465
7466static PyTypeObject TimesResultType;
7467
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007468#ifdef MS_WINDOWS
7469#define HAVE_TIMES /* mandatory, for the method table */
7470#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007471
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007472#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007473
7474static PyObject *
7475build_times_result(double user, double system,
7476 double children_user, double children_system,
7477 double elapsed)
7478{
7479 PyObject *value = PyStructSequence_New(&TimesResultType);
7480 if (value == NULL)
7481 return NULL;
7482
7483#define SET(i, field) \
7484 { \
7485 PyObject *o = PyFloat_FromDouble(field); \
7486 if (!o) { \
7487 Py_DECREF(value); \
7488 return NULL; \
7489 } \
7490 PyStructSequence_SET_ITEM(value, i, o); \
7491 } \
7492
7493 SET(0, user);
7494 SET(1, system);
7495 SET(2, children_user);
7496 SET(3, children_system);
7497 SET(4, elapsed);
7498
7499#undef SET
7500
7501 return value;
7502}
7503
Larry Hastings605a62d2012-06-24 04:33:36 -07007504
Larry Hastings2f936352014-08-05 14:04:04 +10007505#ifndef MS_WINDOWS
7506#define NEED_TICKS_PER_SECOND
7507static long ticks_per_second = -1;
7508#endif /* MS_WINDOWS */
7509
7510/*[clinic input]
7511os.times
7512
7513Return a collection containing process timing information.
7514
7515The object returned behaves like a named tuple with these fields:
7516 (utime, stime, cutime, cstime, elapsed_time)
7517All fields are floating point numbers.
7518[clinic start generated code]*/
7519
Larry Hastings2f936352014-08-05 14:04:04 +10007520static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007521os_times_impl(PyObject *module)
7522/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007523#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007524{
Victor Stinner8c62be82010-05-06 00:08:46 +00007525 FILETIME create, exit, kernel, user;
7526 HANDLE hProc;
7527 hProc = GetCurrentProcess();
7528 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7529 /* The fields of a FILETIME structure are the hi and lo part
7530 of a 64-bit value expressed in 100 nanosecond units.
7531 1e7 is one second in such units; 1e-7 the inverse.
7532 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7533 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007534 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007535 (double)(user.dwHighDateTime*429.4967296 +
7536 user.dwLowDateTime*1e-7),
7537 (double)(kernel.dwHighDateTime*429.4967296 +
7538 kernel.dwLowDateTime*1e-7),
7539 (double)0,
7540 (double)0,
7541 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007542}
Larry Hastings2f936352014-08-05 14:04:04 +10007543#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007544{
Larry Hastings2f936352014-08-05 14:04:04 +10007545
7546
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007547 struct tms t;
7548 clock_t c;
7549 errno = 0;
7550 c = times(&t);
7551 if (c == (clock_t) -1)
7552 return posix_error();
7553 return build_times_result(
7554 (double)t.tms_utime / ticks_per_second,
7555 (double)t.tms_stime / ticks_per_second,
7556 (double)t.tms_cutime / ticks_per_second,
7557 (double)t.tms_cstime / ticks_per_second,
7558 (double)c / ticks_per_second);
7559}
Larry Hastings2f936352014-08-05 14:04:04 +10007560#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007561#endif /* HAVE_TIMES */
7562
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007563
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007564#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007565/*[clinic input]
7566os.getsid
7567
7568 pid: pid_t
7569 /
7570
7571Call the system call getsid(pid) and return the result.
7572[clinic start generated code]*/
7573
Larry Hastings2f936352014-08-05 14:04:04 +10007574static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007575os_getsid_impl(PyObject *module, pid_t pid)
7576/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007577{
Victor Stinner8c62be82010-05-06 00:08:46 +00007578 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007579 sid = getsid(pid);
7580 if (sid < 0)
7581 return posix_error();
7582 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007583}
7584#endif /* HAVE_GETSID */
7585
7586
Guido van Rossumb6775db1994-08-01 11:34:53 +00007587#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007588/*[clinic input]
7589os.setsid
7590
7591Call the system call setsid().
7592[clinic start generated code]*/
7593
Larry Hastings2f936352014-08-05 14:04:04 +10007594static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007595os_setsid_impl(PyObject *module)
7596/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007597{
Victor Stinner8c62be82010-05-06 00:08:46 +00007598 if (setsid() < 0)
7599 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007600 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007601}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007602#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007603
Larry Hastings2f936352014-08-05 14:04:04 +10007604
Guido van Rossumb6775db1994-08-01 11:34:53 +00007605#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007606/*[clinic input]
7607os.setpgid
7608
7609 pid: pid_t
7610 pgrp: pid_t
7611 /
7612
7613Call the system call setpgid(pid, pgrp).
7614[clinic start generated code]*/
7615
Larry Hastings2f936352014-08-05 14:04:04 +10007616static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007617os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7618/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007619{
Victor Stinner8c62be82010-05-06 00:08:46 +00007620 if (setpgid(pid, pgrp) < 0)
7621 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007622 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007623}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007624#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007625
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007626
Guido van Rossumb6775db1994-08-01 11:34:53 +00007627#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007628/*[clinic input]
7629os.tcgetpgrp
7630
7631 fd: int
7632 /
7633
7634Return the process group associated with the terminal specified by fd.
7635[clinic start generated code]*/
7636
Larry Hastings2f936352014-08-05 14:04:04 +10007637static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007638os_tcgetpgrp_impl(PyObject *module, int fd)
7639/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007640{
7641 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007642 if (pgid < 0)
7643 return posix_error();
7644 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007645}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007646#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007647
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007648
Guido van Rossumb6775db1994-08-01 11:34:53 +00007649#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007650/*[clinic input]
7651os.tcsetpgrp
7652
7653 fd: int
7654 pgid: pid_t
7655 /
7656
7657Set the process group associated with the terminal specified by fd.
7658[clinic start generated code]*/
7659
Larry Hastings2f936352014-08-05 14:04:04 +10007660static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007661os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7662/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007663{
Victor Stinner8c62be82010-05-06 00:08:46 +00007664 if (tcsetpgrp(fd, pgid) < 0)
7665 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007666 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007667}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007668#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007669
Guido van Rossum687dd131993-05-17 08:34:16 +00007670/* Functions acting on file descriptors */
7671
Victor Stinnerdaf45552013-08-28 00:53:59 +02007672#ifdef O_CLOEXEC
7673extern int _Py_open_cloexec_works;
7674#endif
7675
Larry Hastings2f936352014-08-05 14:04:04 +10007676
7677/*[clinic input]
7678os.open -> int
7679 path: path_t
7680 flags: int
7681 mode: int = 0o777
7682 *
7683 dir_fd: dir_fd(requires='openat') = None
7684
7685# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7686
7687Open a file for low level IO. Returns a file descriptor (integer).
7688
7689If dir_fd is not None, it should be a file descriptor open to a directory,
7690 and path should be relative; path will then be relative to that directory.
7691dir_fd may not be implemented on your platform.
7692 If it is unavailable, using it will raise a NotImplementedError.
7693[clinic start generated code]*/
7694
Larry Hastings2f936352014-08-05 14:04:04 +10007695static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007696os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7697/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007698{
7699 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007700 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007701
Victor Stinnerdaf45552013-08-28 00:53:59 +02007702#ifdef O_CLOEXEC
7703 int *atomic_flag_works = &_Py_open_cloexec_works;
7704#elif !defined(MS_WINDOWS)
7705 int *atomic_flag_works = NULL;
7706#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007707
Victor Stinnerdaf45552013-08-28 00:53:59 +02007708#ifdef MS_WINDOWS
7709 flags |= O_NOINHERIT;
7710#elif defined(O_CLOEXEC)
7711 flags |= O_CLOEXEC;
7712#endif
7713
Steve Dower8fc89802015-04-12 00:26:27 -04007714 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007715 do {
7716 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007717#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007718 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007719#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007720#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007721 if (dir_fd != DEFAULT_DIR_FD)
7722 fd = openat(dir_fd, path->narrow, flags, mode);
7723 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007724#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007725 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007726#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007727 Py_END_ALLOW_THREADS
7728 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007729 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007730
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007731 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007732 if (!async_err)
7733 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007734 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007735 }
7736
Victor Stinnerdaf45552013-08-28 00:53:59 +02007737#ifndef MS_WINDOWS
7738 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7739 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007740 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007741 }
7742#endif
7743
Larry Hastings2f936352014-08-05 14:04:04 +10007744 return fd;
7745}
7746
7747
7748/*[clinic input]
7749os.close
7750
7751 fd: int
7752
7753Close a file descriptor.
7754[clinic start generated code]*/
7755
Barry Warsaw53699e91996-12-10 23:23:01 +00007756static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007757os_close_impl(PyObject *module, int fd)
7758/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007759{
Larry Hastings2f936352014-08-05 14:04:04 +10007760 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007761 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7762 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7763 * for more details.
7764 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007765 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007766 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007767 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007768 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 Py_END_ALLOW_THREADS
7770 if (res < 0)
7771 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007772 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007773}
7774
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007775
Larry Hastings2f936352014-08-05 14:04:04 +10007776/*[clinic input]
7777os.closerange
7778
7779 fd_low: int
7780 fd_high: int
7781 /
7782
7783Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7784[clinic start generated code]*/
7785
Larry Hastings2f936352014-08-05 14:04:04 +10007786static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007787os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7788/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007789{
7790 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007792 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007793 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007794 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007795 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 Py_END_ALLOW_THREADS
7797 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007798}
7799
7800
Larry Hastings2f936352014-08-05 14:04:04 +10007801/*[clinic input]
7802os.dup -> int
7803
7804 fd: int
7805 /
7806
7807Return a duplicate of a file descriptor.
7808[clinic start generated code]*/
7809
Larry Hastings2f936352014-08-05 14:04:04 +10007810static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007811os_dup_impl(PyObject *module, int fd)
7812/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007813{
7814 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007815}
7816
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007817
Larry Hastings2f936352014-08-05 14:04:04 +10007818/*[clinic input]
7819os.dup2
7820 fd: int
7821 fd2: int
7822 inheritable: bool=True
7823
7824Duplicate file descriptor.
7825[clinic start generated code]*/
7826
Larry Hastings2f936352014-08-05 14:04:04 +10007827static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007828os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7829/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007830{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007831 int res;
7832#if defined(HAVE_DUP3) && \
7833 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7834 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7835 int dup3_works = -1;
7836#endif
7837
Steve Dower940f33a2016-09-08 11:21:54 -07007838 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007839 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007840
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007841 /* dup2() can fail with EINTR if the target FD is already open, because it
7842 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7843 * upon close(), and therefore below.
7844 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007845#ifdef MS_WINDOWS
7846 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007847 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007848 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007849 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007850 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007851 if (res < 0)
7852 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007853
7854 /* Character files like console cannot be make non-inheritable */
7855 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7856 close(fd2);
7857 return NULL;
7858 }
7859
7860#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7861 Py_BEGIN_ALLOW_THREADS
7862 if (!inheritable)
7863 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7864 else
7865 res = dup2(fd, fd2);
7866 Py_END_ALLOW_THREADS
7867 if (res < 0)
7868 return posix_error();
7869
7870#else
7871
7872#ifdef HAVE_DUP3
7873 if (!inheritable && dup3_works != 0) {
7874 Py_BEGIN_ALLOW_THREADS
7875 res = dup3(fd, fd2, O_CLOEXEC);
7876 Py_END_ALLOW_THREADS
7877 if (res < 0) {
7878 if (dup3_works == -1)
7879 dup3_works = (errno != ENOSYS);
7880 if (dup3_works)
7881 return posix_error();
7882 }
7883 }
7884
7885 if (inheritable || dup3_works == 0)
7886 {
7887#endif
7888 Py_BEGIN_ALLOW_THREADS
7889 res = dup2(fd, fd2);
7890 Py_END_ALLOW_THREADS
7891 if (res < 0)
7892 return posix_error();
7893
7894 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7895 close(fd2);
7896 return NULL;
7897 }
7898#ifdef HAVE_DUP3
7899 }
7900#endif
7901
7902#endif
7903
Larry Hastings2f936352014-08-05 14:04:04 +10007904 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007905}
7906
Larry Hastings2f936352014-08-05 14:04:04 +10007907
Ross Lagerwall7807c352011-03-17 20:20:30 +02007908#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007909/*[clinic input]
7910os.lockf
7911
7912 fd: int
7913 An open file descriptor.
7914 command: int
7915 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7916 length: Py_off_t
7917 The number of bytes to lock, starting at the current position.
7918 /
7919
7920Apply, test or remove a POSIX lock on an open file descriptor.
7921
7922[clinic start generated code]*/
7923
Larry Hastings2f936352014-08-05 14:04:04 +10007924static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007925os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7926/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007927{
7928 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007929
7930 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007931 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007932 Py_END_ALLOW_THREADS
7933
7934 if (res < 0)
7935 return posix_error();
7936
7937 Py_RETURN_NONE;
7938}
Larry Hastings2f936352014-08-05 14:04:04 +10007939#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007940
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007941
Larry Hastings2f936352014-08-05 14:04:04 +10007942/*[clinic input]
7943os.lseek -> Py_off_t
7944
7945 fd: int
7946 position: Py_off_t
7947 how: int
7948 /
7949
7950Set the position of a file descriptor. Return the new position.
7951
7952Return the new cursor position in number of bytes
7953relative to the beginning of the file.
7954[clinic start generated code]*/
7955
Larry Hastings2f936352014-08-05 14:04:04 +10007956static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007957os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7958/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007959{
7960 Py_off_t result;
7961
Guido van Rossum687dd131993-05-17 08:34:16 +00007962#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7964 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007965 case 0: how = SEEK_SET; break;
7966 case 1: how = SEEK_CUR; break;
7967 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007968 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007969#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007970
Victor Stinner8c62be82010-05-06 00:08:46 +00007971 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007972 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007973
Victor Stinner8c62be82010-05-06 00:08:46 +00007974 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007975 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007976#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007977 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007978#else
Larry Hastings2f936352014-08-05 14:04:04 +10007979 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007980#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007981 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007983 if (result < 0)
7984 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007985
Larry Hastings2f936352014-08-05 14:04:04 +10007986 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007987}
7988
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007989
Larry Hastings2f936352014-08-05 14:04:04 +10007990/*[clinic input]
7991os.read
7992 fd: int
7993 length: Py_ssize_t
7994 /
7995
7996Read from a file descriptor. Returns a bytes object.
7997[clinic start generated code]*/
7998
Larry Hastings2f936352014-08-05 14:04:04 +10007999static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008000os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8001/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008002{
Victor Stinner8c62be82010-05-06 00:08:46 +00008003 Py_ssize_t n;
8004 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008005
8006 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 errno = EINVAL;
8008 return posix_error();
8009 }
Larry Hastings2f936352014-08-05 14:04:04 +10008010
8011#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008012 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008013 if (length > INT_MAX)
8014 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008015#endif
8016
8017 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 if (buffer == NULL)
8019 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008020
Victor Stinner66aab0c2015-03-19 22:53:20 +01008021 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8022 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008023 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008024 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 }
Larry Hastings2f936352014-08-05 14:04:04 +10008026
8027 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008028 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008029
Victor Stinner8c62be82010-05-06 00:08:46 +00008030 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008031}
8032
Ross Lagerwall7807c352011-03-17 20:20:30 +02008033#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8034 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008035static Py_ssize_t
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008036iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008037{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008038 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008039 Py_ssize_t blen, total = 0;
8040
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008041 *iov = PyMem_New(struct iovec, cnt);
8042 if (*iov == NULL) {
8043 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008044 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008045 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008046
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008047 *buf = PyMem_New(Py_buffer, cnt);
8048 if (*buf == NULL) {
8049 PyMem_Del(*iov);
8050 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008051 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008052 }
8053
8054 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008055 PyObject *item = PySequence_GetItem(seq, i);
8056 if (item == NULL)
8057 goto fail;
8058 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8059 Py_DECREF(item);
8060 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008061 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008062 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008063 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008064 blen = (*buf)[i].len;
8065 (*iov)[i].iov_len = blen;
8066 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008067 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008068 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008069
8070fail:
8071 PyMem_Del(*iov);
8072 for (j = 0; j < i; j++) {
8073 PyBuffer_Release(&(*buf)[j]);
8074 }
8075 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008076 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008077}
8078
8079static void
8080iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8081{
8082 int i;
8083 PyMem_Del(iov);
8084 for (i = 0; i < cnt; i++) {
8085 PyBuffer_Release(&buf[i]);
8086 }
8087 PyMem_Del(buf);
8088}
8089#endif
8090
Larry Hastings2f936352014-08-05 14:04:04 +10008091
Ross Lagerwall7807c352011-03-17 20:20:30 +02008092#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008093/*[clinic input]
8094os.readv -> Py_ssize_t
8095
8096 fd: int
8097 buffers: object
8098 /
8099
8100Read from a file descriptor fd into an iterable of buffers.
8101
8102The buffers should be mutable buffers accepting bytes.
8103readv will transfer data into each buffer until it is full
8104and then move on to the next buffer in the sequence to hold
8105the rest of the data.
8106
8107readv returns the total number of bytes read,
8108which may be less than the total capacity of all the buffers.
8109[clinic start generated code]*/
8110
Larry Hastings2f936352014-08-05 14:04:04 +10008111static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008112os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8113/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008114{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008115 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008116 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008117 struct iovec *iov;
8118 Py_buffer *buf;
8119
Larry Hastings2f936352014-08-05 14:04:04 +10008120 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008121 PyErr_SetString(PyExc_TypeError,
8122 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008123 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008124 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008125
Larry Hastings2f936352014-08-05 14:04:04 +10008126 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008127 if (cnt < 0)
8128 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008129
8130 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8131 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008132
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008133 do {
8134 Py_BEGIN_ALLOW_THREADS
8135 n = readv(fd, iov, cnt);
8136 Py_END_ALLOW_THREADS
8137 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008138
8139 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008140 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008141 if (!async_err)
8142 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008143 return -1;
8144 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008145
Larry Hastings2f936352014-08-05 14:04:04 +10008146 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008147}
Larry Hastings2f936352014-08-05 14:04:04 +10008148#endif /* HAVE_READV */
8149
Ross Lagerwall7807c352011-03-17 20:20:30 +02008150
8151#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008152/*[clinic input]
8153# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8154os.pread
8155
8156 fd: int
8157 length: int
8158 offset: Py_off_t
8159 /
8160
8161Read a number of bytes from a file descriptor starting at a particular offset.
8162
8163Read length bytes from file descriptor fd, starting at offset bytes from
8164the beginning of the file. The file offset remains unchanged.
8165[clinic start generated code]*/
8166
Larry Hastings2f936352014-08-05 14:04:04 +10008167static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008168os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8169/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008170{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008171 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008172 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008173 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008174
Larry Hastings2f936352014-08-05 14:04:04 +10008175 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008176 errno = EINVAL;
8177 return posix_error();
8178 }
Larry Hastings2f936352014-08-05 14:04:04 +10008179 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008180 if (buffer == NULL)
8181 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008182
8183 do {
8184 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008185 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008186 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008187 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008188 Py_END_ALLOW_THREADS
8189 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8190
Ross Lagerwall7807c352011-03-17 20:20:30 +02008191 if (n < 0) {
8192 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008193 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008194 }
Larry Hastings2f936352014-08-05 14:04:04 +10008195 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008196 _PyBytes_Resize(&buffer, n);
8197 return buffer;
8198}
Larry Hastings2f936352014-08-05 14:04:04 +10008199#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008200
Larry Hastings2f936352014-08-05 14:04:04 +10008201
8202/*[clinic input]
8203os.write -> Py_ssize_t
8204
8205 fd: int
8206 data: Py_buffer
8207 /
8208
8209Write a bytes object to a file descriptor.
8210[clinic start generated code]*/
8211
Larry Hastings2f936352014-08-05 14:04:04 +10008212static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008213os_write_impl(PyObject *module, int fd, Py_buffer *data)
8214/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008215{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008216 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008217}
8218
8219#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008220PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008221"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008222sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008223 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008224Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008225
Larry Hastings2f936352014-08-05 14:04:04 +10008226/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008227static PyObject *
8228posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8229{
8230 int in, out;
8231 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008232 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008233 off_t offset;
8234
8235#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8236#ifndef __APPLE__
8237 Py_ssize_t len;
8238#endif
8239 PyObject *headers = NULL, *trailers = NULL;
8240 Py_buffer *hbuf, *tbuf;
8241 off_t sbytes;
8242 struct sf_hdtr sf;
8243 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008244 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008245 static char *keywords[] = {"out", "in",
8246 "offset", "count",
8247 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008248
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008249 sf.headers = NULL;
8250 sf.trailers = NULL;
8251
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008252#ifdef __APPLE__
8253 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008254 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008255#else
8256 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008257 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008258#endif
8259 &headers, &trailers, &flags))
8260 return NULL;
8261 if (headers != NULL) {
8262 if (!PySequence_Check(headers)) {
8263 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008264 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008265 return NULL;
8266 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008267 Py_ssize_t i = PySequence_Size(headers);
8268 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008269 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008270 if (i > INT_MAX) {
8271 PyErr_SetString(PyExc_OverflowError,
8272 "sendfile() header is too large");
8273 return NULL;
8274 }
8275 if (i > 0) {
8276 sf.hdr_cnt = (int)i;
8277 i = iov_setup(&(sf.headers), &hbuf,
8278 headers, sf.hdr_cnt, PyBUF_SIMPLE);
8279 if (i < 0)
8280 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008281#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008282 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008283#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008284 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008285 }
8286 }
8287 if (trailers != NULL) {
8288 if (!PySequence_Check(trailers)) {
8289 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008290 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008291 return NULL;
8292 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008293 Py_ssize_t i = PySequence_Size(trailers);
8294 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008295 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008296 if (i > INT_MAX) {
8297 PyErr_SetString(PyExc_OverflowError,
8298 "sendfile() trailer is too large");
8299 return NULL;
8300 }
8301 if (i > 0) {
8302 sf.trl_cnt = (int)i;
8303 i = iov_setup(&(sf.trailers), &tbuf,
8304 trailers, sf.trl_cnt, PyBUF_SIMPLE);
8305 if (i < 0)
8306 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008307#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008308 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008309#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008310 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008311 }
8312 }
8313
Steve Dower8fc89802015-04-12 00:26:27 -04008314 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008315 do {
8316 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008317#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008318 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008319#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008320 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008321#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008322 Py_END_ALLOW_THREADS
8323 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008324 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008325
8326 if (sf.headers != NULL)
8327 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8328 if (sf.trailers != NULL)
8329 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8330
8331 if (ret < 0) {
8332 if ((errno == EAGAIN) || (errno == EBUSY)) {
8333 if (sbytes != 0) {
8334 // some data has been sent
8335 goto done;
8336 }
8337 else {
8338 // no data has been sent; upper application is supposed
8339 // to retry on EAGAIN or EBUSY
8340 return posix_error();
8341 }
8342 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008343 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008344 }
8345 goto done;
8346
8347done:
8348 #if !defined(HAVE_LARGEFILE_SUPPORT)
8349 return Py_BuildValue("l", sbytes);
8350 #else
8351 return Py_BuildValue("L", sbytes);
8352 #endif
8353
8354#else
8355 Py_ssize_t count;
8356 PyObject *offobj;
8357 static char *keywords[] = {"out", "in",
8358 "offset", "count", NULL};
8359 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8360 keywords, &out, &in, &offobj, &count))
8361 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008362#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008363 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008364 do {
8365 Py_BEGIN_ALLOW_THREADS
8366 ret = sendfile(out, in, NULL, count);
8367 Py_END_ALLOW_THREADS
8368 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008369 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008370 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008371 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008372 }
8373#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008374 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008375 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008376
8377 do {
8378 Py_BEGIN_ALLOW_THREADS
8379 ret = sendfile(out, in, &offset, count);
8380 Py_END_ALLOW_THREADS
8381 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008382 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008383 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008384 return Py_BuildValue("n", ret);
8385#endif
8386}
Larry Hastings2f936352014-08-05 14:04:04 +10008387#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008388
Larry Hastings2f936352014-08-05 14:04:04 +10008389
8390/*[clinic input]
8391os.fstat
8392
8393 fd : int
8394
8395Perform a stat system call on the given file descriptor.
8396
8397Like stat(), but for an open file descriptor.
8398Equivalent to os.stat(fd).
8399[clinic start generated code]*/
8400
Larry Hastings2f936352014-08-05 14:04:04 +10008401static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008402os_fstat_impl(PyObject *module, int fd)
8403/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008404{
Victor Stinner8c62be82010-05-06 00:08:46 +00008405 STRUCT_STAT st;
8406 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008407 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008408
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008409 do {
8410 Py_BEGIN_ALLOW_THREADS
8411 res = FSTAT(fd, &st);
8412 Py_END_ALLOW_THREADS
8413 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008414 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008415#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008416 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008417#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008418 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008419#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008420 }
Tim Peters5aa91602002-01-30 05:46:57 +00008421
Victor Stinner4195b5c2012-02-08 23:03:19 +01008422 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008423}
8424
Larry Hastings2f936352014-08-05 14:04:04 +10008425
8426/*[clinic input]
8427os.isatty -> bool
8428 fd: int
8429 /
8430
8431Return True if the fd is connected to a terminal.
8432
8433Return True if the file descriptor is an open file descriptor
8434connected to the slave end of a terminal.
8435[clinic start generated code]*/
8436
Larry Hastings2f936352014-08-05 14:04:04 +10008437static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008438os_isatty_impl(PyObject *module, int fd)
8439/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008440{
Steve Dower8fc89802015-04-12 00:26:27 -04008441 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008442 _Py_BEGIN_SUPPRESS_IPH
8443 return_value = isatty(fd);
8444 _Py_END_SUPPRESS_IPH
8445 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008446}
8447
8448
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008449#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008450/*[clinic input]
8451os.pipe
8452
8453Create a pipe.
8454
8455Returns a tuple of two file descriptors:
8456 (read_fd, write_fd)
8457[clinic start generated code]*/
8458
Larry Hastings2f936352014-08-05 14:04:04 +10008459static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008460os_pipe_impl(PyObject *module)
8461/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008462{
Victor Stinner8c62be82010-05-06 00:08:46 +00008463 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008464#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008465 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008466 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008467 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008468#else
8469 int res;
8470#endif
8471
8472#ifdef MS_WINDOWS
8473 attr.nLength = sizeof(attr);
8474 attr.lpSecurityDescriptor = NULL;
8475 attr.bInheritHandle = FALSE;
8476
8477 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008478 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008479 ok = CreatePipe(&read, &write, &attr, 0);
8480 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008481 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8482 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008483 if (fds[0] == -1 || fds[1] == -1) {
8484 CloseHandle(read);
8485 CloseHandle(write);
8486 ok = 0;
8487 }
8488 }
Steve Dowerc3630612016-11-19 18:41:16 -08008489 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008490 Py_END_ALLOW_THREADS
8491
Victor Stinner8c62be82010-05-06 00:08:46 +00008492 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008493 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008494#else
8495
8496#ifdef HAVE_PIPE2
8497 Py_BEGIN_ALLOW_THREADS
8498 res = pipe2(fds, O_CLOEXEC);
8499 Py_END_ALLOW_THREADS
8500
8501 if (res != 0 && errno == ENOSYS)
8502 {
8503#endif
8504 Py_BEGIN_ALLOW_THREADS
8505 res = pipe(fds);
8506 Py_END_ALLOW_THREADS
8507
8508 if (res == 0) {
8509 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8510 close(fds[0]);
8511 close(fds[1]);
8512 return NULL;
8513 }
8514 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8515 close(fds[0]);
8516 close(fds[1]);
8517 return NULL;
8518 }
8519 }
8520#ifdef HAVE_PIPE2
8521 }
8522#endif
8523
8524 if (res != 0)
8525 return PyErr_SetFromErrno(PyExc_OSError);
8526#endif /* !MS_WINDOWS */
8527 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008528}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008529#endif /* HAVE_PIPE */
8530
Larry Hastings2f936352014-08-05 14:04:04 +10008531
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008532#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008533/*[clinic input]
8534os.pipe2
8535
8536 flags: int
8537 /
8538
8539Create a pipe with flags set atomically.
8540
8541Returns a tuple of two file descriptors:
8542 (read_fd, write_fd)
8543
8544flags can be constructed by ORing together one or more of these values:
8545O_NONBLOCK, O_CLOEXEC.
8546[clinic start generated code]*/
8547
Larry Hastings2f936352014-08-05 14:04:04 +10008548static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008549os_pipe2_impl(PyObject *module, int flags)
8550/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008551{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008552 int fds[2];
8553 int res;
8554
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008555 res = pipe2(fds, flags);
8556 if (res != 0)
8557 return posix_error();
8558 return Py_BuildValue("(ii)", fds[0], fds[1]);
8559}
8560#endif /* HAVE_PIPE2 */
8561
Larry Hastings2f936352014-08-05 14:04:04 +10008562
Ross Lagerwall7807c352011-03-17 20:20:30 +02008563#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008564/*[clinic input]
8565os.writev -> Py_ssize_t
8566 fd: int
8567 buffers: object
8568 /
8569
8570Iterate over buffers, and write the contents of each to a file descriptor.
8571
8572Returns the total number of bytes written.
8573buffers must be a sequence of bytes-like objects.
8574[clinic start generated code]*/
8575
Larry Hastings2f936352014-08-05 14:04:04 +10008576static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008577os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8578/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008579{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008580 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008581 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008582 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008583 struct iovec *iov;
8584 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008585
8586 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008587 PyErr_SetString(PyExc_TypeError,
8588 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008589 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008590 }
Larry Hastings2f936352014-08-05 14:04:04 +10008591 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008592 if (cnt < 0)
8593 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008594
Larry Hastings2f936352014-08-05 14:04:04 +10008595 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8596 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008597 }
8598
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008599 do {
8600 Py_BEGIN_ALLOW_THREADS
8601 result = writev(fd, iov, cnt);
8602 Py_END_ALLOW_THREADS
8603 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008604
8605 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008606 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008607 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008608
Georg Brandl306336b2012-06-24 12:55:33 +02008609 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008610}
Larry Hastings2f936352014-08-05 14:04:04 +10008611#endif /* HAVE_WRITEV */
8612
8613
8614#ifdef HAVE_PWRITE
8615/*[clinic input]
8616os.pwrite -> Py_ssize_t
8617
8618 fd: int
8619 buffer: Py_buffer
8620 offset: Py_off_t
8621 /
8622
8623Write bytes to a file descriptor starting at a particular offset.
8624
8625Write buffer to fd, starting at offset bytes from the beginning of
8626the file. Returns the number of bytes writte. Does not change the
8627current file offset.
8628[clinic start generated code]*/
8629
Larry Hastings2f936352014-08-05 14:04:04 +10008630static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008631os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8632/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008633{
8634 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008635 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008636
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008637 do {
8638 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008639 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008640 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008641 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008642 Py_END_ALLOW_THREADS
8643 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008644
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008645 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008646 posix_error();
8647 return size;
8648}
8649#endif /* HAVE_PWRITE */
8650
8651
8652#ifdef HAVE_MKFIFO
8653/*[clinic input]
8654os.mkfifo
8655
8656 path: path_t
8657 mode: int=0o666
8658 *
8659 dir_fd: dir_fd(requires='mkfifoat')=None
8660
8661Create a "fifo" (a POSIX named pipe).
8662
8663If dir_fd is not None, it should be a file descriptor open to a directory,
8664 and path should be relative; path will then be relative to that directory.
8665dir_fd may not be implemented on your platform.
8666 If it is unavailable, using it will raise a NotImplementedError.
8667[clinic start generated code]*/
8668
Larry Hastings2f936352014-08-05 14:04:04 +10008669static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008670os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8671/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008672{
8673 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008674 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008675
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008676 do {
8677 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008678#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008679 if (dir_fd != DEFAULT_DIR_FD)
8680 result = mkfifoat(dir_fd, path->narrow, mode);
8681 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008682#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008683 result = mkfifo(path->narrow, mode);
8684 Py_END_ALLOW_THREADS
8685 } while (result != 0 && errno == EINTR &&
8686 !(async_err = PyErr_CheckSignals()));
8687 if (result != 0)
8688 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008689
8690 Py_RETURN_NONE;
8691}
8692#endif /* HAVE_MKFIFO */
8693
8694
8695#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8696/*[clinic input]
8697os.mknod
8698
8699 path: path_t
8700 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008701 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008702 *
8703 dir_fd: dir_fd(requires='mknodat')=None
8704
8705Create a node in the file system.
8706
8707Create a node in the file system (file, device special file or named pipe)
8708at path. mode specifies both the permissions to use and the
8709type of node to be created, being combined (bitwise OR) with one of
8710S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8711device defines the newly created device special file (probably using
8712os.makedev()). Otherwise device is ignored.
8713
8714If dir_fd is not None, it should be a file descriptor open to a directory,
8715 and path should be relative; path will then be relative to that directory.
8716dir_fd may not be implemented on your platform.
8717 If it is unavailable, using it will raise a NotImplementedError.
8718[clinic start generated code]*/
8719
Larry Hastings2f936352014-08-05 14:04:04 +10008720static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008721os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008722 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008723/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008724{
8725 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008726 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008727
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008728 do {
8729 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008730#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008731 if (dir_fd != DEFAULT_DIR_FD)
8732 result = mknodat(dir_fd, path->narrow, mode, device);
8733 else
Larry Hastings2f936352014-08-05 14:04:04 +10008734#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008735 result = mknod(path->narrow, mode, device);
8736 Py_END_ALLOW_THREADS
8737 } while (result != 0 && errno == EINTR &&
8738 !(async_err = PyErr_CheckSignals()));
8739 if (result != 0)
8740 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008741
8742 Py_RETURN_NONE;
8743}
8744#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8745
8746
8747#ifdef HAVE_DEVICE_MACROS
8748/*[clinic input]
8749os.major -> unsigned_int
8750
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008751 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008752 /
8753
8754Extracts a device major number from a raw device number.
8755[clinic start generated code]*/
8756
Larry Hastings2f936352014-08-05 14:04:04 +10008757static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008758os_major_impl(PyObject *module, dev_t device)
8759/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008760{
8761 return major(device);
8762}
8763
8764
8765/*[clinic input]
8766os.minor -> unsigned_int
8767
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008768 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008769 /
8770
8771Extracts a device minor number from a raw device number.
8772[clinic start generated code]*/
8773
Larry Hastings2f936352014-08-05 14:04:04 +10008774static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008775os_minor_impl(PyObject *module, dev_t device)
8776/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008777{
8778 return minor(device);
8779}
8780
8781
8782/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008783os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008784
8785 major: int
8786 minor: int
8787 /
8788
8789Composes a raw device number from the major and minor device numbers.
8790[clinic start generated code]*/
8791
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008792static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008793os_makedev_impl(PyObject *module, int major, int minor)
8794/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008795{
8796 return makedev(major, minor);
8797}
8798#endif /* HAVE_DEVICE_MACROS */
8799
8800
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008801#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008802/*[clinic input]
8803os.ftruncate
8804
8805 fd: int
8806 length: Py_off_t
8807 /
8808
8809Truncate a file, specified by file descriptor, to a specific length.
8810[clinic start generated code]*/
8811
Larry Hastings2f936352014-08-05 14:04:04 +10008812static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008813os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8814/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008815{
8816 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008817 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008818
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008819 do {
8820 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008821 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008822#ifdef MS_WINDOWS
8823 result = _chsize_s(fd, length);
8824#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008825 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008826#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008827 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008828 Py_END_ALLOW_THREADS
8829 } while (result != 0 && errno == EINTR &&
8830 !(async_err = PyErr_CheckSignals()));
8831 if (result != 0)
8832 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008833 Py_RETURN_NONE;
8834}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008835#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008836
8837
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008838#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008839/*[clinic input]
8840os.truncate
8841 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8842 length: Py_off_t
8843
8844Truncate a file, specified by path, to a specific length.
8845
8846On some platforms, path may also be specified as an open file descriptor.
8847 If this functionality is unavailable, using it raises an exception.
8848[clinic start generated code]*/
8849
Larry Hastings2f936352014-08-05 14:04:04 +10008850static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008851os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8852/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008853{
8854 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008855#ifdef MS_WINDOWS
8856 int fd;
8857#endif
8858
8859 if (path->fd != -1)
8860 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008861
8862 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008863 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008864#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008865 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008866 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008867 result = -1;
8868 else {
8869 result = _chsize_s(fd, length);
8870 close(fd);
8871 if (result < 0)
8872 errno = result;
8873 }
8874#else
8875 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008876#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008877 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008878 Py_END_ALLOW_THREADS
8879 if (result < 0)
8880 return path_error(path);
8881
8882 Py_RETURN_NONE;
8883}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008884#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008885
Ross Lagerwall7807c352011-03-17 20:20:30 +02008886
Victor Stinnerd6b17692014-09-30 12:20:05 +02008887/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8888 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8889 defined, which is the case in Python on AIX. AIX bug report:
8890 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8891#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8892# define POSIX_FADVISE_AIX_BUG
8893#endif
8894
Victor Stinnerec39e262014-09-30 12:35:58 +02008895
Victor Stinnerd6b17692014-09-30 12:20:05 +02008896#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008897/*[clinic input]
8898os.posix_fallocate
8899
8900 fd: int
8901 offset: Py_off_t
8902 length: Py_off_t
8903 /
8904
8905Ensure a file has allocated at least a particular number of bytes on disk.
8906
8907Ensure that the file specified by fd encompasses a range of bytes
8908starting at offset bytes from the beginning and continuing for length bytes.
8909[clinic start generated code]*/
8910
Larry Hastings2f936352014-08-05 14:04:04 +10008911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008912os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008913 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008914/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008915{
8916 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008917 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008918
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008919 do {
8920 Py_BEGIN_ALLOW_THREADS
8921 result = posix_fallocate(fd, offset, length);
8922 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05008923 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
8924
8925 if (result == 0)
8926 Py_RETURN_NONE;
8927
8928 if (async_err)
8929 return NULL;
8930
8931 errno = result;
8932 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02008933}
Victor Stinnerec39e262014-09-30 12:35:58 +02008934#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008935
Ross Lagerwall7807c352011-03-17 20:20:30 +02008936
Victor Stinnerd6b17692014-09-30 12:20:05 +02008937#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008938/*[clinic input]
8939os.posix_fadvise
8940
8941 fd: int
8942 offset: Py_off_t
8943 length: Py_off_t
8944 advice: int
8945 /
8946
8947Announce an intention to access data in a specific pattern.
8948
8949Announce an intention to access data in a specific pattern, thus allowing
8950the kernel to make optimizations.
8951The advice applies to the region of the file specified by fd starting at
8952offset and continuing for length bytes.
8953advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8954POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8955POSIX_FADV_DONTNEED.
8956[clinic start generated code]*/
8957
Larry Hastings2f936352014-08-05 14:04:04 +10008958static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008959os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008960 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008961/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008962{
8963 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008964 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008965
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008966 do {
8967 Py_BEGIN_ALLOW_THREADS
8968 result = posix_fadvise(fd, offset, length, advice);
8969 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05008970 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
8971
8972 if (result == 0)
8973 Py_RETURN_NONE;
8974
8975 if (async_err)
8976 return NULL;
8977
8978 errno = result;
8979 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02008980}
Victor Stinnerec39e262014-09-30 12:35:58 +02008981#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008982
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008983#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008984
Fred Drake762e2061999-08-26 17:23:54 +00008985/* Save putenv() parameters as values here, so we can collect them when they
8986 * get re-set with another call for the same key. */
8987static PyObject *posix_putenv_garbage;
8988
Larry Hastings2f936352014-08-05 14:04:04 +10008989static void
8990posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008991{
Larry Hastings2f936352014-08-05 14:04:04 +10008992 /* Install the first arg and newstr in posix_putenv_garbage;
8993 * this will cause previous value to be collected. This has to
8994 * happen after the real putenv() call because the old value
8995 * was still accessible until then. */
8996 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8997 /* really not much we can do; just leak */
8998 PyErr_Clear();
8999 else
9000 Py_DECREF(value);
9001}
9002
9003
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009004#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009005/*[clinic input]
9006os.putenv
9007
9008 name: unicode
9009 value: unicode
9010 /
9011
9012Change or add an environment variable.
9013[clinic start generated code]*/
9014
Larry Hastings2f936352014-08-05 14:04:04 +10009015static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009016os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9017/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009018{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009019 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009020 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009021
Serhiy Storchaka77703942017-06-25 07:33:01 +03009022 /* Search from index 1 because on Windows starting '=' is allowed for
9023 defining hidden environment variables. */
9024 if (PyUnicode_GET_LENGTH(name) == 0 ||
9025 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9026 {
9027 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9028 return NULL;
9029 }
Larry Hastings2f936352014-08-05 14:04:04 +10009030 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9031 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009032 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009033 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009034
9035 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9036 if (env == NULL)
9037 goto error;
9038 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009039 PyErr_Format(PyExc_ValueError,
9040 "the environment variable is longer than %u characters",
9041 _MAX_ENV);
9042 goto error;
9043 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009044 if (wcslen(env) != (size_t)size) {
9045 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009046 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009047 }
9048
Larry Hastings2f936352014-08-05 14:04:04 +10009049 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009050 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009051 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009052 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009053
Larry Hastings2f936352014-08-05 14:04:04 +10009054 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009055 Py_RETURN_NONE;
9056
9057error:
Larry Hastings2f936352014-08-05 14:04:04 +10009058 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009059 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009060}
Larry Hastings2f936352014-08-05 14:04:04 +10009061#else /* MS_WINDOWS */
9062/*[clinic input]
9063os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009064
Larry Hastings2f936352014-08-05 14:04:04 +10009065 name: FSConverter
9066 value: FSConverter
9067 /
9068
9069Change or add an environment variable.
9070[clinic start generated code]*/
9071
Larry Hastings2f936352014-08-05 14:04:04 +10009072static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009073os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9074/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009075{
9076 PyObject *bytes = NULL;
9077 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009078 const char *name_string = PyBytes_AS_STRING(name);
9079 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009080
Serhiy Storchaka77703942017-06-25 07:33:01 +03009081 if (strchr(name_string, '=') != NULL) {
9082 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9083 return NULL;
9084 }
Larry Hastings2f936352014-08-05 14:04:04 +10009085 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9086 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009087 return NULL;
9088 }
9089
9090 env = PyBytes_AS_STRING(bytes);
9091 if (putenv(env)) {
9092 Py_DECREF(bytes);
9093 return posix_error();
9094 }
9095
9096 posix_putenv_garbage_setitem(name, bytes);
9097 Py_RETURN_NONE;
9098}
9099#endif /* MS_WINDOWS */
9100#endif /* HAVE_PUTENV */
9101
9102
9103#ifdef HAVE_UNSETENV
9104/*[clinic input]
9105os.unsetenv
9106 name: FSConverter
9107 /
9108
9109Delete an environment variable.
9110[clinic start generated code]*/
9111
Larry Hastings2f936352014-08-05 14:04:04 +10009112static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009113os_unsetenv_impl(PyObject *module, PyObject *name)
9114/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009115{
Victor Stinner984890f2011-11-24 13:53:38 +01009116#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009117 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009118#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009119
Victor Stinner984890f2011-11-24 13:53:38 +01009120#ifdef HAVE_BROKEN_UNSETENV
9121 unsetenv(PyBytes_AS_STRING(name));
9122#else
Victor Stinner65170952011-11-22 22:16:17 +01009123 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009124 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009125 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009126#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009127
Victor Stinner8c62be82010-05-06 00:08:46 +00009128 /* Remove the key from posix_putenv_garbage;
9129 * this will cause it to be collected. This has to
9130 * happen after the real unsetenv() call because the
9131 * old value was still accessible until then.
9132 */
Victor Stinner65170952011-11-22 22:16:17 +01009133 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009134 /* really not much we can do; just leak */
9135 PyErr_Clear();
9136 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009137 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009138}
Larry Hastings2f936352014-08-05 14:04:04 +10009139#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009140
Larry Hastings2f936352014-08-05 14:04:04 +10009141
9142/*[clinic input]
9143os.strerror
9144
9145 code: int
9146 /
9147
9148Translate an error code to a message string.
9149[clinic start generated code]*/
9150
Larry Hastings2f936352014-08-05 14:04:04 +10009151static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009152os_strerror_impl(PyObject *module, int code)
9153/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009154{
9155 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009156 if (message == NULL) {
9157 PyErr_SetString(PyExc_ValueError,
9158 "strerror() argument out of range");
9159 return NULL;
9160 }
Victor Stinner1b579672011-12-17 05:47:23 +01009161 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009162}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009163
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009164
Guido van Rossumc9641791998-08-04 15:26:23 +00009165#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009166#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009167/*[clinic input]
9168os.WCOREDUMP -> bool
9169
9170 status: int
9171 /
9172
9173Return True if the process returning status was dumped to a core file.
9174[clinic start generated code]*/
9175
Larry Hastings2f936352014-08-05 14:04:04 +10009176static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009177os_WCOREDUMP_impl(PyObject *module, int status)
9178/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009179{
9180 WAIT_TYPE wait_status;
9181 WAIT_STATUS_INT(wait_status) = status;
9182 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009183}
9184#endif /* WCOREDUMP */
9185
Larry Hastings2f936352014-08-05 14:04:04 +10009186
Fred Drake106c1a02002-04-23 15:58:02 +00009187#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009188/*[clinic input]
9189os.WIFCONTINUED -> bool
9190
9191 status: int
9192
9193Return True if a particular process was continued from a job control stop.
9194
9195Return True if the process returning status was continued from a
9196job control stop.
9197[clinic start generated code]*/
9198
Larry Hastings2f936352014-08-05 14:04:04 +10009199static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009200os_WIFCONTINUED_impl(PyObject *module, int status)
9201/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009202{
9203 WAIT_TYPE wait_status;
9204 WAIT_STATUS_INT(wait_status) = status;
9205 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009206}
9207#endif /* WIFCONTINUED */
9208
Larry Hastings2f936352014-08-05 14:04:04 +10009209
Guido van Rossumc9641791998-08-04 15:26:23 +00009210#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009211/*[clinic input]
9212os.WIFSTOPPED -> bool
9213
9214 status: int
9215
9216Return True if the process returning status was stopped.
9217[clinic start generated code]*/
9218
Larry Hastings2f936352014-08-05 14:04:04 +10009219static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009220os_WIFSTOPPED_impl(PyObject *module, int status)
9221/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009222{
9223 WAIT_TYPE wait_status;
9224 WAIT_STATUS_INT(wait_status) = status;
9225 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009226}
9227#endif /* WIFSTOPPED */
9228
Larry Hastings2f936352014-08-05 14:04:04 +10009229
Guido van Rossumc9641791998-08-04 15:26:23 +00009230#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009231/*[clinic input]
9232os.WIFSIGNALED -> bool
9233
9234 status: int
9235
9236Return True if the process returning status was terminated by a signal.
9237[clinic start generated code]*/
9238
Larry Hastings2f936352014-08-05 14:04:04 +10009239static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009240os_WIFSIGNALED_impl(PyObject *module, int status)
9241/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009242{
9243 WAIT_TYPE wait_status;
9244 WAIT_STATUS_INT(wait_status) = status;
9245 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009246}
9247#endif /* WIFSIGNALED */
9248
Larry Hastings2f936352014-08-05 14:04:04 +10009249
Guido van Rossumc9641791998-08-04 15:26:23 +00009250#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009251/*[clinic input]
9252os.WIFEXITED -> bool
9253
9254 status: int
9255
9256Return True if the process returning status exited via the exit() system call.
9257[clinic start generated code]*/
9258
Larry Hastings2f936352014-08-05 14:04:04 +10009259static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009260os_WIFEXITED_impl(PyObject *module, int status)
9261/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009262{
9263 WAIT_TYPE wait_status;
9264 WAIT_STATUS_INT(wait_status) = status;
9265 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009266}
9267#endif /* WIFEXITED */
9268
Larry Hastings2f936352014-08-05 14:04:04 +10009269
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009270#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009271/*[clinic input]
9272os.WEXITSTATUS -> int
9273
9274 status: int
9275
9276Return the process return code from status.
9277[clinic start generated code]*/
9278
Larry Hastings2f936352014-08-05 14:04:04 +10009279static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009280os_WEXITSTATUS_impl(PyObject *module, int status)
9281/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009282{
9283 WAIT_TYPE wait_status;
9284 WAIT_STATUS_INT(wait_status) = status;
9285 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009286}
9287#endif /* WEXITSTATUS */
9288
Larry Hastings2f936352014-08-05 14:04:04 +10009289
Guido van Rossumc9641791998-08-04 15:26:23 +00009290#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009291/*[clinic input]
9292os.WTERMSIG -> int
9293
9294 status: int
9295
9296Return the signal that terminated the process that provided the status value.
9297[clinic start generated code]*/
9298
Larry Hastings2f936352014-08-05 14:04:04 +10009299static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009300os_WTERMSIG_impl(PyObject *module, int status)
9301/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009302{
9303 WAIT_TYPE wait_status;
9304 WAIT_STATUS_INT(wait_status) = status;
9305 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009306}
9307#endif /* WTERMSIG */
9308
Larry Hastings2f936352014-08-05 14:04:04 +10009309
Guido van Rossumc9641791998-08-04 15:26:23 +00009310#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009311/*[clinic input]
9312os.WSTOPSIG -> int
9313
9314 status: int
9315
9316Return the signal that stopped the process that provided the status value.
9317[clinic start generated code]*/
9318
Larry Hastings2f936352014-08-05 14:04:04 +10009319static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009320os_WSTOPSIG_impl(PyObject *module, int status)
9321/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009322{
9323 WAIT_TYPE wait_status;
9324 WAIT_STATUS_INT(wait_status) = status;
9325 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009326}
9327#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009328#endif /* HAVE_SYS_WAIT_H */
9329
9330
Thomas Wouters477c8d52006-05-27 19:21:47 +00009331#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009332#ifdef _SCO_DS
9333/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9334 needed definitions in sys/statvfs.h */
9335#define _SVID3
9336#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009337#include <sys/statvfs.h>
9338
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009339static PyObject*
9340_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009341 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9342 if (v == NULL)
9343 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009344
9345#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009346 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9347 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9348 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9349 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9350 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9351 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9352 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9353 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9354 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9355 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009356#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009357 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9358 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9359 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009360 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009362 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009364 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009366 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009368 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009369 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009370 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9372 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009373#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009374 if (PyErr_Occurred()) {
9375 Py_DECREF(v);
9376 return NULL;
9377 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009378
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009380}
9381
Larry Hastings2f936352014-08-05 14:04:04 +10009382
9383/*[clinic input]
9384os.fstatvfs
9385 fd: int
9386 /
9387
9388Perform an fstatvfs system call on the given fd.
9389
9390Equivalent to statvfs(fd).
9391[clinic start generated code]*/
9392
Larry Hastings2f936352014-08-05 14:04:04 +10009393static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009394os_fstatvfs_impl(PyObject *module, int fd)
9395/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009396{
9397 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009398 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009399 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009400
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009401 do {
9402 Py_BEGIN_ALLOW_THREADS
9403 result = fstatvfs(fd, &st);
9404 Py_END_ALLOW_THREADS
9405 } while (result != 0 && errno == EINTR &&
9406 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009407 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009408 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009409
Victor Stinner8c62be82010-05-06 00:08:46 +00009410 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009411}
Larry Hastings2f936352014-08-05 14:04:04 +10009412#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009413
9414
Thomas Wouters477c8d52006-05-27 19:21:47 +00009415#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009416#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009417/*[clinic input]
9418os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009419
Larry Hastings2f936352014-08-05 14:04:04 +10009420 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9421
9422Perform a statvfs system call on the given path.
9423
9424path may always be specified as a string.
9425On some platforms, path may also be specified as an open file descriptor.
9426 If this functionality is unavailable, using it raises an exception.
9427[clinic start generated code]*/
9428
Larry Hastings2f936352014-08-05 14:04:04 +10009429static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009430os_statvfs_impl(PyObject *module, path_t *path)
9431/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009432{
9433 int result;
9434 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009435
9436 Py_BEGIN_ALLOW_THREADS
9437#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009438 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009439#ifdef __APPLE__
9440 /* handle weak-linking on Mac OS X 10.3 */
9441 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009442 fd_specified("statvfs", path->fd);
9443 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009444 }
9445#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009446 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009447 }
9448 else
9449#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009450 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009451 Py_END_ALLOW_THREADS
9452
9453 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009454 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009455 }
9456
Larry Hastings2f936352014-08-05 14:04:04 +10009457 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009458}
Larry Hastings2f936352014-08-05 14:04:04 +10009459#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9460
Guido van Rossum94f6f721999-01-06 18:42:14 +00009461
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009462#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009463/*[clinic input]
9464os._getdiskusage
9465
9466 path: Py_UNICODE
9467
9468Return disk usage statistics about the given path as a (total, free) tuple.
9469[clinic start generated code]*/
9470
Larry Hastings2f936352014-08-05 14:04:04 +10009471static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009472os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9473/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009474{
9475 BOOL retval;
9476 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009477
9478 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009479 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009480 Py_END_ALLOW_THREADS
9481 if (retval == 0)
9482 return PyErr_SetFromWindowsErr(0);
9483
9484 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9485}
Larry Hastings2f936352014-08-05 14:04:04 +10009486#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009487
9488
Fred Drakec9680921999-12-13 16:37:25 +00009489/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9490 * It maps strings representing configuration variable names to
9491 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009492 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009493 * rarely-used constants. There are three separate tables that use
9494 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009495 *
9496 * This code is always included, even if none of the interfaces that
9497 * need it are included. The #if hackery needed to avoid it would be
9498 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009499 */
9500struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009501 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009502 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009503};
9504
Fred Drake12c6e2d1999-12-14 21:25:03 +00009505static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009506conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009507 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009508{
Christian Heimes217cfd12007-12-02 14:31:20 +00009509 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009510 int value = _PyLong_AsInt(arg);
9511 if (value == -1 && PyErr_Occurred())
9512 return 0;
9513 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009514 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009515 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009516 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009517 /* look up the value in the table using a binary search */
9518 size_t lo = 0;
9519 size_t mid;
9520 size_t hi = tablesize;
9521 int cmp;
9522 const char *confname;
9523 if (!PyUnicode_Check(arg)) {
9524 PyErr_SetString(PyExc_TypeError,
9525 "configuration names must be strings or integers");
9526 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009528 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009529 if (confname == NULL)
9530 return 0;
9531 while (lo < hi) {
9532 mid = (lo + hi) / 2;
9533 cmp = strcmp(confname, table[mid].name);
9534 if (cmp < 0)
9535 hi = mid;
9536 else if (cmp > 0)
9537 lo = mid + 1;
9538 else {
9539 *valuep = table[mid].value;
9540 return 1;
9541 }
9542 }
9543 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9544 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009546}
9547
9548
9549#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9550static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009551#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009553#endif
9554#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009556#endif
Fred Drakec9680921999-12-13 16:37:25 +00009557#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009559#endif
9560#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009562#endif
9563#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009565#endif
9566#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009568#endif
9569#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009571#endif
9572#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009574#endif
9575#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009577#endif
9578#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009580#endif
9581#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009583#endif
9584#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009586#endif
9587#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009589#endif
9590#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009592#endif
9593#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009595#endif
9596#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009598#endif
9599#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009601#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009602#ifdef _PC_ACL_ENABLED
9603 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9604#endif
9605#ifdef _PC_MIN_HOLE_SIZE
9606 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9607#endif
9608#ifdef _PC_ALLOC_SIZE_MIN
9609 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9610#endif
9611#ifdef _PC_REC_INCR_XFER_SIZE
9612 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9613#endif
9614#ifdef _PC_REC_MAX_XFER_SIZE
9615 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9616#endif
9617#ifdef _PC_REC_MIN_XFER_SIZE
9618 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9619#endif
9620#ifdef _PC_REC_XFER_ALIGN
9621 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9622#endif
9623#ifdef _PC_SYMLINK_MAX
9624 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9625#endif
9626#ifdef _PC_XATTR_ENABLED
9627 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9628#endif
9629#ifdef _PC_XATTR_EXISTS
9630 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9631#endif
9632#ifdef _PC_TIMESTAMP_RESOLUTION
9633 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9634#endif
Fred Drakec9680921999-12-13 16:37:25 +00009635};
9636
Fred Drakec9680921999-12-13 16:37:25 +00009637static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009638conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009639{
9640 return conv_confname(arg, valuep, posix_constants_pathconf,
9641 sizeof(posix_constants_pathconf)
9642 / sizeof(struct constdef));
9643}
9644#endif
9645
Larry Hastings2f936352014-08-05 14:04:04 +10009646
Fred Drakec9680921999-12-13 16:37:25 +00009647#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009648/*[clinic input]
9649os.fpathconf -> long
9650
9651 fd: int
9652 name: path_confname
9653 /
9654
9655Return the configuration limit name for the file descriptor fd.
9656
9657If there is no limit, return -1.
9658[clinic start generated code]*/
9659
Larry Hastings2f936352014-08-05 14:04:04 +10009660static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009661os_fpathconf_impl(PyObject *module, int fd, int name)
9662/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009663{
9664 long limit;
9665
9666 errno = 0;
9667 limit = fpathconf(fd, name);
9668 if (limit == -1 && errno != 0)
9669 posix_error();
9670
9671 return limit;
9672}
9673#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009674
9675
9676#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009677/*[clinic input]
9678os.pathconf -> long
9679 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9680 name: path_confname
9681
9682Return the configuration limit name for the file or directory path.
9683
9684If there is no limit, return -1.
9685On some platforms, path may also be specified as an open file descriptor.
9686 If this functionality is unavailable, using it raises an exception.
9687[clinic start generated code]*/
9688
Larry Hastings2f936352014-08-05 14:04:04 +10009689static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009690os_pathconf_impl(PyObject *module, path_t *path, int name)
9691/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009692{
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009694
Victor Stinner8c62be82010-05-06 00:08:46 +00009695 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009696#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009697 if (path->fd != -1)
9698 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009699 else
9700#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009701 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 if (limit == -1 && errno != 0) {
9703 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009704 /* could be a path or name problem */
9705 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009706 else
Larry Hastings2f936352014-08-05 14:04:04 +10009707 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 }
Larry Hastings2f936352014-08-05 14:04:04 +10009709
9710 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009711}
Larry Hastings2f936352014-08-05 14:04:04 +10009712#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009713
9714#ifdef HAVE_CONFSTR
9715static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009716#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009718#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009719#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009721#endif
9722#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009724#endif
Fred Draked86ed291999-12-15 15:34:33 +00009725#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009727#endif
9728#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009730#endif
9731#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009733#endif
9734#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009736#endif
Fred Drakec9680921999-12-13 16:37:25 +00009737#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
Fred Draked86ed291999-12-15 15:34:33 +00009761#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009763#endif
Fred Drakec9680921999-12-13 16:37:25 +00009764#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
Fred Draked86ed291999-12-15 15:34:33 +00009767#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009769#endif
9770#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009772#endif
9773#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009775#endif
9776#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009778#endif
Fred Drakec9680921999-12-13 16:37:25 +00009779#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
Fred Draked86ed291999-12-15 15:34:33 +00009827#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009829#endif
9830#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009832#endif
9833#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009835#endif
9836#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009838#endif
9839#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009841#endif
9842#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009844#endif
9845#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009847#endif
9848#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009850#endif
9851#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009853#endif
9854#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009856#endif
9857#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009859#endif
9860#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009862#endif
9863#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009865#endif
Fred Drakec9680921999-12-13 16:37:25 +00009866};
9867
9868static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009869conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009870{
9871 return conv_confname(arg, valuep, posix_constants_confstr,
9872 sizeof(posix_constants_confstr)
9873 / sizeof(struct constdef));
9874}
9875
Larry Hastings2f936352014-08-05 14:04:04 +10009876
9877/*[clinic input]
9878os.confstr
9879
9880 name: confstr_confname
9881 /
9882
9883Return a string-valued system configuration variable.
9884[clinic start generated code]*/
9885
Larry Hastings2f936352014-08-05 14:04:04 +10009886static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009887os_confstr_impl(PyObject *module, int name)
9888/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009889{
9890 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009891 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009892 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009893
Victor Stinnercb043522010-09-10 23:49:04 +00009894 errno = 0;
9895 len = confstr(name, buffer, sizeof(buffer));
9896 if (len == 0) {
9897 if (errno) {
9898 posix_error();
9899 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009900 }
9901 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009902 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009903 }
9904 }
Victor Stinnercb043522010-09-10 23:49:04 +00009905
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009906 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009907 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009908 char *buf = PyMem_Malloc(len);
9909 if (buf == NULL)
9910 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009911 len2 = confstr(name, buf, len);
9912 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009913 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009914 PyMem_Free(buf);
9915 }
9916 else
9917 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009918 return result;
9919}
Larry Hastings2f936352014-08-05 14:04:04 +10009920#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009921
9922
9923#ifdef HAVE_SYSCONF
9924static struct constdef posix_constants_sysconf[] = {
9925#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
9937#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
9940#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
9943#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
9946#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
9949#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009951#endif
9952#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
Fred Draked86ed291999-12-15 15:34:33 +00009955#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009957#endif
9958#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009960#endif
Fred Drakec9680921999-12-13 16:37:25 +00009961#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
Fred Drakec9680921999-12-13 16:37:25 +00009964#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
9967#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009969#endif
9970#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
Fred Draked86ed291999-12-15 15:34:33 +00009979#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009981#endif
Fred Drakec9680921999-12-13 16:37:25 +00009982#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
9985#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009987#endif
9988#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
9991#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
Fred Draked86ed291999-12-15 15:34:33 +00009997#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009999#endif
Fred Drakec9680921999-12-13 16:37:25 +000010000#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
10018#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
10021#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010023#endif
10024#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010026#endif
10027#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
10033#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
10036#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
10039#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010041#endif
10042#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010044#endif
10045#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
10048#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
10051#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010053#endif
10054#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
10057#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010059#endif
10060#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
10063#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010065#endif
10066#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
Fred Draked86ed291999-12-15 15:34:33 +000010069#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010071#endif
Fred Drakec9680921999-12-13 16:37:25 +000010072#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010074#endif
10075#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010077#endif
10078#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010080#endif
Fred Draked86ed291999-12-15 15:34:33 +000010081#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010083#endif
Fred Drakec9680921999-12-13 16:37:25 +000010084#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010086#endif
Fred Draked86ed291999-12-15 15:34:33 +000010087#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010089#endif
10090#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010092#endif
Fred Drakec9680921999-12-13 16:37:25 +000010093#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010095#endif
10096#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
Fred Draked86ed291999-12-15 15:34:33 +000010105#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010107#endif
Fred Drakec9680921999-12-13 16:37:25 +000010108#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
10111#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
10114#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
10117#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
10120#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
10123#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
10126#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
Fred Draked86ed291999-12-15 15:34:33 +000010129#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010131#endif
Fred Drakec9680921999-12-13 16:37:25 +000010132#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
Fred Draked86ed291999-12-15 15:34:33 +000010138#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010140#endif
Fred Drakec9680921999-12-13 16:37:25 +000010141#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
10153#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
10156#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010158#endif
10159#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
10162#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
Fred Draked86ed291999-12-15 15:34:33 +000010168#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010170#endif
10171#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010173#endif
Fred Drakec9680921999-12-13 16:37:25 +000010174#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
10234#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
10258#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010260#endif
10261#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010263#endif
10264#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010266#endif
10267#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010269#endif
10270#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010272#endif
10273#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010275#endif
10276#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010278#endif
Fred Draked86ed291999-12-15 15:34:33 +000010279#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010281#endif
Fred Drakec9680921999-12-13 16:37:25 +000010282#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010284#endif
10285#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010287#endif
10288#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010290#endif
10291#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010293#endif
10294#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010296#endif
10297#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
10303#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010305#endif
10306#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
10309#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
10327#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010329#endif
10330#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
10336#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
10339#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
10342#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010344#endif
10345#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010347#endif
10348#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010350#endif
10351#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010353#endif
10354#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010356#endif
10357#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010359#endif
10360#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010361 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010362#endif
10363#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010365#endif
10366#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010368#endif
10369#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010371#endif
10372#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010374#endif
10375#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010377#endif
10378#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010380#endif
10381#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010383#endif
10384#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010386#endif
10387#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010389#endif
10390#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010392#endif
10393#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010394 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010395#endif
10396#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010397 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010398#endif
10399#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010400 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010401#endif
10402#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010403 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010404#endif
10405#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010406 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010407#endif
10408#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010409 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010410#endif
10411#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010412 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010413#endif
10414#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010415 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010416#endif
10417};
10418
10419static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010420conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010421{
10422 return conv_confname(arg, valuep, posix_constants_sysconf,
10423 sizeof(posix_constants_sysconf)
10424 / sizeof(struct constdef));
10425}
10426
Larry Hastings2f936352014-08-05 14:04:04 +100010427
10428/*[clinic input]
10429os.sysconf -> long
10430 name: sysconf_confname
10431 /
10432
10433Return an integer-valued system configuration variable.
10434[clinic start generated code]*/
10435
Larry Hastings2f936352014-08-05 14:04:04 +100010436static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010437os_sysconf_impl(PyObject *module, int name)
10438/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010439{
10440 long value;
10441
10442 errno = 0;
10443 value = sysconf(name);
10444 if (value == -1 && errno != 0)
10445 posix_error();
10446 return value;
10447}
10448#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010449
10450
Fred Drakebec628d1999-12-15 18:31:10 +000010451/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010452 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010453 * the exported dictionaries that are used to publish information about the
10454 * names available on the host platform.
10455 *
10456 * Sorting the table at runtime ensures that the table is properly ordered
10457 * when used, even for platforms we're not able to test on. It also makes
10458 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010459 */
Fred Drakebec628d1999-12-15 18:31:10 +000010460
10461static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010462cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010463{
10464 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010465 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010466 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010468
10469 return strcmp(c1->name, c2->name);
10470}
10471
10472static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010473setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010474 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010475{
Fred Drakebec628d1999-12-15 18:31:10 +000010476 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010477 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010478
10479 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10480 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010481 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010483
Barry Warsaw3155db32000-04-13 15:20:40 +000010484 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 PyObject *o = PyLong_FromLong(table[i].value);
10486 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10487 Py_XDECREF(o);
10488 Py_DECREF(d);
10489 return -1;
10490 }
10491 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010492 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010493 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010494}
10495
Fred Drakebec628d1999-12-15 18:31:10 +000010496/* Return -1 on failure, 0 on success. */
10497static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010498setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010499{
10500#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010501 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010502 sizeof(posix_constants_pathconf)
10503 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010504 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010505 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010506#endif
10507#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010508 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010509 sizeof(posix_constants_confstr)
10510 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010511 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010512 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010513#endif
10514#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010515 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010516 sizeof(posix_constants_sysconf)
10517 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010518 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010519 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010520#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010521 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010522}
Fred Draked86ed291999-12-15 15:34:33 +000010523
10524
Larry Hastings2f936352014-08-05 14:04:04 +100010525/*[clinic input]
10526os.abort
10527
10528Abort the interpreter immediately.
10529
10530This function 'dumps core' or otherwise fails in the hardest way possible
10531on the hosting operating system. This function never returns.
10532[clinic start generated code]*/
10533
Larry Hastings2f936352014-08-05 14:04:04 +100010534static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010535os_abort_impl(PyObject *module)
10536/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010537{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010538 abort();
10539 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010540#ifndef __clang__
10541 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10542 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10543 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010544 Py_FatalError("abort() called from Python code didn't abort!");
10545 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010546#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010547}
Fred Drakebec628d1999-12-15 18:31:10 +000010548
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010549#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010550/* Grab ShellExecute dynamically from shell32 */
10551static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010552static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10553 LPCWSTR, INT);
10554static int
10555check_ShellExecute()
10556{
10557 HINSTANCE hShell32;
10558
10559 /* only recheck */
10560 if (-1 == has_ShellExecute) {
10561 Py_BEGIN_ALLOW_THREADS
10562 hShell32 = LoadLibraryW(L"SHELL32");
10563 Py_END_ALLOW_THREADS
10564 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010565 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10566 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010567 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010568 } else {
10569 has_ShellExecute = 0;
10570 }
10571 }
10572 return has_ShellExecute;
10573}
10574
10575
Steve Dowercc16be82016-09-08 10:35:16 -070010576/*[clinic input]
10577os.startfile
10578 filepath: path_t
10579 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010580
Steve Dowercc16be82016-09-08 10:35:16 -070010581startfile(filepath [, operation])
10582
10583Start a file with its associated application.
10584
10585When "operation" is not specified or "open", this acts like
10586double-clicking the file in Explorer, or giving the file name as an
10587argument to the DOS "start" command: the file is opened with whatever
10588application (if any) its extension is associated.
10589When another "operation" is given, it specifies what should be done with
10590the file. A typical operation is "print".
10591
10592startfile returns as soon as the associated application is launched.
10593There is no option to wait for the application to close, and no way
10594to retrieve the application's exit status.
10595
10596The filepath is relative to the current directory. If you want to use
10597an absolute path, make sure the first character is not a slash ("/");
10598the underlying Win32 ShellExecute function doesn't work if it is.
10599[clinic start generated code]*/
10600
10601static PyObject *
10602os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10603/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10604{
10605 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010606
10607 if(!check_ShellExecute()) {
10608 /* If the OS doesn't have ShellExecute, return a
10609 NotImplementedError. */
10610 return PyErr_Format(PyExc_NotImplementedError,
10611 "startfile not available on this platform");
10612 }
10613
Victor Stinner8c62be82010-05-06 00:08:46 +000010614 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010615 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010616 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010617 Py_END_ALLOW_THREADS
10618
Victor Stinner8c62be82010-05-06 00:08:46 +000010619 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010620 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010621 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010622 }
Steve Dowercc16be82016-09-08 10:35:16 -070010623 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010624}
Larry Hastings2f936352014-08-05 14:04:04 +100010625#endif /* MS_WINDOWS */
10626
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010627
Martin v. Löwis438b5342002-12-27 10:16:42 +000010628#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010629/*[clinic input]
10630os.getloadavg
10631
10632Return average recent system load information.
10633
10634Return the number of processes in the system run queue averaged over
10635the last 1, 5, and 15 minutes as a tuple of three floats.
10636Raises OSError if the load average was unobtainable.
10637[clinic start generated code]*/
10638
Larry Hastings2f936352014-08-05 14:04:04 +100010639static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010640os_getloadavg_impl(PyObject *module)
10641/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010642{
10643 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010644 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010645 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10646 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010647 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010648 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010649}
Larry Hastings2f936352014-08-05 14:04:04 +100010650#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010651
Larry Hastings2f936352014-08-05 14:04:04 +100010652
10653/*[clinic input]
10654os.device_encoding
10655 fd: int
10656
10657Return a string describing the encoding of a terminal's file descriptor.
10658
10659The file descriptor must be attached to a terminal.
10660If the device is not a terminal, return None.
10661[clinic start generated code]*/
10662
Larry Hastings2f936352014-08-05 14:04:04 +100010663static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010664os_device_encoding_impl(PyObject *module, int fd)
10665/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010666{
Brett Cannonefb00c02012-02-29 18:31:31 -050010667 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010668}
10669
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010670
Larry Hastings2f936352014-08-05 14:04:04 +100010671#ifdef HAVE_SETRESUID
10672/*[clinic input]
10673os.setresuid
10674
10675 ruid: uid_t
10676 euid: uid_t
10677 suid: uid_t
10678 /
10679
10680Set the current process's real, effective, and saved user ids.
10681[clinic start generated code]*/
10682
Larry Hastings2f936352014-08-05 14:04:04 +100010683static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010684os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10685/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010686{
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 if (setresuid(ruid, euid, suid) < 0)
10688 return posix_error();
10689 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010690}
Larry Hastings2f936352014-08-05 14:04:04 +100010691#endif /* HAVE_SETRESUID */
10692
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010693
10694#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010695/*[clinic input]
10696os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010697
Larry Hastings2f936352014-08-05 14:04:04 +100010698 rgid: gid_t
10699 egid: gid_t
10700 sgid: gid_t
10701 /
10702
10703Set the current process's real, effective, and saved group ids.
10704[clinic start generated code]*/
10705
Larry Hastings2f936352014-08-05 14:04:04 +100010706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010707os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10708/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010709{
Victor Stinner8c62be82010-05-06 00:08:46 +000010710 if (setresgid(rgid, egid, sgid) < 0)
10711 return posix_error();
10712 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010713}
Larry Hastings2f936352014-08-05 14:04:04 +100010714#endif /* HAVE_SETRESGID */
10715
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010716
10717#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010718/*[clinic input]
10719os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010720
Larry Hastings2f936352014-08-05 14:04:04 +100010721Return a tuple of the current process's real, effective, and saved user ids.
10722[clinic start generated code]*/
10723
Larry Hastings2f936352014-08-05 14:04:04 +100010724static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010725os_getresuid_impl(PyObject *module)
10726/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010727{
Victor Stinner8c62be82010-05-06 00:08:46 +000010728 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 if (getresuid(&ruid, &euid, &suid) < 0)
10730 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010731 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10732 _PyLong_FromUid(euid),
10733 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010734}
Larry Hastings2f936352014-08-05 14:04:04 +100010735#endif /* HAVE_GETRESUID */
10736
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010737
10738#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010739/*[clinic input]
10740os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010741
Larry Hastings2f936352014-08-05 14:04:04 +100010742Return a tuple of the current process's real, effective, and saved group ids.
10743[clinic start generated code]*/
10744
Larry Hastings2f936352014-08-05 14:04:04 +100010745static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010746os_getresgid_impl(PyObject *module)
10747/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010748{
10749 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010750 if (getresgid(&rgid, &egid, &sgid) < 0)
10751 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010752 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10753 _PyLong_FromGid(egid),
10754 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010755}
Larry Hastings2f936352014-08-05 14:04:04 +100010756#endif /* HAVE_GETRESGID */
10757
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010758
Benjamin Peterson9428d532011-09-14 11:45:52 -040010759#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010760/*[clinic input]
10761os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010762
Larry Hastings2f936352014-08-05 14:04:04 +100010763 path: path_t(allow_fd=True)
10764 attribute: path_t
10765 *
10766 follow_symlinks: bool = True
10767
10768Return the value of extended attribute attribute on path.
10769
10770path may be either a string or an open file descriptor.
10771If follow_symlinks is False, and the last element of the path is a symbolic
10772 link, getxattr will examine the symbolic link itself instead of the file
10773 the link points to.
10774
10775[clinic start generated code]*/
10776
Larry Hastings2f936352014-08-05 14:04:04 +100010777static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010778os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010779 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010780/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010781{
10782 Py_ssize_t i;
10783 PyObject *buffer = NULL;
10784
10785 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10786 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010787
Larry Hastings9cf065c2012-06-22 16:30:09 -070010788 for (i = 0; ; i++) {
10789 void *ptr;
10790 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010791 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010792 Py_ssize_t buffer_size = buffer_sizes[i];
10793 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010794 path_error(path);
10795 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010796 }
10797 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10798 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010799 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010800 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010801
Larry Hastings9cf065c2012-06-22 16:30:09 -070010802 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010803 if (path->fd >= 0)
10804 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010805 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010806 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010807 else
Larry Hastings2f936352014-08-05 14:04:04 +100010808 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010809 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010810
Larry Hastings9cf065c2012-06-22 16:30:09 -070010811 if (result < 0) {
10812 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010813 if (errno == ERANGE)
10814 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010815 path_error(path);
10816 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010817 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010818
Larry Hastings9cf065c2012-06-22 16:30:09 -070010819 if (result != buffer_size) {
10820 /* Can only shrink. */
10821 _PyBytes_Resize(&buffer, result);
10822 }
10823 break;
10824 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010825
Larry Hastings9cf065c2012-06-22 16:30:09 -070010826 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010827}
10828
Larry Hastings2f936352014-08-05 14:04:04 +100010829
10830/*[clinic input]
10831os.setxattr
10832
10833 path: path_t(allow_fd=True)
10834 attribute: path_t
10835 value: Py_buffer
10836 flags: int = 0
10837 *
10838 follow_symlinks: bool = True
10839
10840Set extended attribute attribute on path to value.
10841
10842path may be either a string or an open file descriptor.
10843If follow_symlinks is False, and the last element of the path is a symbolic
10844 link, setxattr will modify the symbolic link itself instead of the file
10845 the link points to.
10846
10847[clinic start generated code]*/
10848
Benjamin Peterson799bd802011-08-31 22:15:17 -040010849static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010850os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010851 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010852/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010853{
Larry Hastings2f936352014-08-05 14:04:04 +100010854 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010855
Larry Hastings2f936352014-08-05 14:04:04 +100010856 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010857 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010858
Benjamin Peterson799bd802011-08-31 22:15:17 -040010859 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010860 if (path->fd > -1)
10861 result = fsetxattr(path->fd, attribute->narrow,
10862 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010863 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010864 result = setxattr(path->narrow, attribute->narrow,
10865 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010866 else
Larry Hastings2f936352014-08-05 14:04:04 +100010867 result = lsetxattr(path->narrow, attribute->narrow,
10868 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010869 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010870
Larry Hastings9cf065c2012-06-22 16:30:09 -070010871 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010872 path_error(path);
10873 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010874 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010875
Larry Hastings2f936352014-08-05 14:04:04 +100010876 Py_RETURN_NONE;
10877}
10878
10879
10880/*[clinic input]
10881os.removexattr
10882
10883 path: path_t(allow_fd=True)
10884 attribute: path_t
10885 *
10886 follow_symlinks: bool = True
10887
10888Remove extended attribute attribute on path.
10889
10890path may be either a string or an open file descriptor.
10891If follow_symlinks is False, and the last element of the path is a symbolic
10892 link, removexattr will modify the symbolic link itself instead of the file
10893 the link points to.
10894
10895[clinic start generated code]*/
10896
Larry Hastings2f936352014-08-05 14:04:04 +100010897static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010898os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010899 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010900/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010901{
10902 ssize_t result;
10903
10904 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10905 return NULL;
10906
10907 Py_BEGIN_ALLOW_THREADS;
10908 if (path->fd > -1)
10909 result = fremovexattr(path->fd, attribute->narrow);
10910 else if (follow_symlinks)
10911 result = removexattr(path->narrow, attribute->narrow);
10912 else
10913 result = lremovexattr(path->narrow, attribute->narrow);
10914 Py_END_ALLOW_THREADS;
10915
10916 if (result) {
10917 return path_error(path);
10918 }
10919
10920 Py_RETURN_NONE;
10921}
10922
10923
10924/*[clinic input]
10925os.listxattr
10926
10927 path: path_t(allow_fd=True, nullable=True) = None
10928 *
10929 follow_symlinks: bool = True
10930
10931Return a list of extended attributes on path.
10932
10933path may be either None, a string, or an open file descriptor.
10934if path is None, listxattr will examine the current directory.
10935If follow_symlinks is False, and the last element of the path is a symbolic
10936 link, listxattr will examine the symbolic link itself instead of the file
10937 the link points to.
10938[clinic start generated code]*/
10939
Larry Hastings2f936352014-08-05 14:04:04 +100010940static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010941os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10942/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010943{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010944 Py_ssize_t i;
10945 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010946 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010947 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010948
Larry Hastings2f936352014-08-05 14:04:04 +100010949 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010950 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010951
Larry Hastings2f936352014-08-05 14:04:04 +100010952 name = path->narrow ? path->narrow : ".";
10953
Larry Hastings9cf065c2012-06-22 16:30:09 -070010954 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010955 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010956 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010957 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010958 Py_ssize_t buffer_size = buffer_sizes[i];
10959 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010960 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010961 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010962 break;
10963 }
10964 buffer = PyMem_MALLOC(buffer_size);
10965 if (!buffer) {
10966 PyErr_NoMemory();
10967 break;
10968 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010969
Larry Hastings9cf065c2012-06-22 16:30:09 -070010970 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010971 if (path->fd > -1)
10972 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010973 else if (follow_symlinks)
10974 length = listxattr(name, buffer, buffer_size);
10975 else
10976 length = llistxattr(name, buffer, buffer_size);
10977 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010978
Larry Hastings9cf065c2012-06-22 16:30:09 -070010979 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010980 if (errno == ERANGE) {
10981 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010982 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010983 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010984 }
Larry Hastings2f936352014-08-05 14:04:04 +100010985 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010986 break;
10987 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010988
Larry Hastings9cf065c2012-06-22 16:30:09 -070010989 result = PyList_New(0);
10990 if (!result) {
10991 goto exit;
10992 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010993
Larry Hastings9cf065c2012-06-22 16:30:09 -070010994 end = buffer + length;
10995 for (trace = start = buffer; trace != end; trace++) {
10996 if (!*trace) {
10997 int error;
10998 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10999 trace - start);
11000 if (!attribute) {
11001 Py_DECREF(result);
11002 result = NULL;
11003 goto exit;
11004 }
11005 error = PyList_Append(result, attribute);
11006 Py_DECREF(attribute);
11007 if (error) {
11008 Py_DECREF(result);
11009 result = NULL;
11010 goto exit;
11011 }
11012 start = trace + 1;
11013 }
11014 }
11015 break;
11016 }
11017exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011018 if (buffer)
11019 PyMem_FREE(buffer);
11020 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011021}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011022#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011023
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011024
Larry Hastings2f936352014-08-05 14:04:04 +100011025/*[clinic input]
11026os.urandom
11027
11028 size: Py_ssize_t
11029 /
11030
11031Return a bytes object containing random bytes suitable for cryptographic use.
11032[clinic start generated code]*/
11033
Larry Hastings2f936352014-08-05 14:04:04 +100011034static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011035os_urandom_impl(PyObject *module, Py_ssize_t size)
11036/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011037{
11038 PyObject *bytes;
11039 int result;
11040
Georg Brandl2fb477c2012-02-21 00:33:36 +010011041 if (size < 0)
11042 return PyErr_Format(PyExc_ValueError,
11043 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011044 bytes = PyBytes_FromStringAndSize(NULL, size);
11045 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011046 return NULL;
11047
Victor Stinnere66987e2016-09-06 16:33:52 -070011048 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011049 if (result == -1) {
11050 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011051 return NULL;
11052 }
Larry Hastings2f936352014-08-05 14:04:04 +100011053 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011054}
11055
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011056/* Terminal size querying */
11057
11058static PyTypeObject TerminalSizeType;
11059
11060PyDoc_STRVAR(TerminalSize_docstring,
11061 "A tuple of (columns, lines) for holding terminal window size");
11062
11063static PyStructSequence_Field TerminalSize_fields[] = {
11064 {"columns", "width of the terminal window in characters"},
11065 {"lines", "height of the terminal window in characters"},
11066 {NULL, NULL}
11067};
11068
11069static PyStructSequence_Desc TerminalSize_desc = {
11070 "os.terminal_size",
11071 TerminalSize_docstring,
11072 TerminalSize_fields,
11073 2,
11074};
11075
11076#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011077/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011078PyDoc_STRVAR(termsize__doc__,
11079 "Return the size of the terminal window as (columns, lines).\n" \
11080 "\n" \
11081 "The optional argument fd (default standard output) specifies\n" \
11082 "which file descriptor should be queried.\n" \
11083 "\n" \
11084 "If the file descriptor is not connected to a terminal, an OSError\n" \
11085 "is thrown.\n" \
11086 "\n" \
11087 "This function will only be defined if an implementation is\n" \
11088 "available for this system.\n" \
11089 "\n" \
11090 "shutil.get_terminal_size is the high-level function which should \n" \
11091 "normally be used, os.get_terminal_size is the low-level implementation.");
11092
11093static PyObject*
11094get_terminal_size(PyObject *self, PyObject *args)
11095{
11096 int columns, lines;
11097 PyObject *termsize;
11098
11099 int fd = fileno(stdout);
11100 /* Under some conditions stdout may not be connected and
11101 * fileno(stdout) may point to an invalid file descriptor. For example
11102 * GUI apps don't have valid standard streams by default.
11103 *
11104 * If this happens, and the optional fd argument is not present,
11105 * the ioctl below will fail returning EBADF. This is what we want.
11106 */
11107
11108 if (!PyArg_ParseTuple(args, "|i", &fd))
11109 return NULL;
11110
11111#ifdef TERMSIZE_USE_IOCTL
11112 {
11113 struct winsize w;
11114 if (ioctl(fd, TIOCGWINSZ, &w))
11115 return PyErr_SetFromErrno(PyExc_OSError);
11116 columns = w.ws_col;
11117 lines = w.ws_row;
11118 }
11119#endif /* TERMSIZE_USE_IOCTL */
11120
11121#ifdef TERMSIZE_USE_CONIO
11122 {
11123 DWORD nhandle;
11124 HANDLE handle;
11125 CONSOLE_SCREEN_BUFFER_INFO csbi;
11126 switch (fd) {
11127 case 0: nhandle = STD_INPUT_HANDLE;
11128 break;
11129 case 1: nhandle = STD_OUTPUT_HANDLE;
11130 break;
11131 case 2: nhandle = STD_ERROR_HANDLE;
11132 break;
11133 default:
11134 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11135 }
11136 handle = GetStdHandle(nhandle);
11137 if (handle == NULL)
11138 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11139 if (handle == INVALID_HANDLE_VALUE)
11140 return PyErr_SetFromWindowsErr(0);
11141
11142 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11143 return PyErr_SetFromWindowsErr(0);
11144
11145 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11146 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11147 }
11148#endif /* TERMSIZE_USE_CONIO */
11149
11150 termsize = PyStructSequence_New(&TerminalSizeType);
11151 if (termsize == NULL)
11152 return NULL;
11153 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11154 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11155 if (PyErr_Occurred()) {
11156 Py_DECREF(termsize);
11157 return NULL;
11158 }
11159 return termsize;
11160}
11161#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11162
Larry Hastings2f936352014-08-05 14:04:04 +100011163
11164/*[clinic input]
11165os.cpu_count
11166
Charles-François Natali80d62e62015-08-13 20:37:08 +010011167Return the number of CPUs in the system; return None if indeterminable.
11168
11169This number is not equivalent to the number of CPUs the current process can
11170use. The number of usable CPUs can be obtained with
11171``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011172[clinic start generated code]*/
11173
Larry Hastings2f936352014-08-05 14:04:04 +100011174static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011175os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011176/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011177{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011178 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011179#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011180 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11181 Need to fallback to Vista behavior if this call isn't present */
11182 HINSTANCE hKernel32;
11183 hKernel32 = GetModuleHandleW(L"KERNEL32");
11184
11185 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11186 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11187 "GetMaximumProcessorCount");
11188 if (_GetMaximumProcessorCount != NULL) {
11189 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11190 }
11191 else {
11192 SYSTEM_INFO sysinfo;
11193 GetSystemInfo(&sysinfo);
11194 ncpu = sysinfo.dwNumberOfProcessors;
11195 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011196#elif defined(__hpux)
11197 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11198#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11199 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011200#elif defined(__DragonFly__) || \
11201 defined(__OpenBSD__) || \
11202 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011203 defined(__NetBSD__) || \
11204 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011205 int mib[2];
11206 size_t len = sizeof(ncpu);
11207 mib[0] = CTL_HW;
11208 mib[1] = HW_NCPU;
11209 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11210 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011211#endif
11212 if (ncpu >= 1)
11213 return PyLong_FromLong(ncpu);
11214 else
11215 Py_RETURN_NONE;
11216}
11217
Victor Stinnerdaf45552013-08-28 00:53:59 +020011218
Larry Hastings2f936352014-08-05 14:04:04 +100011219/*[clinic input]
11220os.get_inheritable -> bool
11221
11222 fd: int
11223 /
11224
11225Get the close-on-exe flag of the specified file descriptor.
11226[clinic start generated code]*/
11227
Larry Hastings2f936352014-08-05 14:04:04 +100011228static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011229os_get_inheritable_impl(PyObject *module, int fd)
11230/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011231{
Steve Dower8fc89802015-04-12 00:26:27 -040011232 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011233 _Py_BEGIN_SUPPRESS_IPH
11234 return_value = _Py_get_inheritable(fd);
11235 _Py_END_SUPPRESS_IPH
11236 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011237}
11238
11239
11240/*[clinic input]
11241os.set_inheritable
11242 fd: int
11243 inheritable: int
11244 /
11245
11246Set the inheritable flag of the specified file descriptor.
11247[clinic start generated code]*/
11248
Larry Hastings2f936352014-08-05 14:04:04 +100011249static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011250os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11251/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011252{
Steve Dower8fc89802015-04-12 00:26:27 -040011253 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011254
Steve Dower8fc89802015-04-12 00:26:27 -040011255 _Py_BEGIN_SUPPRESS_IPH
11256 result = _Py_set_inheritable(fd, inheritable, NULL);
11257 _Py_END_SUPPRESS_IPH
11258 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011259 return NULL;
11260 Py_RETURN_NONE;
11261}
11262
11263
11264#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011265/*[clinic input]
11266os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011267 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011268 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011269
Larry Hastings2f936352014-08-05 14:04:04 +100011270Get the close-on-exe flag of the specified file descriptor.
11271[clinic start generated code]*/
11272
Larry Hastings2f936352014-08-05 14:04:04 +100011273static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011274os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011275/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011276{
11277 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011278
11279 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11280 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011281 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011282 }
11283
Larry Hastings2f936352014-08-05 14:04:04 +100011284 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011285}
11286
Victor Stinnerdaf45552013-08-28 00:53:59 +020011287
Larry Hastings2f936352014-08-05 14:04:04 +100011288/*[clinic input]
11289os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011290 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011291 inheritable: bool
11292 /
11293
11294Set the inheritable flag of the specified handle.
11295[clinic start generated code]*/
11296
Larry Hastings2f936352014-08-05 14:04:04 +100011297static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011298os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011299 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011300/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011301{
11302 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011303 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11304 PyErr_SetFromWindowsErr(0);
11305 return NULL;
11306 }
11307 Py_RETURN_NONE;
11308}
Larry Hastings2f936352014-08-05 14:04:04 +100011309#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011310
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011311#ifndef MS_WINDOWS
11312PyDoc_STRVAR(get_blocking__doc__,
11313 "get_blocking(fd) -> bool\n" \
11314 "\n" \
11315 "Get the blocking mode of the file descriptor:\n" \
11316 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11317
11318static PyObject*
11319posix_get_blocking(PyObject *self, PyObject *args)
11320{
11321 int fd;
11322 int blocking;
11323
11324 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11325 return NULL;
11326
Steve Dower8fc89802015-04-12 00:26:27 -040011327 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011328 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011329 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011330 if (blocking < 0)
11331 return NULL;
11332 return PyBool_FromLong(blocking);
11333}
11334
11335PyDoc_STRVAR(set_blocking__doc__,
11336 "set_blocking(fd, blocking)\n" \
11337 "\n" \
11338 "Set the blocking mode of the specified file descriptor.\n" \
11339 "Set the O_NONBLOCK flag if blocking is False,\n" \
11340 "clear the O_NONBLOCK flag otherwise.");
11341
11342static PyObject*
11343posix_set_blocking(PyObject *self, PyObject *args)
11344{
Steve Dower8fc89802015-04-12 00:26:27 -040011345 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011346
11347 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11348 return NULL;
11349
Steve Dower8fc89802015-04-12 00:26:27 -040011350 _Py_BEGIN_SUPPRESS_IPH
11351 result = _Py_set_blocking(fd, blocking);
11352 _Py_END_SUPPRESS_IPH
11353 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011354 return NULL;
11355 Py_RETURN_NONE;
11356}
11357#endif /* !MS_WINDOWS */
11358
11359
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011360/*[clinic input]
11361class os.DirEntry "DirEntry *" "&DirEntryType"
11362[clinic start generated code]*/
11363/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011364
11365typedef struct {
11366 PyObject_HEAD
11367 PyObject *name;
11368 PyObject *path;
11369 PyObject *stat;
11370 PyObject *lstat;
11371#ifdef MS_WINDOWS
11372 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011373 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011374 int got_file_index;
11375#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011376#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011377 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011378#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011379 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011380 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011381#endif
11382} DirEntry;
11383
11384static void
11385DirEntry_dealloc(DirEntry *entry)
11386{
11387 Py_XDECREF(entry->name);
11388 Py_XDECREF(entry->path);
11389 Py_XDECREF(entry->stat);
11390 Py_XDECREF(entry->lstat);
11391 Py_TYPE(entry)->tp_free((PyObject *)entry);
11392}
11393
11394/* Forward reference */
11395static int
11396DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11397
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011398/*[clinic input]
11399os.DirEntry.is_symlink -> bool
11400
11401Return True if the entry is a symbolic link; cached per entry.
11402[clinic start generated code]*/
11403
Victor Stinner6036e442015-03-08 01:58:04 +010011404static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011405os_DirEntry_is_symlink_impl(DirEntry *self)
11406/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011407{
11408#ifdef MS_WINDOWS
11409 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011410#elif defined(HAVE_DIRENT_D_TYPE)
11411 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011412 if (self->d_type != DT_UNKNOWN)
11413 return self->d_type == DT_LNK;
11414 else
11415 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011416#else
11417 /* POSIX without d_type */
11418 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011419#endif
11420}
11421
11422static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011423DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11424{
11425 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011426 STRUCT_STAT st;
11427 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011428
11429#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011430 if (!PyUnicode_FSDecoder(self->path, &ub))
11431 return NULL;
11432 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011433#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011434 if (!PyUnicode_FSConverter(self->path, &ub))
11435 return NULL;
11436 const char *path = PyBytes_AS_STRING(ub);
11437 if (self->dir_fd != DEFAULT_DIR_FD) {
11438#ifdef HAVE_FSTATAT
11439 result = fstatat(self->dir_fd, path, &st,
11440 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11441#else
11442 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11443 return NULL;
11444#endif /* HAVE_FSTATAT */
11445 }
11446 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011447#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011448 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011449 if (follow_symlinks)
11450 result = STAT(path, &st);
11451 else
11452 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011453 }
11454 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011455
11456 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011457 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011458
11459 return _pystat_fromstructstat(&st);
11460}
11461
11462static PyObject *
11463DirEntry_get_lstat(DirEntry *self)
11464{
11465 if (!self->lstat) {
11466#ifdef MS_WINDOWS
11467 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11468#else /* POSIX */
11469 self->lstat = DirEntry_fetch_stat(self, 0);
11470#endif
11471 }
11472 Py_XINCREF(self->lstat);
11473 return self->lstat;
11474}
11475
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011476/*[clinic input]
11477os.DirEntry.stat
11478 *
11479 follow_symlinks: bool = True
11480
11481Return stat_result object for the entry; cached per entry.
11482[clinic start generated code]*/
11483
Victor Stinner6036e442015-03-08 01:58:04 +010011484static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011485os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11486/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011487{
11488 if (!follow_symlinks)
11489 return DirEntry_get_lstat(self);
11490
11491 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011492 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011493 if (result == -1)
11494 return NULL;
11495 else if (result)
11496 self->stat = DirEntry_fetch_stat(self, 1);
11497 else
11498 self->stat = DirEntry_get_lstat(self);
11499 }
11500
11501 Py_XINCREF(self->stat);
11502 return self->stat;
11503}
11504
Victor Stinner6036e442015-03-08 01:58:04 +010011505/* Set exception and return -1 on error, 0 for False, 1 for True */
11506static int
11507DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11508{
11509 PyObject *stat = NULL;
11510 PyObject *st_mode = NULL;
11511 long mode;
11512 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011513#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011514 int is_symlink;
11515 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011516#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011517#ifdef MS_WINDOWS
11518 unsigned long dir_bits;
11519#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011520 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011521
11522#ifdef MS_WINDOWS
11523 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11524 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011525#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011526 is_symlink = self->d_type == DT_LNK;
11527 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11528#endif
11529
Victor Stinner35a97c02015-03-08 02:59:09 +010011530#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011531 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011532#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011533 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011534 if (!stat) {
11535 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11536 /* If file doesn't exist (anymore), then return False
11537 (i.e., say it's not a file/directory) */
11538 PyErr_Clear();
11539 return 0;
11540 }
11541 goto error;
11542 }
11543 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11544 if (!st_mode)
11545 goto error;
11546
11547 mode = PyLong_AsLong(st_mode);
11548 if (mode == -1 && PyErr_Occurred())
11549 goto error;
11550 Py_CLEAR(st_mode);
11551 Py_CLEAR(stat);
11552 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011553#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011554 }
11555 else if (is_symlink) {
11556 assert(mode_bits != S_IFLNK);
11557 result = 0;
11558 }
11559 else {
11560 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11561#ifdef MS_WINDOWS
11562 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11563 if (mode_bits == S_IFDIR)
11564 result = dir_bits != 0;
11565 else
11566 result = dir_bits == 0;
11567#else /* POSIX */
11568 if (mode_bits == S_IFDIR)
11569 result = self->d_type == DT_DIR;
11570 else
11571 result = self->d_type == DT_REG;
11572#endif
11573 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011574#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011575
11576 return result;
11577
11578error:
11579 Py_XDECREF(st_mode);
11580 Py_XDECREF(stat);
11581 return -1;
11582}
11583
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011584/*[clinic input]
11585os.DirEntry.is_dir -> bool
11586 *
11587 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011588
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011589Return True if the entry is a directory; cached per entry.
11590[clinic start generated code]*/
11591
11592static int
11593os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11594/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11595{
11596 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011597}
11598
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011599/*[clinic input]
11600os.DirEntry.is_file -> bool
11601 *
11602 follow_symlinks: bool = True
11603
11604Return True if the entry is a file; cached per entry.
11605[clinic start generated code]*/
11606
11607static int
11608os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11609/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011610{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011611 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011612}
11613
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011614/*[clinic input]
11615os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011616
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011617Return inode of the entry; cached per entry.
11618[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011619
11620static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011621os_DirEntry_inode_impl(DirEntry *self)
11622/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011623{
11624#ifdef MS_WINDOWS
11625 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011626 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011627 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011628 STRUCT_STAT stat;
11629 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011630
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011631 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011632 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011633 path = PyUnicode_AsUnicode(unicode);
11634 result = LSTAT(path, &stat);
11635 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011636
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011637 if (result != 0)
11638 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011639
11640 self->win32_file_index = stat.st_ino;
11641 self->got_file_index = 1;
11642 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011643 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11644 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011645#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011646 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11647 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011648#endif
11649}
11650
11651static PyObject *
11652DirEntry_repr(DirEntry *self)
11653{
11654 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11655}
11656
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011657/*[clinic input]
11658os.DirEntry.__fspath__
11659
11660Returns the path for the entry.
11661[clinic start generated code]*/
11662
Brett Cannon96881cd2016-06-10 14:37:21 -070011663static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011664os_DirEntry___fspath___impl(DirEntry *self)
11665/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011666{
11667 Py_INCREF(self->path);
11668 return self->path;
11669}
11670
Victor Stinner6036e442015-03-08 01:58:04 +010011671static PyMemberDef DirEntry_members[] = {
11672 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11673 "the entry's base filename, relative to scandir() \"path\" argument"},
11674 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11675 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11676 {NULL}
11677};
11678
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011679#include "clinic/posixmodule.c.h"
11680
Victor Stinner6036e442015-03-08 01:58:04 +010011681static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011682 OS_DIRENTRY_IS_DIR_METHODDEF
11683 OS_DIRENTRY_IS_FILE_METHODDEF
11684 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11685 OS_DIRENTRY_STAT_METHODDEF
11686 OS_DIRENTRY_INODE_METHODDEF
11687 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011688 {NULL}
11689};
11690
Benjamin Peterson5646de42015-04-12 17:56:34 -040011691static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011692 PyVarObject_HEAD_INIT(NULL, 0)
11693 MODNAME ".DirEntry", /* tp_name */
11694 sizeof(DirEntry), /* tp_basicsize */
11695 0, /* tp_itemsize */
11696 /* methods */
11697 (destructor)DirEntry_dealloc, /* tp_dealloc */
11698 0, /* tp_print */
11699 0, /* tp_getattr */
11700 0, /* tp_setattr */
11701 0, /* tp_compare */
11702 (reprfunc)DirEntry_repr, /* tp_repr */
11703 0, /* tp_as_number */
11704 0, /* tp_as_sequence */
11705 0, /* tp_as_mapping */
11706 0, /* tp_hash */
11707 0, /* tp_call */
11708 0, /* tp_str */
11709 0, /* tp_getattro */
11710 0, /* tp_setattro */
11711 0, /* tp_as_buffer */
11712 Py_TPFLAGS_DEFAULT, /* tp_flags */
11713 0, /* tp_doc */
11714 0, /* tp_traverse */
11715 0, /* tp_clear */
11716 0, /* tp_richcompare */
11717 0, /* tp_weaklistoffset */
11718 0, /* tp_iter */
11719 0, /* tp_iternext */
11720 DirEntry_methods, /* tp_methods */
11721 DirEntry_members, /* tp_members */
11722};
11723
11724#ifdef MS_WINDOWS
11725
11726static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011727join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011728{
11729 Py_ssize_t path_len;
11730 Py_ssize_t size;
11731 wchar_t *result;
11732 wchar_t ch;
11733
11734 if (!path_wide) { /* Default arg: "." */
11735 path_wide = L".";
11736 path_len = 1;
11737 }
11738 else {
11739 path_len = wcslen(path_wide);
11740 }
11741
11742 /* The +1's are for the path separator and the NUL */
11743 size = path_len + 1 + wcslen(filename) + 1;
11744 result = PyMem_New(wchar_t, size);
11745 if (!result) {
11746 PyErr_NoMemory();
11747 return NULL;
11748 }
11749 wcscpy(result, path_wide);
11750 if (path_len > 0) {
11751 ch = result[path_len - 1];
11752 if (ch != SEP && ch != ALTSEP && ch != L':')
11753 result[path_len++] = SEP;
11754 wcscpy(result + path_len, filename);
11755 }
11756 return result;
11757}
11758
11759static PyObject *
11760DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11761{
11762 DirEntry *entry;
11763 BY_HANDLE_FILE_INFORMATION file_info;
11764 ULONG reparse_tag;
11765 wchar_t *joined_path;
11766
11767 entry = PyObject_New(DirEntry, &DirEntryType);
11768 if (!entry)
11769 return NULL;
11770 entry->name = NULL;
11771 entry->path = NULL;
11772 entry->stat = NULL;
11773 entry->lstat = NULL;
11774 entry->got_file_index = 0;
11775
11776 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11777 if (!entry->name)
11778 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011779 if (path->narrow) {
11780 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11781 if (!entry->name)
11782 goto error;
11783 }
Victor Stinner6036e442015-03-08 01:58:04 +010011784
11785 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11786 if (!joined_path)
11787 goto error;
11788
11789 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11790 PyMem_Free(joined_path);
11791 if (!entry->path)
11792 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011793 if (path->narrow) {
11794 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11795 if (!entry->path)
11796 goto error;
11797 }
Victor Stinner6036e442015-03-08 01:58:04 +010011798
Steve Dowercc16be82016-09-08 10:35:16 -070011799 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011800 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11801
11802 return (PyObject *)entry;
11803
11804error:
11805 Py_DECREF(entry);
11806 return NULL;
11807}
11808
11809#else /* POSIX */
11810
11811static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011812join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011813{
11814 Py_ssize_t path_len;
11815 Py_ssize_t size;
11816 char *result;
11817
11818 if (!path_narrow) { /* Default arg: "." */
11819 path_narrow = ".";
11820 path_len = 1;
11821 }
11822 else {
11823 path_len = strlen(path_narrow);
11824 }
11825
11826 if (filename_len == -1)
11827 filename_len = strlen(filename);
11828
11829 /* The +1's are for the path separator and the NUL */
11830 size = path_len + 1 + filename_len + 1;
11831 result = PyMem_New(char, size);
11832 if (!result) {
11833 PyErr_NoMemory();
11834 return NULL;
11835 }
11836 strcpy(result, path_narrow);
11837 if (path_len > 0 && result[path_len - 1] != '/')
11838 result[path_len++] = '/';
11839 strcpy(result + path_len, filename);
11840 return result;
11841}
11842
11843static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011844DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011845 ino_t d_ino
11846#ifdef HAVE_DIRENT_D_TYPE
11847 , unsigned char d_type
11848#endif
11849 )
Victor Stinner6036e442015-03-08 01:58:04 +010011850{
11851 DirEntry *entry;
11852 char *joined_path;
11853
11854 entry = PyObject_New(DirEntry, &DirEntryType);
11855 if (!entry)
11856 return NULL;
11857 entry->name = NULL;
11858 entry->path = NULL;
11859 entry->stat = NULL;
11860 entry->lstat = NULL;
11861
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011862 if (path->fd != -1) {
11863 entry->dir_fd = path->fd;
11864 joined_path = NULL;
11865 }
11866 else {
11867 entry->dir_fd = DEFAULT_DIR_FD;
11868 joined_path = join_path_filename(path->narrow, name, name_len);
11869 if (!joined_path)
11870 goto error;
11871 }
Victor Stinner6036e442015-03-08 01:58:04 +010011872
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030011873 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010011874 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011875 if (joined_path)
11876 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011877 }
11878 else {
11879 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011880 if (joined_path)
11881 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011882 }
11883 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011884 if (!entry->name)
11885 goto error;
11886
11887 if (path->fd != -1) {
11888 entry->path = entry->name;
11889 Py_INCREF(entry->path);
11890 }
11891 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010011892 goto error;
11893
Victor Stinner35a97c02015-03-08 02:59:09 +010011894#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011895 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011896#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011897 entry->d_ino = d_ino;
11898
11899 return (PyObject *)entry;
11900
11901error:
11902 Py_XDECREF(entry);
11903 return NULL;
11904}
11905
11906#endif
11907
11908
11909typedef struct {
11910 PyObject_HEAD
11911 path_t path;
11912#ifdef MS_WINDOWS
11913 HANDLE handle;
11914 WIN32_FIND_DATAW file_data;
11915 int first_time;
11916#else /* POSIX */
11917 DIR *dirp;
11918#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011919#ifdef HAVE_FDOPENDIR
11920 int fd;
11921#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011922} ScandirIterator;
11923
11924#ifdef MS_WINDOWS
11925
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011926static int
11927ScandirIterator_is_closed(ScandirIterator *iterator)
11928{
11929 return iterator->handle == INVALID_HANDLE_VALUE;
11930}
11931
Victor Stinner6036e442015-03-08 01:58:04 +010011932static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011933ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011934{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011935 HANDLE handle = iterator->handle;
11936
11937 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011938 return;
11939
Victor Stinner6036e442015-03-08 01:58:04 +010011940 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011941 Py_BEGIN_ALLOW_THREADS
11942 FindClose(handle);
11943 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011944}
11945
11946static PyObject *
11947ScandirIterator_iternext(ScandirIterator *iterator)
11948{
11949 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11950 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011951 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011952
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011953 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011954 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011955 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011956
11957 while (1) {
11958 if (!iterator->first_time) {
11959 Py_BEGIN_ALLOW_THREADS
11960 success = FindNextFileW(iterator->handle, file_data);
11961 Py_END_ALLOW_THREADS
11962 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011963 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011964 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011965 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011966 break;
11967 }
11968 }
11969 iterator->first_time = 0;
11970
11971 /* Skip over . and .. */
11972 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011973 wcscmp(file_data->cFileName, L"..") != 0) {
11974 entry = DirEntry_from_find_data(&iterator->path, file_data);
11975 if (!entry)
11976 break;
11977 return entry;
11978 }
Victor Stinner6036e442015-03-08 01:58:04 +010011979
11980 /* Loop till we get a non-dot directory or finish iterating */
11981 }
11982
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011983 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011984 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011985 return NULL;
11986}
11987
11988#else /* POSIX */
11989
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011990static int
11991ScandirIterator_is_closed(ScandirIterator *iterator)
11992{
11993 return !iterator->dirp;
11994}
11995
Victor Stinner6036e442015-03-08 01:58:04 +010011996static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011997ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011998{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011999 DIR *dirp = iterator->dirp;
12000
12001 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012002 return;
12003
Victor Stinner6036e442015-03-08 01:58:04 +010012004 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012005 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012006#ifdef HAVE_FDOPENDIR
12007 if (iterator->path.fd != -1)
12008 rewinddir(dirp);
12009#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012010 closedir(dirp);
12011 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012012 return;
12013}
12014
12015static PyObject *
12016ScandirIterator_iternext(ScandirIterator *iterator)
12017{
12018 struct dirent *direntp;
12019 Py_ssize_t name_len;
12020 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012021 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012022
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012023 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012024 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012025 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012026
12027 while (1) {
12028 errno = 0;
12029 Py_BEGIN_ALLOW_THREADS
12030 direntp = readdir(iterator->dirp);
12031 Py_END_ALLOW_THREADS
12032
12033 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012034 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012035 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012036 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012037 break;
12038 }
12039
12040 /* Skip over . and .. */
12041 name_len = NAMLEN(direntp);
12042 is_dot = direntp->d_name[0] == '.' &&
12043 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12044 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012045 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012046 name_len, direntp->d_ino
12047#ifdef HAVE_DIRENT_D_TYPE
12048 , direntp->d_type
12049#endif
12050 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012051 if (!entry)
12052 break;
12053 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012054 }
12055
12056 /* Loop till we get a non-dot directory or finish iterating */
12057 }
12058
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012059 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012060 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012061 return NULL;
12062}
12063
12064#endif
12065
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012066static PyObject *
12067ScandirIterator_close(ScandirIterator *self, PyObject *args)
12068{
12069 ScandirIterator_closedir(self);
12070 Py_RETURN_NONE;
12071}
12072
12073static PyObject *
12074ScandirIterator_enter(PyObject *self, PyObject *args)
12075{
12076 Py_INCREF(self);
12077 return self;
12078}
12079
12080static PyObject *
12081ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12082{
12083 ScandirIterator_closedir(self);
12084 Py_RETURN_NONE;
12085}
12086
Victor Stinner6036e442015-03-08 01:58:04 +010012087static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012088ScandirIterator_finalize(ScandirIterator *iterator)
12089{
12090 PyObject *error_type, *error_value, *error_traceback;
12091
12092 /* Save the current exception, if any. */
12093 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12094
12095 if (!ScandirIterator_is_closed(iterator)) {
12096 ScandirIterator_closedir(iterator);
12097
12098 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12099 "unclosed scandir iterator %R", iterator)) {
12100 /* Spurious errors can appear at shutdown */
12101 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12102 PyErr_WriteUnraisable((PyObject *) iterator);
12103 }
12104 }
12105 }
12106
Victor Stinner7bfa4092016-03-23 00:43:54 +010012107 path_cleanup(&iterator->path);
12108
12109 /* Restore the saved exception. */
12110 PyErr_Restore(error_type, error_value, error_traceback);
12111}
12112
12113static void
Victor Stinner6036e442015-03-08 01:58:04 +010012114ScandirIterator_dealloc(ScandirIterator *iterator)
12115{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012116 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12117 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012118
Victor Stinner6036e442015-03-08 01:58:04 +010012119 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12120}
12121
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012122static PyMethodDef ScandirIterator_methods[] = {
12123 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12124 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12125 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12126 {NULL}
12127};
12128
Benjamin Peterson5646de42015-04-12 17:56:34 -040012129static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012130 PyVarObject_HEAD_INIT(NULL, 0)
12131 MODNAME ".ScandirIterator", /* tp_name */
12132 sizeof(ScandirIterator), /* tp_basicsize */
12133 0, /* tp_itemsize */
12134 /* methods */
12135 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12136 0, /* tp_print */
12137 0, /* tp_getattr */
12138 0, /* tp_setattr */
12139 0, /* tp_compare */
12140 0, /* tp_repr */
12141 0, /* tp_as_number */
12142 0, /* tp_as_sequence */
12143 0, /* tp_as_mapping */
12144 0, /* tp_hash */
12145 0, /* tp_call */
12146 0, /* tp_str */
12147 0, /* tp_getattro */
12148 0, /* tp_setattro */
12149 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012150 Py_TPFLAGS_DEFAULT
12151 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012152 0, /* tp_doc */
12153 0, /* tp_traverse */
12154 0, /* tp_clear */
12155 0, /* tp_richcompare */
12156 0, /* tp_weaklistoffset */
12157 PyObject_SelfIter, /* tp_iter */
12158 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012159 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012160 0, /* tp_members */
12161 0, /* tp_getset */
12162 0, /* tp_base */
12163 0, /* tp_dict */
12164 0, /* tp_descr_get */
12165 0, /* tp_descr_set */
12166 0, /* tp_dictoffset */
12167 0, /* tp_init */
12168 0, /* tp_alloc */
12169 0, /* tp_new */
12170 0, /* tp_free */
12171 0, /* tp_is_gc */
12172 0, /* tp_bases */
12173 0, /* tp_mro */
12174 0, /* tp_cache */
12175 0, /* tp_subclasses */
12176 0, /* tp_weaklist */
12177 0, /* tp_del */
12178 0, /* tp_version_tag */
12179 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012180};
12181
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012182/*[clinic input]
12183os.scandir
12184
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012185 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012186
12187Return an iterator of DirEntry objects for given path.
12188
12189path can be specified as either str, bytes or path-like object. If path
12190is bytes, the names of yielded DirEntry objects will also be bytes; in
12191all other circumstances they will be str.
12192
12193If path is None, uses the path='.'.
12194[clinic start generated code]*/
12195
Victor Stinner6036e442015-03-08 01:58:04 +010012196static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012197os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012198/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012199{
12200 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012201#ifdef MS_WINDOWS
12202 wchar_t *path_strW;
12203#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012204 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012205#ifdef HAVE_FDOPENDIR
12206 int fd = -1;
12207#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012208#endif
12209
12210 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12211 if (!iterator)
12212 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012213
12214#ifdef MS_WINDOWS
12215 iterator->handle = INVALID_HANDLE_VALUE;
12216#else
12217 iterator->dirp = NULL;
12218#endif
12219
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012220 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012221 /* Move the ownership to iterator->path */
12222 path->object = NULL;
12223 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012224
12225#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012226 iterator->first_time = 1;
12227
12228 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12229 if (!path_strW)
12230 goto error;
12231
12232 Py_BEGIN_ALLOW_THREADS
12233 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12234 Py_END_ALLOW_THREADS
12235
12236 PyMem_Free(path_strW);
12237
12238 if (iterator->handle == INVALID_HANDLE_VALUE) {
12239 path_error(&iterator->path);
12240 goto error;
12241 }
12242#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012243 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012244#ifdef HAVE_FDOPENDIR
12245 if (path->fd != -1) {
12246 /* closedir() closes the FD, so we duplicate it */
12247 fd = _Py_dup(path->fd);
12248 if (fd == -1)
12249 goto error;
12250
12251 Py_BEGIN_ALLOW_THREADS
12252 iterator->dirp = fdopendir(fd);
12253 Py_END_ALLOW_THREADS
12254 }
12255 else
12256#endif
12257 {
12258 if (iterator->path.narrow)
12259 path_str = iterator->path.narrow;
12260 else
12261 path_str = ".";
12262
12263 Py_BEGIN_ALLOW_THREADS
12264 iterator->dirp = opendir(path_str);
12265 Py_END_ALLOW_THREADS
12266 }
Victor Stinner6036e442015-03-08 01:58:04 +010012267
12268 if (!iterator->dirp) {
12269 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012270#ifdef HAVE_FDOPENDIR
12271 if (fd != -1) {
12272 Py_BEGIN_ALLOW_THREADS
12273 close(fd);
12274 Py_END_ALLOW_THREADS
12275 }
12276#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012277 goto error;
12278 }
12279#endif
12280
12281 return (PyObject *)iterator;
12282
12283error:
12284 Py_DECREF(iterator);
12285 return NULL;
12286}
12287
Ethan Furman410ef8e2016-06-04 12:06:26 -070012288/*
12289 Return the file system path representation of the object.
12290
12291 If the object is str or bytes, then allow it to pass through with
12292 an incremented refcount. If the object defines __fspath__(), then
12293 return the result of that method. All other types raise a TypeError.
12294*/
12295PyObject *
12296PyOS_FSPath(PyObject *path)
12297{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012298 /* For error message reasons, this function is manually inlined in
12299 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012300 _Py_IDENTIFIER(__fspath__);
12301 PyObject *func = NULL;
12302 PyObject *path_repr = NULL;
12303
12304 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12305 Py_INCREF(path);
12306 return path;
12307 }
12308
12309 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12310 if (NULL == func) {
12311 return PyErr_Format(PyExc_TypeError,
12312 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012313 "not %.200s",
12314 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012315 }
12316
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012317 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012318 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012319 if (NULL == path_repr) {
12320 return NULL;
12321 }
12322
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012323 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12324 PyErr_Format(PyExc_TypeError,
12325 "expected %.200s.__fspath__() to return str or bytes, "
12326 "not %.200s", Py_TYPE(path)->tp_name,
12327 Py_TYPE(path_repr)->tp_name);
12328 Py_DECREF(path_repr);
12329 return NULL;
12330 }
12331
Ethan Furman410ef8e2016-06-04 12:06:26 -070012332 return path_repr;
12333}
12334
12335/*[clinic input]
12336os.fspath
12337
12338 path: object
12339
12340Return the file system path representation of the object.
12341
Brett Cannonb4f43e92016-06-09 14:32:08 -070012342If the object is str or bytes, then allow it to pass through as-is. If the
12343object defines __fspath__(), then return the result of that method. All other
12344types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012345[clinic start generated code]*/
12346
12347static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012348os_fspath_impl(PyObject *module, PyObject *path)
12349/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012350{
12351 return PyOS_FSPath(path);
12352}
Victor Stinner6036e442015-03-08 01:58:04 +010012353
Victor Stinner9b1f4742016-09-06 16:18:52 -070012354#ifdef HAVE_GETRANDOM_SYSCALL
12355/*[clinic input]
12356os.getrandom
12357
12358 size: Py_ssize_t
12359 flags: int=0
12360
12361Obtain a series of random bytes.
12362[clinic start generated code]*/
12363
12364static PyObject *
12365os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12366/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12367{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012368 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012369 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012370
12371 if (size < 0) {
12372 errno = EINVAL;
12373 return posix_error();
12374 }
12375
Victor Stinnerec2319c2016-09-20 23:00:59 +020012376 bytes = PyBytes_FromStringAndSize(NULL, size);
12377 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012378 PyErr_NoMemory();
12379 return NULL;
12380 }
12381
12382 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012383 n = syscall(SYS_getrandom,
12384 PyBytes_AS_STRING(bytes),
12385 PyBytes_GET_SIZE(bytes),
12386 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012387 if (n < 0 && errno == EINTR) {
12388 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012389 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012390 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012391
12392 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012393 continue;
12394 }
12395 break;
12396 }
12397
12398 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012399 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012400 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012401 }
12402
Victor Stinnerec2319c2016-09-20 23:00:59 +020012403 if (n != size) {
12404 _PyBytes_Resize(&bytes, n);
12405 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012406
12407 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012408
12409error:
12410 Py_DECREF(bytes);
12411 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012412}
12413#endif /* HAVE_GETRANDOM_SYSCALL */
12414
Larry Hastings31826802013-10-19 00:09:25 -070012415
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012416static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012417
12418 OS_STAT_METHODDEF
12419 OS_ACCESS_METHODDEF
12420 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012421 OS_CHDIR_METHODDEF
12422 OS_CHFLAGS_METHODDEF
12423 OS_CHMOD_METHODDEF
12424 OS_FCHMOD_METHODDEF
12425 OS_LCHMOD_METHODDEF
12426 OS_CHOWN_METHODDEF
12427 OS_FCHOWN_METHODDEF
12428 OS_LCHOWN_METHODDEF
12429 OS_LCHFLAGS_METHODDEF
12430 OS_CHROOT_METHODDEF
12431 OS_CTERMID_METHODDEF
12432 OS_GETCWD_METHODDEF
12433 OS_GETCWDB_METHODDEF
12434 OS_LINK_METHODDEF
12435 OS_LISTDIR_METHODDEF
12436 OS_LSTAT_METHODDEF
12437 OS_MKDIR_METHODDEF
12438 OS_NICE_METHODDEF
12439 OS_GETPRIORITY_METHODDEF
12440 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012441#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012442 {"readlink", (PyCFunction)posix_readlink,
12443 METH_VARARGS | METH_KEYWORDS,
12444 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012445#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012446#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012447 {"readlink", (PyCFunction)win_readlink,
12448 METH_VARARGS | METH_KEYWORDS,
12449 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012450#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012451 OS_RENAME_METHODDEF
12452 OS_REPLACE_METHODDEF
12453 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012454 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012455 OS_SYMLINK_METHODDEF
12456 OS_SYSTEM_METHODDEF
12457 OS_UMASK_METHODDEF
12458 OS_UNAME_METHODDEF
12459 OS_UNLINK_METHODDEF
12460 OS_REMOVE_METHODDEF
12461 OS_UTIME_METHODDEF
12462 OS_TIMES_METHODDEF
12463 OS__EXIT_METHODDEF
12464 OS_EXECV_METHODDEF
12465 OS_EXECVE_METHODDEF
12466 OS_SPAWNV_METHODDEF
12467 OS_SPAWNVE_METHODDEF
12468 OS_FORK1_METHODDEF
12469 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012470 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012471 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12472 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12473 OS_SCHED_GETPARAM_METHODDEF
12474 OS_SCHED_GETSCHEDULER_METHODDEF
12475 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12476 OS_SCHED_SETPARAM_METHODDEF
12477 OS_SCHED_SETSCHEDULER_METHODDEF
12478 OS_SCHED_YIELD_METHODDEF
12479 OS_SCHED_SETAFFINITY_METHODDEF
12480 OS_SCHED_GETAFFINITY_METHODDEF
12481 OS_OPENPTY_METHODDEF
12482 OS_FORKPTY_METHODDEF
12483 OS_GETEGID_METHODDEF
12484 OS_GETEUID_METHODDEF
12485 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012486#ifdef HAVE_GETGROUPLIST
12487 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12488#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012489 OS_GETGROUPS_METHODDEF
12490 OS_GETPID_METHODDEF
12491 OS_GETPGRP_METHODDEF
12492 OS_GETPPID_METHODDEF
12493 OS_GETUID_METHODDEF
12494 OS_GETLOGIN_METHODDEF
12495 OS_KILL_METHODDEF
12496 OS_KILLPG_METHODDEF
12497 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012498#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012499 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012500#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012501 OS_SETUID_METHODDEF
12502 OS_SETEUID_METHODDEF
12503 OS_SETREUID_METHODDEF
12504 OS_SETGID_METHODDEF
12505 OS_SETEGID_METHODDEF
12506 OS_SETREGID_METHODDEF
12507 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012508#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012509 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012510#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012511 OS_GETPGID_METHODDEF
12512 OS_SETPGRP_METHODDEF
12513 OS_WAIT_METHODDEF
12514 OS_WAIT3_METHODDEF
12515 OS_WAIT4_METHODDEF
12516 OS_WAITID_METHODDEF
12517 OS_WAITPID_METHODDEF
12518 OS_GETSID_METHODDEF
12519 OS_SETSID_METHODDEF
12520 OS_SETPGID_METHODDEF
12521 OS_TCGETPGRP_METHODDEF
12522 OS_TCSETPGRP_METHODDEF
12523 OS_OPEN_METHODDEF
12524 OS_CLOSE_METHODDEF
12525 OS_CLOSERANGE_METHODDEF
12526 OS_DEVICE_ENCODING_METHODDEF
12527 OS_DUP_METHODDEF
12528 OS_DUP2_METHODDEF
12529 OS_LOCKF_METHODDEF
12530 OS_LSEEK_METHODDEF
12531 OS_READ_METHODDEF
12532 OS_READV_METHODDEF
12533 OS_PREAD_METHODDEF
12534 OS_WRITE_METHODDEF
12535 OS_WRITEV_METHODDEF
12536 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012537#ifdef HAVE_SENDFILE
12538 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12539 posix_sendfile__doc__},
12540#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012541 OS_FSTAT_METHODDEF
12542 OS_ISATTY_METHODDEF
12543 OS_PIPE_METHODDEF
12544 OS_PIPE2_METHODDEF
12545 OS_MKFIFO_METHODDEF
12546 OS_MKNOD_METHODDEF
12547 OS_MAJOR_METHODDEF
12548 OS_MINOR_METHODDEF
12549 OS_MAKEDEV_METHODDEF
12550 OS_FTRUNCATE_METHODDEF
12551 OS_TRUNCATE_METHODDEF
12552 OS_POSIX_FALLOCATE_METHODDEF
12553 OS_POSIX_FADVISE_METHODDEF
12554 OS_PUTENV_METHODDEF
12555 OS_UNSETENV_METHODDEF
12556 OS_STRERROR_METHODDEF
12557 OS_FCHDIR_METHODDEF
12558 OS_FSYNC_METHODDEF
12559 OS_SYNC_METHODDEF
12560 OS_FDATASYNC_METHODDEF
12561 OS_WCOREDUMP_METHODDEF
12562 OS_WIFCONTINUED_METHODDEF
12563 OS_WIFSTOPPED_METHODDEF
12564 OS_WIFSIGNALED_METHODDEF
12565 OS_WIFEXITED_METHODDEF
12566 OS_WEXITSTATUS_METHODDEF
12567 OS_WTERMSIG_METHODDEF
12568 OS_WSTOPSIG_METHODDEF
12569 OS_FSTATVFS_METHODDEF
12570 OS_STATVFS_METHODDEF
12571 OS_CONFSTR_METHODDEF
12572 OS_SYSCONF_METHODDEF
12573 OS_FPATHCONF_METHODDEF
12574 OS_PATHCONF_METHODDEF
12575 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012576 OS__GETFULLPATHNAME_METHODDEF
12577 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012578 OS__GETDISKUSAGE_METHODDEF
12579 OS__GETFINALPATHNAME_METHODDEF
12580 OS__GETVOLUMEPATHNAME_METHODDEF
12581 OS_GETLOADAVG_METHODDEF
12582 OS_URANDOM_METHODDEF
12583 OS_SETRESUID_METHODDEF
12584 OS_SETRESGID_METHODDEF
12585 OS_GETRESUID_METHODDEF
12586 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012587
Larry Hastings2f936352014-08-05 14:04:04 +100012588 OS_GETXATTR_METHODDEF
12589 OS_SETXATTR_METHODDEF
12590 OS_REMOVEXATTR_METHODDEF
12591 OS_LISTXATTR_METHODDEF
12592
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012593#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12594 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12595#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012596 OS_CPU_COUNT_METHODDEF
12597 OS_GET_INHERITABLE_METHODDEF
12598 OS_SET_INHERITABLE_METHODDEF
12599 OS_GET_HANDLE_INHERITABLE_METHODDEF
12600 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012601#ifndef MS_WINDOWS
12602 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12603 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12604#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012605 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012606 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012607 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012608 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012609};
12610
12611
Brian Curtin52173d42010-12-02 18:29:18 +000012612#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012613static int
Brian Curtin52173d42010-12-02 18:29:18 +000012614enable_symlink()
12615{
12616 HANDLE tok;
12617 TOKEN_PRIVILEGES tok_priv;
12618 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012619
12620 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012621 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012622
12623 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012624 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012625
12626 tok_priv.PrivilegeCount = 1;
12627 tok_priv.Privileges[0].Luid = luid;
12628 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12629
12630 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12631 sizeof(TOKEN_PRIVILEGES),
12632 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012633 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012634
Brian Curtin3b4499c2010-12-28 14:31:47 +000012635 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12636 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012637}
12638#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12639
Barry Warsaw4a342091996-12-19 23:50:02 +000012640static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012641all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012642{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012643#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012644 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012645#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012646#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012647 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012648#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012649#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012650 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012651#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012652#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012653 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012654#endif
Fred Drakec9680921999-12-13 16:37:25 +000012655#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012656 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012657#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012658#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012659 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012660#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012661#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012662 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012663#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012664#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012665 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012666#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012667#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012668 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012669#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012670#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012671 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012672#endif
12673#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012674 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012675#endif
12676#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012677 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012678#endif
12679#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012680 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012681#endif
12682#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012684#endif
12685#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012687#endif
12688#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012689 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012690#endif
12691#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012692 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012693#endif
12694#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012696#endif
12697#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012698 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012699#endif
12700#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012701 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012702#endif
12703#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012704 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012705#endif
12706#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012707 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012708#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012709#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012710 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012711#endif
12712#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012713 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012714#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012715#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012716 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012717#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012718#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012719 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012720#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012721#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012722#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012723 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012724#endif
12725#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012726 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012727#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012728#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012729#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012730 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012731#endif
12732#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012733 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012734#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012735#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012736 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012737#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012738#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012739 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012740#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012741#ifdef O_TMPFILE
12742 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12743#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012744#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012745 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012746#endif
12747#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012748 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012749#endif
12750#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012751 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012752#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012753#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012754 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012755#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012756#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012757 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012758#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012759
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012760
Jesus Cea94363612012-06-22 18:32:07 +020012761#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012762 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012763#endif
12764#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012765 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012766#endif
12767
Tim Peters5aa91602002-01-30 05:46:57 +000012768/* MS Windows */
12769#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012770 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012771 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012772#endif
12773#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012774 /* Optimize for short life (keep in memory). */
12775 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012776 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012777#endif
12778#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012779 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012780 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012781#endif
12782#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012783 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012784 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012785#endif
12786#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012787 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012788 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012789#endif
12790
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012791/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012792#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012793 /* Send a SIGIO signal whenever input or output
12794 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012795 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012796#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012797#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012798 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012799 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012800#endif
12801#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012802 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012803 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012804#endif
12805#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012806 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012807 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012808#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012809#ifdef O_NOLINKS
12810 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012811 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012812#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012813#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012814 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012815 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012816#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012817
Victor Stinner8c62be82010-05-06 00:08:46 +000012818 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012819#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012820 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012821#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012822#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012823 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012824#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012825#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012826 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012827#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012828#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012829 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012830#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012831#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012832 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012833#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012834#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012835 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012836#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012837#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012838 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012839#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012840#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012841 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012842#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012843#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012844 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012845#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012846#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012847 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012848#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012849#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012850 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012851#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012852#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012853 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012854#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012855#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012856 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012857#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012858#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012859 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012860#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012861#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012862 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012863#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012864#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012865 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012866#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012867#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012868 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012869#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012870
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012871 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012872#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012873 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012874#endif /* ST_RDONLY */
12875#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012876 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012877#endif /* ST_NOSUID */
12878
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012879 /* GNU extensions */
12880#ifdef ST_NODEV
12881 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12882#endif /* ST_NODEV */
12883#ifdef ST_NOEXEC
12884 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12885#endif /* ST_NOEXEC */
12886#ifdef ST_SYNCHRONOUS
12887 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12888#endif /* ST_SYNCHRONOUS */
12889#ifdef ST_MANDLOCK
12890 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12891#endif /* ST_MANDLOCK */
12892#ifdef ST_WRITE
12893 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12894#endif /* ST_WRITE */
12895#ifdef ST_APPEND
12896 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12897#endif /* ST_APPEND */
12898#ifdef ST_NOATIME
12899 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12900#endif /* ST_NOATIME */
12901#ifdef ST_NODIRATIME
12902 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12903#endif /* ST_NODIRATIME */
12904#ifdef ST_RELATIME
12905 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12906#endif /* ST_RELATIME */
12907
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012908 /* FreeBSD sendfile() constants */
12909#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012910 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012911#endif
12912#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012913 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012914#endif
12915#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012916 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012917#endif
12918
Ross Lagerwall7807c352011-03-17 20:20:30 +020012919 /* constants for posix_fadvise */
12920#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012921 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012922#endif
12923#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012924 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012925#endif
12926#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012927 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012928#endif
12929#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012930 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012931#endif
12932#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012933 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012934#endif
12935#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012936 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012937#endif
12938
12939 /* constants for waitid */
12940#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012941 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12942 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12943 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012944#endif
12945#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012946 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012947#endif
12948#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012949 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012950#endif
12951#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012952 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012953#endif
12954#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012955 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012956#endif
12957#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012958 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012959#endif
12960#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012961 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012962#endif
12963#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012964 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012965#endif
12966
12967 /* constants for lockf */
12968#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012969 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012970#endif
12971#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012972 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012973#endif
12974#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012975 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012976#endif
12977#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012978 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012979#endif
12980
Guido van Rossum246bc171999-02-01 23:54:31 +000012981#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012982 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12983 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12984 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12985 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12986 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012987#endif
12988
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012989#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012990#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012991 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012992#endif
12993#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012994 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012995#endif
12996#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012997 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012998#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012999#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013000 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013001#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013002#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013003 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013004#endif
13005#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013006 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013007#endif
13008#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013009 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013010#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013011#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013012 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013013#endif
13014#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013015 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013016#endif
13017#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013018 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013019#endif
13020#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013021 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013022#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013023#endif
13024
Benjamin Peterson9428d532011-09-14 11:45:52 -040013025#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013026 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13027 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13028 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013029#endif
13030
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013031#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013032 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013033#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013034#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013035 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013036#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013037#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013038 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013039#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013040#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013041 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013042#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013043#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013044 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013045#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013046#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013047 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013048#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013049#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013050 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013051#endif
13052
Victor Stinner9b1f4742016-09-06 16:18:52 -070013053#ifdef HAVE_GETRANDOM_SYSCALL
13054 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13055 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13056#endif
13057
Victor Stinner8c62be82010-05-06 00:08:46 +000013058 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013059}
13060
13061
Martin v. Löwis1a214512008-06-11 05:26:20 +000013062static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013063 PyModuleDef_HEAD_INIT,
13064 MODNAME,
13065 posix__doc__,
13066 -1,
13067 posix_methods,
13068 NULL,
13069 NULL,
13070 NULL,
13071 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013072};
13073
13074
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013075static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013076
13077#ifdef HAVE_FACCESSAT
13078 "HAVE_FACCESSAT",
13079#endif
13080
13081#ifdef HAVE_FCHDIR
13082 "HAVE_FCHDIR",
13083#endif
13084
13085#ifdef HAVE_FCHMOD
13086 "HAVE_FCHMOD",
13087#endif
13088
13089#ifdef HAVE_FCHMODAT
13090 "HAVE_FCHMODAT",
13091#endif
13092
13093#ifdef HAVE_FCHOWN
13094 "HAVE_FCHOWN",
13095#endif
13096
Larry Hastings00964ed2013-08-12 13:49:30 -040013097#ifdef HAVE_FCHOWNAT
13098 "HAVE_FCHOWNAT",
13099#endif
13100
Larry Hastings9cf065c2012-06-22 16:30:09 -070013101#ifdef HAVE_FEXECVE
13102 "HAVE_FEXECVE",
13103#endif
13104
13105#ifdef HAVE_FDOPENDIR
13106 "HAVE_FDOPENDIR",
13107#endif
13108
Georg Brandl306336b2012-06-24 12:55:33 +020013109#ifdef HAVE_FPATHCONF
13110 "HAVE_FPATHCONF",
13111#endif
13112
Larry Hastings9cf065c2012-06-22 16:30:09 -070013113#ifdef HAVE_FSTATAT
13114 "HAVE_FSTATAT",
13115#endif
13116
13117#ifdef HAVE_FSTATVFS
13118 "HAVE_FSTATVFS",
13119#endif
13120
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013121#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013122 "HAVE_FTRUNCATE",
13123#endif
13124
Larry Hastings9cf065c2012-06-22 16:30:09 -070013125#ifdef HAVE_FUTIMENS
13126 "HAVE_FUTIMENS",
13127#endif
13128
13129#ifdef HAVE_FUTIMES
13130 "HAVE_FUTIMES",
13131#endif
13132
13133#ifdef HAVE_FUTIMESAT
13134 "HAVE_FUTIMESAT",
13135#endif
13136
13137#ifdef HAVE_LINKAT
13138 "HAVE_LINKAT",
13139#endif
13140
13141#ifdef HAVE_LCHFLAGS
13142 "HAVE_LCHFLAGS",
13143#endif
13144
13145#ifdef HAVE_LCHMOD
13146 "HAVE_LCHMOD",
13147#endif
13148
13149#ifdef HAVE_LCHOWN
13150 "HAVE_LCHOWN",
13151#endif
13152
13153#ifdef HAVE_LSTAT
13154 "HAVE_LSTAT",
13155#endif
13156
13157#ifdef HAVE_LUTIMES
13158 "HAVE_LUTIMES",
13159#endif
13160
13161#ifdef HAVE_MKDIRAT
13162 "HAVE_MKDIRAT",
13163#endif
13164
13165#ifdef HAVE_MKFIFOAT
13166 "HAVE_MKFIFOAT",
13167#endif
13168
13169#ifdef HAVE_MKNODAT
13170 "HAVE_MKNODAT",
13171#endif
13172
13173#ifdef HAVE_OPENAT
13174 "HAVE_OPENAT",
13175#endif
13176
13177#ifdef HAVE_READLINKAT
13178 "HAVE_READLINKAT",
13179#endif
13180
13181#ifdef HAVE_RENAMEAT
13182 "HAVE_RENAMEAT",
13183#endif
13184
13185#ifdef HAVE_SYMLINKAT
13186 "HAVE_SYMLINKAT",
13187#endif
13188
13189#ifdef HAVE_UNLINKAT
13190 "HAVE_UNLINKAT",
13191#endif
13192
13193#ifdef HAVE_UTIMENSAT
13194 "HAVE_UTIMENSAT",
13195#endif
13196
13197#ifdef MS_WINDOWS
13198 "MS_WINDOWS",
13199#endif
13200
13201 NULL
13202};
13203
13204
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013205PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013206INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013207{
Victor Stinner8c62be82010-05-06 00:08:46 +000013208 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013209 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013210 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013211
Brian Curtin52173d42010-12-02 18:29:18 +000013212#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013213 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013214#endif
13215
Victor Stinner8c62be82010-05-06 00:08:46 +000013216 m = PyModule_Create(&posixmodule);
13217 if (m == NULL)
13218 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013219
Victor Stinner8c62be82010-05-06 00:08:46 +000013220 /* Initialize environ dictionary */
13221 v = convertenviron();
13222 Py_XINCREF(v);
13223 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13224 return NULL;
13225 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013226
Victor Stinner8c62be82010-05-06 00:08:46 +000013227 if (all_ins(m))
13228 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013229
Victor Stinner8c62be82010-05-06 00:08:46 +000013230 if (setup_confname_tables(m))
13231 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013232
Victor Stinner8c62be82010-05-06 00:08:46 +000013233 Py_INCREF(PyExc_OSError);
13234 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013235
Guido van Rossumb3d39562000-01-31 18:41:26 +000013236#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013237 if (posix_putenv_garbage == NULL)
13238 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013239#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013240
Victor Stinner8c62be82010-05-06 00:08:46 +000013241 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013242#if defined(HAVE_WAITID) && !defined(__APPLE__)
13243 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013244 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13245 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013246#endif
13247
Christian Heimes25827622013-10-12 01:27:08 +020013248 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013249 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13250 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13251 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013252 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13253 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013254 structseq_new = StatResultType.tp_new;
13255 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013256
Christian Heimes25827622013-10-12 01:27:08 +020013257 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013258 if (PyStructSequence_InitType2(&StatVFSResultType,
13259 &statvfs_result_desc) < 0)
13260 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013261#ifdef NEED_TICKS_PER_SECOND
13262# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013263 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013264# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013265 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013266# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013267 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013268# endif
13269#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013270
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013271#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013272 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013273 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13274 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013275 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013276#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013277
13278 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013279 if (PyStructSequence_InitType2(&TerminalSizeType,
13280 &TerminalSize_desc) < 0)
13281 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013282
13283 /* initialize scandir types */
13284 if (PyType_Ready(&ScandirIteratorType) < 0)
13285 return NULL;
13286 if (PyType_Ready(&DirEntryType) < 0)
13287 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013288 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013289#if defined(HAVE_WAITID) && !defined(__APPLE__)
13290 Py_INCREF((PyObject*) &WaitidResultType);
13291 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13292#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013293 Py_INCREF((PyObject*) &StatResultType);
13294 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13295 Py_INCREF((PyObject*) &StatVFSResultType);
13296 PyModule_AddObject(m, "statvfs_result",
13297 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013298
13299#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013300 Py_INCREF(&SchedParamType);
13301 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013302#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013303
Larry Hastings605a62d2012-06-24 04:33:36 -070013304 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013305 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13306 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013307 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13308
13309 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013310 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13311 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013312 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13313
Thomas Wouters477c8d52006-05-27 19:21:47 +000013314#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013315 /*
13316 * Step 2 of weak-linking support on Mac OS X.
13317 *
13318 * The code below removes functions that are not available on the
13319 * currently active platform.
13320 *
13321 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013322 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013323 * OSX 10.4.
13324 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013325#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013326 if (fstatvfs == NULL) {
13327 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13328 return NULL;
13329 }
13330 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013331#endif /* HAVE_FSTATVFS */
13332
13333#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013334 if (statvfs == NULL) {
13335 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13336 return NULL;
13337 }
13338 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013339#endif /* HAVE_STATVFS */
13340
13341# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013342 if (lchown == NULL) {
13343 if (PyObject_DelAttrString(m, "lchown") == -1) {
13344 return NULL;
13345 }
13346 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013347#endif /* HAVE_LCHOWN */
13348
13349
13350#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013351
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013352 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013353 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13354
Larry Hastings6fe20b32012-04-19 15:07:49 -070013355 billion = PyLong_FromLong(1000000000);
13356 if (!billion)
13357 return NULL;
13358
Larry Hastings9cf065c2012-06-22 16:30:09 -070013359 /* suppress "function not used" warnings */
13360 {
13361 int ignored;
13362 fd_specified("", -1);
13363 follow_symlinks_specified("", 1);
13364 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13365 dir_fd_converter(Py_None, &ignored);
13366 dir_fd_unavailable(Py_None, &ignored);
13367 }
13368
13369 /*
13370 * provide list of locally available functions
13371 * so os.py can populate support_* lists
13372 */
13373 list = PyList_New(0);
13374 if (!list)
13375 return NULL;
13376 for (trace = have_functions; *trace; trace++) {
13377 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13378 if (!unicode)
13379 return NULL;
13380 if (PyList_Append(list, unicode))
13381 return NULL;
13382 Py_DECREF(unicode);
13383 }
13384 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013385
13386 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013387 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013388
13389 initialized = 1;
13390
Victor Stinner8c62be82010-05-06 00:08:46 +000013391 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013392}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013393
13394#ifdef __cplusplus
13395}
13396#endif